smithy-lang / smithy-kotlin

Smithy code generator for Kotlin (in development)
Apache License 2.0
77 stars 26 forks source link

Closing an event stream throws IllegalStateException #935

Closed lauzadis closed 12 months ago

lauzadis commented 1 year ago

This is caused by a blocked read() call in SdkSource.toSdkByteReadChannel().

The call is blocked on read() (waiting for a new event stream update) while the HTTP call is finishing. This causes two threads to touch the same OkHttp Call which is forbidden.

The problem is solved by replacing engineResponse.body.close() with engineCall.cancel() as suggested by OkHttp devs, but according to the documentation for .cancel(), this may leak resources:

It's the caller's responsibility to close the request body and response body streams; otherwise resources may be leaked. This method is safe to be called concurrently, but provides limited guarantees

lauzadis commented 1 year ago

Trying to use both engineCall.cancel() and engineResponse.body.close() results in the same issue. The coroutine which is blocked on read() needs some time to unblock itself and attach the job.

callContext.job.invokeOnCompletion {
    engineCall.cancel()
    // without this delay, the same `IllegalStateException` is thrown. note: in practice, this delay will be more than 1 nanosecond
    runBlocking { delay(1.nanoseconds) } 
    engineResponse.body.close()
}