Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Auto-dispatch to I/O context #218

Merged
merged 3 commits into from
Feb 9, 2024
Merged

Auto-dispatch to I/O context #218

merged 3 commits into from
Feb 9, 2024

Conversation

jhump
Copy link
Member

@jhump jhump commented Feb 6, 2024

This adds a new property to ProtocolClientConfig called ioCoroutineContext. It defaults to null, which means there is no change in behavior from the current defaults -- operations happen in the calling coroutine context, so callers of RPC methods must handle the dispatch.

But when it is configured as non-null (most likely using a value like Dispatchers.IO), then I/O and blocking operations for an RPC are automatically dispatched to the given coroutine context. This allows for RPC client code to be used from any coroutine context without having to worry about explicitly dispatching.

@jhump jhump force-pushed the jh/auto-coroutine branch from 0dc0249 to 93ab537 Compare February 6, 2024 03:39
@@ -46,92 +45,3 @@ interface HTTPClientInterface {
*/
fun stream(request: HTTPRequest, duplex: Boolean, onResult: suspend (StreamResult<Buffer>) -> Unit): Stream
}

interface Stream {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor cleanup in here: I hoisted the Stream stuff out to a separate Stream.kt file.

headers: Headers,
): BidirectionalStream<Input, Output> = suspendCancellableCoroutine { continuation ->
Copy link
Member Author

@jhump jhump Feb 6, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

More cleanup: the suspendCancellableCoroutine usage here didn't really do anything.

It tried to associate cancellation of the stream with the coroutine being cancelled. But this only does anything for the duration of this method body. Since the method always immediately resumes the continuation, this didn't really do anything in practice. So I've removed it for clarity (and replaced it with a try/catch).

Now, it's no longer a suspendable function (so can't be cancelled while executing anyway). Instead, the previous PR (#213, that adds auto-closing block-based RPC invocations to the conformance client) demonstrates the better (IMO) way forward for making sure that the RPCs are appropriately cancelled when a coroutine gets cancelled.

@jhump jhump force-pushed the jh/auto-coroutine branch from 93ab537 to 5e55820 Compare February 6, 2024 03:50
@jhump jhump force-pushed the jh/auto-coroutine branch from 5e55820 to 7e6334e Compare February 6, 2024 12:11
@jhump jhump requested a review from pkwarren February 6, 2024 12:12
Copy link
Contributor

@pkwarren pkwarren left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes look good - one question on Android example. I like that this simplifies the other examples.

lifecycleScope.launch(Dispatchers.IO) {
stream.send(ConverseRequest.newBuilder().setSentence(sentence).build())
}
buttonView.setOnClickListener {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should code that deals with the UI still be dispatched to Dispatchers.Main? I'm not familiar with android development but we might want to keep this here.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The documentation for LifecycleCoroutineScope (the type returned by lifecycleScope) states that it is already tied to Dispatchers.Main. So the above call to lifecycleScope.launch should already dispatch in the right context.

I can set it explicitly above if you'd prefer. I wasn't really sure what was the most idiomatic for Android apps -- to omit when using the default or to always specify explicitly. I guess, even if it is idiomatic to omit, we might want to state it explicitly, just for maximum clarity.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok - I was looking for that documentation and didn't find that information. I think this is ok as-is.

@jhump jhump merged commit d921d9b into main Feb 9, 2024
7 checks passed
@jhump jhump deleted the jh/auto-coroutine branch February 9, 2024 12:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants