'Do the actual work of the Cron. Will first check if DueToRun is True.
CronJob object must be locked (i.e. opened via OpenWithLock) for Run() to be
called.
Args:
force: If True, the job will run no matter what (i.e. even if DueToRun()
returns False).
Raises:
LockError: if the object is not locked.'

def Run(self, force=False):

    if (not self.locked):
        raise aff4.LockError('CronJob    must    be    locked    for    Run()    to    be    called.')
    self.KillOldFlows()
    current_flow_urn = self.Get(self.Schema.CURRENT_FLOW_URN)
    if current_flow_urn:
        current_flow = aff4.FACTORY.Open(current_flow_urn, token=self.token)
        runner = current_flow.GetRunner()
        if (not runner.IsRunning()):
            if (runner.context.state == rdf_flows.FlowContext.State.ERROR):
                self.Set(self.Schema.LAST_RUN_STATUS, rdf_cronjobs.CronJobRunStatus(status=rdf_cronjobs.CronJobRunStatus.Status.ERROR))
                stats.STATS.IncrementCounter('cron_job_failure', fields=[self.urn.Basename()])
            else:
                self.Set(self.Schema.LAST_RUN_STATUS, rdf_cronjobs.CronJobRunStatus(status=rdf_cronjobs.CronJobRunStatus.Status.OK))
                start_time = self.Get(self.Schema.LAST_RUN_TIME)
                elapsed = (time.time() - start_time.AsSecondsFromEpoch())
                stats.STATS.RecordEvent('cron_job_latency', elapsed, fields=[self.urn.Basename()])
            self.DeleteAttribute(self.Schema.CURRENT_FLOW_URN)
            self.Flush()
    if ((not force) and (not self.DueToRun())):
        return
    cron_args = self.Get(self.Schema.CRON_ARGS)
    cron_args.flow_runner_args.base_session_id = self.urn
    flow_urn = flow.GRRFlow.StartFlow(runner_args=cron_args.flow_runner_args, args=cron_args.flow_args, token=self.token, sync=False)
    self.Set(self.Schema.CURRENT_FLOW_URN, flow_urn)
    self.Set(self.Schema.LAST_RUN_TIME, rdfvalue.RDFDatetime.Now())
    self.Flush()
