This repository has been 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
OkHttpClient
per process, which will manage aDispatcher
andOkHttpConnectionPool
to 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 sharedOkHttpClient
by 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)BinanceApiServiceGenerator
now properly uses theexistingClient.newBuilder().interceptor(someInterceptor).build()
pattern to make a shallow clone of the sharedOkHttpClient
and 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 newRetrofit
instance, 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
pingInterval
on 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 sensiblepingInterval
of 20 seconds to detect disconnections, which is working perfectly.Additionally I noticed that every
BinanceApiWebSocketClientImpl
was 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 thatBinanceApiWebSocketClientImpl
now uses the same process-wide sharedOkHttpClient
as the rest of the application.Please review the changes attached and let me know what you think! 🌽