beginning to make caching asynchronous
fixing final compile errs in specs
getting specs passing
making specs compile, and fixing ReadCachingHttpClientSpecs
simplifying hash construction code
and using request hash codes in InMemoryHttpResponseCacher
simplifying caching code in ETagAwareHttpClient
adding more tests for ETagAwareHttpClient
also, adding a race condition todo
Merge branch 'master' into async-caching
Merge branch 'master' into async-caching
fixing race condition in ETagAwareHttpClient
this commit introduces FutureScheduler to provide a scalable way to synchronize the execution of futures. this synchronization method means the ETagAwareHttpClient get method can remove the race condition between the get and apply methods
providing constructor params to customize the future scheduler
making it easy to override the future scheduler in InMemoryHttpResponseCacher
cleaning up NonEmptyList => String code
removing FutureScheduler interaction from HttpResponseCacher
ETagAwareHttpClient does the scheduling itself, and the cacher stays simple this way
removing cache synchronization
there's still a race condition between the remove and the various cache sets, and if get is called multiple times
using asyncMutex to synchronize cache access on each get call
this code keeps a concurrent map for each GetRequest => AsyncMutex. the get function gets or sets a new mutex for its enclosing GetRequest, and then acquires the mutex before it does any real work. when the work is done, it releases the permit as expected
going back to get-and-remove algorithm for ETagAwareHttpClient
the algorithm is safe because it's protected by AsyncMutex
making Async mutexes and Async mutex tables generic
and using the generic versions in ETagAwareHttpClient
adding more specific docs about mutual exclusion
fixing typo
thx @drapp