housekeeping: Limit concurrency of OptimizeRepository to 1
OptimizeRepository should not run concurrently. It could lead to a data race that ends up deleting objects incorrectly. In order to limit the concurrency to 1, we can use a simple mutex.
This change also reorganizes the code so that we can test it more easily by swapping in an implementation of optimizeRepository.
fixes: #4105 (closed)