This repository was archived by the owner on Oct 30, 2023. It is now read-only.
Fix OkHttp/Retrofit interceptor mess and improve web sockets #133
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Hey! I discovered more problems with the current state of the library. OkHttp and Retrofit were used incorrectly, so I decided to improve it. With a few quick modifications I was able to address some issues that have been raised before. It's still no immutable Scala heaven, but it works! 🙃
Background
It's recommended that there is only one
OkHttpClientper process, which will manage aDispatcherandOkHttpConnectionPoolto coordinate all (a)synchronous requests, including the handshake requests for web socket negotiation.AuthenticationInterceptor
I found out that there was some truly wacky shit going on in
BinanceApiServiceGenerator. On every 'service generation' for an authenticated (a)synchronous REST API client there was this weird dance involving the modification of the sharedOkHttpClientby adding a newAuthenticationInterceptor. This updated client was then plugged into a (shared/static) instance of Retrofit that kept getting modified behind the scenes before it would be returned to callers. This was asking for trouble, especially in the case of 'multi tenancy'. (#99, #123)BinanceApiServiceGeneratornow properly uses theexistingClient.newBuilder().interceptor(someInterceptor).build()pattern to make a shallow clone of the sharedOkHttpClientand have this clone use a specificAuthenticationInterceptor, while still using the connection/thread pool and other resources of the process-wide shared client. This adapted client is then used to create a newRetrofitinstance, which then materializes the service.Web sockets
During testing I discovered that the web sockets weren't properly detecting disconnections (#96). It could take up to a few minutes before disconnections of the web socket (or internet) would be detected and propagated as exceptions. In my use case this was unacceptable.
I attempted to improve this by setting a very small
pingIntervalon theOkHttpClient, but this had no effect. It turns out that there was a problem with the version of OkHttp used by Retrofit 2.3. I learned that upgrading to a newer version of OkHttpClient would fix this, and it did! I upgraded Retrofit to 2.4 (which uses the newer version of OkHttp) and hardcoded (!) a sensiblepingIntervalof 20 seconds to detect disconnections, which is working perfectly.Additionally I noticed that every
BinanceApiWebSocketClientImplwas spawning its ownOkHttpClient, with its own Dispatcher and thread pool. This is not suited for multi tenancy and leads to an unnecessary amount of (idle) threads. I changed this so thatBinanceApiWebSocketClientImplnow uses the same process-wide sharedOkHttpClientas the rest of the application.Please review the changes attached and let me know what you think! 🌽