static <ID, T> TaskExecutors<ID, T> singleItemExecutors(final String name,
                                                            int workerCount,
                                                            final TaskProcessor<T> processor,
                                                            final AcceptorExecutor<ID, T> acceptorExecutor) {
        final AtomicBoolean isShutdown = new AtomicBoolean();
        final TaskExecutorMetrics metrics = new TaskExecutorMetrics(name);
        registeredMonitors.put(name, metrics);
        return new TaskExecutors<>(idx -> new SingleTaskWorkerRunnable<>("TaskNonBatchingWorker-" + name + '-' + idx, isShutdown, metrics, processor, acceptorExecutor), workerCount, isShutdown);
    }
@Test
    public void testSingleItemProcessingWithTransientError() throws Exception {
        taskExecutors = TaskExecutors.singleItemExecutors("TEST", 1, processor, acceptorExecutor);

        TaskHolder<Integer, ProcessingResult> taskHolder = transientErrorTaskHolder(1);
        taskQueue.add(taskHolder);

        // Verify that transient task is be re-scheduled
        processor.expectTransientErrors(1);
        verify(acceptorExecutor, timeout(500).times(1)).reprocess(taskHolder, ProcessingResult.TransientError);
    }