/**
  * Mark the specified action as completed
  *
  * @param transactionId the unique transaction id for this action
  * @param scheduledActionUuid the unique name of an action
  */
 private void markAsCompleted(String transactionId, String scheduledActionUuid) {
   try {
     Ebean.beginTransaction();
     SchedulerState schedulerState =
         SchedulerState.getRunningSchedulerStateFromTransactionId(transactionId);
     if (schedulerState == null) {
       log.error(
           String.format(
               "Strange ... No running scheduled action for %s with transaction id %s while one was running and mark as completed is requested",
               scheduledActionUuid, transactionId));
     } else {
       schedulerState.isRunning = false;
       schedulerState.save();
       if (log.isDebugEnabled()) {
         log.debug(
             String.format(
                 "Scheduled action for %s with transaction id %s completed",
                 scheduledActionUuid, transactionId));
       }
     }
     Ebean.commitTransaction();
   } catch (Exception e) {
     log.error("Failed to mark as complete", e);
     rollbackTransactionSilent();
   } finally {
     endTransactionSilent();
   }
 }
 @Override
 public Cancellable scheduleRecurring(
     final boolean exclusive,
     final String scheduledActionUuid,
     FiniteDuration initialDelay,
     FiniteDuration interval,
     final Runnable runnable,
     final boolean logInDebug) {
   if (log.isDebugEnabled()) {
     log.debug("Request " + (exclusive ? "EXCLUSIVE" : "STANDARD") + " " + scheduledActionUuid);
   }
   return getActorSystem()
       .scheduler()
       .schedule(
           initialDelay,
           interval,
           new Runnable() {
             @Override
             public void run() {
               String transactionId = Utilities.getRandomID();
               dumpSystemStatus(
                   "SCHEDULER START for "
                       + scheduledActionUuid
                       + " ["
                       + (exclusive ? "EXCLUSIVE" : "STANDARD")
                       + "] and transaction "
                       + transactionId,
                   logInDebug);
               markAsStarted(transactionId, scheduledActionUuid);
               try {
                 runnable.run();
               } catch (Exception e) {
                 log.error(
                     "The job "
                         + scheduledActionUuid
                         + " raised an exception within the transaction "
                         + transactionId,
                     e);
               }
               markAsCompleted(transactionId, scheduledActionUuid);
               dumpSystemStatus(
                   "SCHEDULER STOP for "
                       + scheduledActionUuid
                       + " and transaction "
                       + transactionId,
                   logInDebug);
             }
           },
           getActorSystem().dispatcher());
 }
 /**
  * Mark the specified action as completed
  *
  * @param transactionId the unique transaction id for this action
  * @param scheduledActionUuid the unique name of an action
  */
 private void markAsStarted(String transactionId, String scheduledActionUuid) {
   try {
     Ebean.beginTransaction();
     SchedulerState schedulerState = new SchedulerState();
     schedulerState.actionUuid = scheduledActionUuid;
     schedulerState.transactionId = transactionId;
     schedulerState.isRunning = true;
     schedulerState.save();
     if (log.isDebugEnabled()) {
       log.debug(
           String.format(
               "Scheduled action for %s with transaction id %s started",
               scheduledActionUuid, transactionId));
     }
     Ebean.commitTransaction();
   } catch (Exception e) {
     log.error("Failed to mark as started", e);
     rollbackTransactionSilent();
   } finally {
     endTransactionSilent();
   }
 }