PersistenceManagerImpl.stop() acquires all the permits of publisherSemaphore to make sure there is no ongoing iteration. But there is no timeout, so if the application is slowly going through all the entries in a huge cache it could block cache stop for a very long time.
What's more, when a publisher finishes, the stop thread and other threads trying to start a new publisher have the same priority, and if the new publisher acquires a permit stop will have to wait for it to finish.
We should limit the amount of time we wait for iterations to finish, similar to how TransactionTable only waits for ongoing transactions to finish for transaction.cacheStopTimeout millis. Ideally we would move cacheStopTimeout out of the transaction configuration and use it everywhere we could wait for user threads to finish doing their work before stopping.