private boolean execute(final T doc,
                            final ExecutionSchedule executionSchedule,
                            final TaskContext taskContext) {
        final ExecutionTracker currentTracker = executionScheduleDao.getTracker(executionSchedule).orElse(null);
        final Schedule schedule = executionSchedule.getSchedule();
        final ScheduleBounds scheduleBounds = executionSchedule.getScheduleBounds();

        // See if it is time to execute this query.
        final Instant executionTime = Instant.now();
        final Trigger trigger = TriggerFactory.create(schedule);

        final Instant effectiveExecutionTime;
        if (currentTracker != null) {
            effectiveExecutionTime = Instant.ofEpochMilli(currentTracker.getNextEffectiveExecutionTimeMs());
        } else {
            if (scheduleBounds != null && scheduleBounds.getStartTimeMs() != null) {
                effectiveExecutionTime = Instant.ofEpochMilli(scheduleBounds.getStartTimeMs());
            } else {
                effectiveExecutionTime = trigger.getNextExecutionTimeAfter(executionTime);
            }
        }

        // Calculate end bounds.
        Instant endTime = Instant.MAX;
        if (scheduleBounds != null && scheduleBounds.getEndTimeMs() != null) {
            endTime = Instant.ofEpochMilli(scheduleBounds.getEndTimeMs());
        }

        if (!effectiveExecutionTime.isAfter(executionTime) && !effectiveExecutionTime.isAfter(endTime)) {
            taskContext.info(() -> "Executing schedule '" +
                                   executionSchedule.getName() +
                                   "' with effective time: " +
                                   DateUtil.createNormalDateTimeString(effectiveExecutionTime.toEpochMilli()));
            final String errorFeedName = getErrorFeedName(doc);
            final AnalyticErrorWriter analyticErrorWriter = analyticErrorWriterProvider.get();
            return analyticErrorWriter.exec(
                    errorFeedName,
                    null,
                    taskContext,
                    (t) -> process(
                            doc,
                            trigger,
                            executionTime,
                            effectiveExecutionTime,
                            executionSchedule,
                            currentTracker));
        }
        return false;
    }
Called at the end of execution to perform any tidy up operations.

@param analyticDocs The list of all known analyticDocs for this executor.
stroom-analytics/stroom-analytics-impl/src/main/java/stroom/analytics/impl/AbstractScheduledQueryExecutor.java