@Override
    public int physicallyDeleteOldTasks(final Instant deleteThreshold) {
        LOGGER.debug("Deleting old COMPLETE or DELETED processor tasks");
        final AtomicInteger totalDeleteCount = new AtomicInteger();
        final Condition condition = DSL.and(
                PROCESSOR_TASK.STATUS.eq(TaskStatus.COMPLETE.getPrimitiveValue())
                        .or(PROCESSOR_TASK.STATUS.eq(TaskStatus.DELETED.getPrimitiveValue())),
                PROCESSOR_TASK.STATUS_TIME_MS.isNull()
                        .or(PROCESSOR_TASK.STATUS_TIME_MS.lessThan(deleteThreshold.toEpochMilli())));
        LOGGER.debug("Using condition: {}", condition);
        while (true) {
            final List<Long> idList = JooqUtil.contextResult(processorDbConnProvider, context ->
                    context
                            .select(PROCESSOR_TASK.ID)
                            .from(PROCESSOR_TASK)
                            .where(condition)
                            .limit(BATCH_SIZE)
                            .fetch()
                            .map(Record1::value1));

            if (NullSafe.isEmptyCollection(idList)) {
                LOGGER.debug("No IDs found, breaking out of loop");
                break;
            }

            // Ideally we would re-use the additional status/time condition as we are doing this
            // outside of a txn so state may have changed, but we don't have code that un-logically-deletes.
            // The where on the idList should mean we don't create any gap-locks or next-key locks which
            // can deadlock updates on this table
            final int count = JooqUtil.contextResult(processorDbConnProvider, context ->
                    context
                            .deleteFrom(PROCESSOR_TASK)
                            .where(PROCESSOR_TASK.ID.in(idList))
                            .execute());

            totalDeleteCount.addAndGet(count);

            LOGGER.debug(() -> LogUtil.message(
                    "Physically deleted a batch of {} processor tasks with status time older than {} " +
                    "for an idList size of {}, totalDeleteCount: {}",
                    count, deleteThreshold, idList.size(), totalDeleteCount));
        }

        LOGGER.debug("Physically deleted {} processor tasks with status time older than {}",
                totalDeleteCount, deleteThreshold);
        return totalDeleteCount.get();
    }
Physically delete tasks that are logically deleted or complete for longer than the threshold.

@param deleteThreshold Only physically delete tasks with an update time older than the threshold.
@return The number of physically deleted tasks.
stroom-processor/stroom-processor-impl-db/src/main/java/stroom/processor/impl/db/ProcessorTaskDaoImpl.java