Wrap LightClient in typestate for guided API#146
Wrap LightClient in typestate for guided API#146rustaceanrob merged 1 commit intobitcoindevkit:masterfrom
LightClient in typestate for guided API#146Conversation
LightClient in typestate for guided API
6669715 to
9818572
Compare
553160d to
bdbfeeb
Compare
thunderbiscuit
left a comment
There was a problem hiding this comment.
Concept ACK. I got it working on the bindings side, see bitcoindevkit/bdk-ffi#965.
I'm not sure the code is where I'd like it to be there but at least it compiles and works for now. The one odd thing is that I had to use start_managed, so in the end it's the same as if I had created a wrapper on the old API and kept the node inside the wrapper and not exposed it to the user.
|
Yes, admittedly this won't change the situation much for the bindings, however |
I made an attempt in the base client to use typestate for running the node [here](2140-dev/kyoto#535). While I think the pattern is ergonomic, it imposes too many restrictions on the `Client` ownership model. The pattern does seem appropriate here, however, where we are taking a more opinionated approach as to how the user interacts with the light client. This API abstracts the `Node` entirely for users that have a `tokio` environment present. I divided the stages of the `LightClient` into `Idle`, `Subscribed`, `Active`. The differentiation between `Idle` and `Subscribed` can be seen in the example. This allows the user to set up the necessary logging tasks required for their app. Then they may call `start` to execute the task, and finally make requests thereafter.
bdbfeeb to
203a6d1
Compare
|
One thing I'll look into is how uniffi can allow Rust to actually hand over async code directly to the target languages, and so it's (I think) at least in theory possible to use the asynchronous code directly in Kotlin and not require tokio at all. This would not necessarily be a huge gain, but maybe a small optimization because it would allow the node to not use a full OS thread for its work, and instead be jointly given to a dispatcher (on Kotlin) and so interleave its work with the loggers for example. I assume something similarly doable for Swift. If that was even possible you'd also save the size of shipping Tokio with the lib? Not sure if that's big or not. |
|
Kyoto internally uses |
|
Yeah it's not possible with kyoto and bdk-kyoto as is, but I wanted to see what the requirements are for this type of thing (I know it's currently supported by uniffi). What you need is a runtime-agnostic library on the Rust side, but honestly this sounds it would have very low usefulness because it's not like there are a lot of other options other than Tokio in Rust, and so the only value would be for bindings at the cost of (I assume?) significant increase in complexity. |
I made an attempt in the base client to use typestate for running the node here. While I think the pattern is ergonomic, it imposes too many restrictions on the
Clientownership model. The pattern does seem appropriate here, however, where we are taking a more opinionated approach as to how the user interacts with the light client. This API abstracts theNodeentirely for users that have atokioenvironment present.I divided the stages of the
LightClientintoIdle,Subscribed,Active. The differentiation betweenIdleandSubscribedcan be seen in the example. This allows the user to set up the necessary logging tasks required for their app. Then they may callstartto execute the task, and finally make requests thereafter.ref: 2140-dev/kyoto#527
ref: https://cliffle.com/blog/rust-typestate/
cc @thunderbiscuit