CRS Authority Cache Handling - STEMLab/geotools GitHub Wiki
The relationship between the FactoryUsingOracleSQL and the backpointer buffered is highlighted as a problem in most of the above alternatives. This section outlines some possible solutions.
- Isolate Cache into a Separate Object and Inject - 💛 provides a clear separation of concerns
- Reduce Worker to DAO - acceptable, but may involve too much email
- Minimize Connection Use Time - Java EE best practice, forces us to provide connection policy stratagy object for others
- Hack Cache to Package Visibility - not recommended
- Worker Factory per Thread - acceptable
This problem only occurs when we are handling a FactoryUsingOracleSQL cascading request (such as creating a Datum) in which the recursive call to FactoryOnOracleSQL results in a cache miss. On a cache miss we have no assurance that our origional FactoryUsingOracleSQL would be used to satisfy the request. We are open to the possibility of a second FactoryUsingOracleSQL (and a second connection) being used.
The BufferedAuthorityFactory currently managed cached objects in a Map called findPool (associated with the find method). If we isolate this concept into a seperate class we can inject the same buffer into each worker Factory.
Clean seperation of concerns, isolates cache for stress testing
A more significant design change
Reduce the worker to just a DAO (producing a Map of properties). The FactoryOnOracleSQL would be responsible for object creation - and playing with its internal cache. We would still want to isolate the cache code to facilitate debugging.
Clean seperation of concerns, isolate cache for stress testing. The creatation of a DAO layer is more approachable (and normal) senario when working with databases
The definition of the keys for the map may prove difficult (but since most creation methods seem to take a map of properties we should be okay).
Basically arrange to be in a situtation where we can ignore the problem. We can reduce the amount of time we use a connection open to just the amount needed to process the result set into a Map of properties.
Actually turning the Map of properties into the the next call to create should darn well occur when the connection has been returned).
Java EE best practice
Not an acceptable alternative in other environments - we would need to make a ConnectionPolicy strategy object
Any cascading requests having a cache miss would have indeed have to fetch another FactoryUsingOracleSQL out of the pool, yes it means that we would have more worker factories in use then strictly needed, but what the heck if they are not tieing up connections.
We can make the get method package visible so FactoryUsingOracleSQL can check the cache, and if needed perform the operation itself in the case of a cache miss.
Sequence Diagram
Quick
Hack
We can maintain a map of Thread to FactoryUsingOracleSQL object, this information can be be used to route a cache miss back to the FactoryUsingOracleSQL object making the cascading request.
The backingStore method below locates the correct FactoryUsingOracleSQL instance for the current Thread. During the first call any free implementation in the pool is returned, during the second the instance associated with the thread is returned (again).
The diagram shows a cascade while creating a Datum, the createEllipsoid value is not available in the cache and needs to be retrieved with a seperate query.
If we do not take this step the cascade brought on by cache misses may tie up more than one connection (one for each create method).
It will work.
We are maintaining a complicated data structure in order to facilitate recursion - it will be difficult to debug and maintain.