Fix/enhance KeyedResourcePool

Should address https://github.com/m3dev/octoparts/issues/66

If we want our `KeyedResourcePool` to work well with shared mutable state in general (not cause race conditions in things that it may not know about), we will need to synchronise our accesses to the underlying holder map as well as the conditional side-effecting logic that follows. For`KeyedResourcePool` this is either in the `getOrCreate` and the `cleanObsolete` methods.

This PR implements a naive (?) version of `KeyedResourcePool` called `SyncedKeyedResourcePool` (for now, after iteration we might just replace the old) that uses `synchronized` to do syncing as well as a failing test (passes under `SyncedKeyedResourcePool`).

Another way is to use an Akka actor, which is easier to reason about with (thus safer to maintain) in the long run. It will likely perform worse though (more method calls, construction Futures objects, thread-weaving, possibly others), though I don't know for sure without benching.

Note that all bets are off if there are multiple instances of `KeyedResourcePool` that may affect the same global state. 
The point of using Symbol keys is so that I would be able to use the simpler `synchronized` to do locking on individual Symbol objects rather than juggling locks myself. While Symbol creation does use locking, the performance there is something I can leave for the Scala lib devs to worry about, and from what I can see, they have improved it at least once (global synchronized -> RWLock).

I hear you on the merits of using global/RWlocks to increase understandability and lower the chance of heisenbugs though. I will go back to allowing any kind of keys and either do global locking on the pool instance or RWlocks :+1: