class PooledTaskExecutor implements TaskExecutor {

    @Override
    public void execute(String tokenId, Task task) throws DataLayerException {
        try {
            debug("Polling pool for an executor");
            semaphore.acquire();
        } catch (InterruptedException e) {
            Thread.interrupted();
            throw new DataLayerException("Interrupted while waiting for executor - cannot continue", e);
        }
        SimpleTaskExecutor executor = pool.poll();
        if (executor == null) {
            executor = createExecutor();
        }
        try {
            debug("Got an executor - executing task");
            executor.execute(tokenId, task);
        } finally {
            debug("Returning executor to the pool");
            if (pool.add(executor)) {
                semaphore.release();
            }
        }
    }

    @Inject public  PooledTaskExecutor(Provider<SimpleTaskExecutor> simpleTaskExecutorProvider,
            @Named(DataLayerConstants.DATA_LAYER_DEBUG) Debug debug, ConnectionType connectionType,
            ConnectionConfigFactory connectionConfig,
            @Named(SEMAPHORE) Semaphore semaphore);

}