private void OnTimer(object state) { lock (_lock) { if (_isRunning) { return; } _isRunning = true; } using (Logging.Server.DebugTraceMethodCall("WorkflowServer.OnTimer")) { try { using (var localScope = _scope.BeginLifetimeScope()) { while (true) { using (var queryCtx = localScope.Resolve <IZetboxServerContext>()) { var now = DateTime.Now; var nextSchedulerEntries = queryCtx.GetQuery <SchedulerEntry>() .Where(e => e.InvokeOn <= now) .Where(e => e.State.IsActive) .Take(MAX_ITEMS_PER_BATCH) .ToList(); if (nextSchedulerEntries.Count == 0) { break; } Logging.Server.InfoFormat("Found {0} SchedulerEntries", nextSchedulerEntries.Count); foreach (var entry in nextSchedulerEntries) { lock (_lock) { if (_isInShutdown) { return; } } using (var ctx = localScope.Resolve <IZetboxContext>()) { try { var localEntry = ctx.Find <SchedulerEntry>(entry.ID); localEntry.Action.Action.Execute(localEntry.Action, localEntry.State); // Re-Schedule var scheduledActions = localEntry.State.StateDefinition.Actions .OfType <ScheduledActionDefinition>() .Where(ad => ad.IsRecurrent) .Where(ad => ad.InvokeAction == localEntry.Action) .ToList(); Logging.Server.InfoFormat(" processing wf instance.state '{0}.{1}', {2} actions", localEntry.State.Instance, localEntry.State.ToString(), scheduledActions.Count); foreach (var sAction in scheduledActions) { sAction.Action.Execute(sAction, localEntry.State); } ctx.Delete(localEntry); ctx.SubmitChanges(); } catch (ConcurrencyException) { // This is one of the rare cases, where the exception may be ignored // continue and try again. } } } } } } } catch (Exception ex) { Logging.Server.Error("Error during workflow scheduler service timer callback", ex); } finally { lock (_lock) { _isRunning = false; } } } }
public IOC.ILifetimeScope BeginLifetimeScope() { var result = new LifetimeScopeImpl(_lifetimeScope.BeginLifetimeScope()); return(result); }