protected bool DetermineCurrentlyRunning(ContextControllerCondition startCondition) { // we are not currently running if either of the endpoints is not crontab-triggered var contextDetailInitiatedTerminated = _factory.ContextDetailInitiatedTerminated; if ((contextDetailInitiatedTerminated.Start is ContextDetailConditionCrontab) && ((contextDetailInitiatedTerminated.End is ContextDetailConditionCrontab))) { var scheduleStart = ((ContextDetailConditionCrontab)contextDetailInitiatedTerminated.Start).Schedule; var scheduleEnd = ((ContextDetailConditionCrontab)contextDetailInitiatedTerminated.End).Schedule; var nextScheduledStartTime = ScheduleComputeHelper.ComputeNextOccurance(scheduleStart, _factory.TimeProvider.Time, _factory.StatementContext.MethodResolutionService.EngineImportService.TimeZone); var nextScheduledEndTime = ScheduleComputeHelper.ComputeNextOccurance(scheduleEnd, _factory.TimeProvider.Time, _factory.StatementContext.MethodResolutionService.EngineImportService.TimeZone); return(nextScheduledStartTime >= nextScheduledEndTime); } if (startCondition is ContextControllerConditionTimePeriod) { var condition = (ContextControllerConditionTimePeriod)startCondition; var endTime = condition.ExpectedEndTime; if (endTime != null && endTime <= 0) { return(true); } } return(startCondition is ContextControllerConditionImmediate); }
public override void Transfer( IntSeqKey path, bool transferChildContexts, AgentInstanceTransferServices xfer) { ContextControllerCondition start = initTermSvc.MgmtGetStartCondition(path); start?.Transfer(xfer); initTermSvc.EndVisitConditions( path, ( condition, subPathId) => { condition?.Transfer(xfer); }); if (transferChildContexts) { VisitPartitions( path, ( partitionKey, subpathOrCPIds) => { realization.TransferRecursive(path, subpathOrCPIds, this, xfer); }); } }
public static ContextControllerInitTermPartitionKey BuildPartitionKey( EventBean optionalTriggeringEvent, IDictionary<string, object> optionalTriggeringPattern, ContextControllerCondition endCondition, ContextControllerInitTerm controller) { var startTime = controller.realization.AgentInstanceContextCreate.SchedulingService.Time; var expectedEndTime = endCondition.ExpectedEndTime; return new ContextControllerInitTermPartitionKey( optionalTriggeringEvent, optionalTriggeringPattern, startTime, expectedEndTime); }
public static bool DetermineCurrentlyRunning( ContextControllerCondition startCondition, ContextControllerInitTerm controller) { if (startCondition.IsImmediate) { return true; } var factory = controller.InitTermFactory; var spec = factory.InitTermSpec; if (spec.IsOverlapping) { return false; } // we are not currently running if either of the endpoints is not crontab-triggered if (spec.StartCondition is ContextConditionDescriptorCrontab && spec.EndCondition is ContextConditionDescriptorCrontab) { var scheduleStart = ((ContextControllerConditionCrontab) startCondition).Schedule; var endCron = (ContextConditionDescriptorCrontab) spec.EndCondition; var scheduleEnd = ScheduleExpressionUtil.CrontabScheduleBuild( endCron.Evaluators, controller.Realization.AgentInstanceContextCreate); var importService = controller.Realization.AgentInstanceContextCreate.ImportServiceRuntime; var time = controller.Realization.AgentInstanceContextCreate.SchedulingService.Time; var nextScheduledStartTime = ScheduleComputeHelper.ComputeNextOccurance( scheduleStart, time, importService.TimeZone, importService.TimeAbacus); var nextScheduledEndTime = ScheduleComputeHelper.ComputeNextOccurance( scheduleEnd, time, importService.TimeZone, importService.TimeAbacus); return nextScheduledStartTime >= nextScheduledEndTime; } if (startCondition.Descriptor is ContextConditionDescriptorTimePeriod) { var descriptor = (ContextConditionDescriptorTimePeriod) startCondition.Descriptor; var endTime = descriptor.GetExpectedEndTime(controller.Realization); if (endTime != null && endTime <= 0) { return true; } } return startCondition is ContextConditionDescriptorImmediate; }
public static bool DetermineCurrentlyRunning( ContextControllerCondition startCondition, ContextControllerInitTerm controller) { if (startCondition.IsImmediate) { return true; } var factory = controller.InitTermFactory; var spec = factory.InitTermSpec; if (spec.IsOverlapping) { return false; } // we are not currently running if either of the endpoints is not crontab-triggered if (spec.StartCondition is ContextConditionDescriptorCrontab && spec.EndCondition is ContextConditionDescriptorCrontab) { ScheduleSpec[] schedulesStart = ((ContextControllerConditionCrontab) startCondition).Schedules; var endCron = (ContextConditionDescriptorCrontab) spec.EndCondition; var schedulesEnd = new ScheduleSpec[endCron.EvaluatorsPerCrontab.Length]; for (var i = 0; i < schedulesEnd.Length; i++) { schedulesEnd[i] = ScheduleExpressionUtil.CrontabScheduleBuild( endCron.EvaluatorsPerCrontab[i], controller.Realization.AgentInstanceContextCreate); } var classpathImportService = controller.Realization.AgentInstanceContextCreate.ImportServiceRuntime; var time = controller.Realization.AgentInstanceContextCreate.SchedulingService.Time; var nextScheduledStartTime = ComputeScheduleMinimumNextOccurance(schedulesStart, time, classpathImportService); var nextScheduledEndTime = ComputeScheduleMinimumNextOccurance(schedulesEnd, time, classpathImportService); return nextScheduledStartTime >= nextScheduledEndTime; } if (startCondition.Descriptor is ContextConditionDescriptorTimePeriod) { var descriptor = (ContextConditionDescriptorTimePeriod) startCondition.Descriptor; var endTime = descriptor.GetExpectedEndTime(controller.Realization); if (endTime != null && endTime <= 0) { return true; } } return startCondition is ContextConditionDescriptorImmediate; }
public void Activate(EventBean optionalTriggeringEvent, IDictionary <String, Object> optionalTriggeringPattern, ContextControllerState controllerState, ContextInternalFilterAddendum filterAddendum, int?importPathId) { if (_factory.FactoryContext.NestingLevel == 1) { controllerState = ContextControllerStateUtil.GetRecoveryStates(_factory.FactoryContext.StateCache, _factory.FactoryContext.OutermostContextName); } bool currentlyRunning; var contextDetailInitiatedTerminated = _factory.ContextDetailInitiatedTerminated; if (controllerState == null) { StartCondition = MakeEndpoint(contextDetailInitiatedTerminated.Start, filterAddendum, true, 0); // if this is single-instance mode, check if we are currently running according to schedule currentlyRunning = StartCondition.IsImmediate; if (!contextDetailInitiatedTerminated.IsOverlapping) { currentlyRunning = DetermineCurrentlyRunning(StartCondition); } if (currentlyRunning) { CurrentSubpathId++; var endEndpoint = MakeEndpoint(contextDetailInitiatedTerminated.End, filterAddendum, false, CurrentSubpathId); endEndpoint.Activate(optionalTriggeringEvent, null, 0, _factory.FactoryContext.IsRecoveringResilient); var startTime = _factory.SchedulingService.Time; var endTime = endEndpoint.ExpectedEndTime; var builtinProps = GetBuiltinProperties(_factory.FactoryContext.ContextName, startTime, endTime, Collections.GetEmptyMap <string, object>()); var instanceHandle = ActivationCallback.ContextPartitionInstantiate(null, CurrentSubpathId, null, this, optionalTriggeringEvent, optionalTriggeringPattern, null, builtinProps, controllerState, filterAddendum, _factory.FactoryContext.IsRecoveringResilient, ContextPartitionState.STARTED); EndConditions.Put(endEndpoint, new ContextControllerInitTermInstance(instanceHandle, null, startTime, endTime, CurrentSubpathId)); var state = new ContextControllerInitTermState(_factory.FactoryContext.ServicesContext.SchedulingService.Time, builtinProps); _factory.FactoryContext.StateCache.AddContextPath(_factory.FactoryContext.OutermostContextName, _factory.FactoryContext.NestingLevel, _pathId, CurrentSubpathId, instanceHandle.ContextPartitionOrPathId, state, _factory.Binding); } // non-overlapping and not currently running, or overlapping if ((!contextDetailInitiatedTerminated.IsOverlapping && !currentlyRunning) || contextDetailInitiatedTerminated.IsOverlapping) { StartCondition.Activate(optionalTriggeringEvent, null, 0, _factory.FactoryContext.IsRecoveringResilient); } return; } StartCondition = MakeEndpoint(contextDetailInitiatedTerminated.Start, filterAddendum, true, 0); // if this is single-instance mode, check if we are currently running according to schedule currentlyRunning = false; if (!contextDetailInitiatedTerminated.IsOverlapping) { currentlyRunning = DetermineCurrentlyRunning(StartCondition); } if (!currentlyRunning) { StartCondition.Activate(optionalTriggeringEvent, null, 0, _factory.FactoryContext.IsRecoveringResilient); } int pathIdToUse = importPathId ?? _pathId; InitializeFromState(optionalTriggeringEvent, optionalTriggeringPattern, filterAddendum, controllerState, pathIdToUse, null, false); }
public void RangeNotification( IDictionary <String, Object> builtinProperties, ContextControllerCondition originCondition, EventBean optionalTriggeringEvent, IDictionary <String, Object> optionalTriggeringPattern, ContextInternalFilterAddendum filterAddendum) { var endConditionNotification = originCondition != StartCondition; var startNow = StartCondition is ContextControllerConditionImmediate; IList <AgentInstance> agentInstancesLocksHeld = null; _nonDistinctLastTrigger = optionalTriggeringEvent; ILockable tempLock = startNow ? _factory.FactoryContext.ServicesContext.FilterService.WriteLock : new VoidLock(); using (tempLock.Acquire()) { try { if (endConditionNotification) { if (originCondition.IsRunning) { originCondition.Deactivate(); } // indicate terminate var instance = EndConditions.Pluck(originCondition); if (instance == null) { return; } // For start-now (non-overlapping only) we hold the lock of the existing agent instance // until the new one is ready. if (startNow) { agentInstancesLocksHeld = new List <AgentInstance>(); optionalTriggeringEvent = null; // since we are restarting, we don't want to evaluate the event twice optionalTriggeringPattern = null; } ActivationCallback.ContextPartitionTerminate( instance.InstanceHandle, builtinProperties, startNow, agentInstancesLocksHeld); // remove distinct key RemoveDistinctKey(instance); // re-activate start condition if not overlapping if (!_factory.ContextDetailInitiatedTerminated.IsOverlapping) { StartCondition.Activate(optionalTriggeringEvent, null, 0, false); } _factory.FactoryContext.StateCache.RemoveContextPath( _factory.FactoryContext.OutermostContextName, _factory.FactoryContext.NestingLevel, _pathId, instance.SubPathId); } // handle start-condition notification if (!endConditionNotification || startNow) { // Check if this is distinct-only and the key already exists if (_distinctContexts != null) { var added = AddDistinctKey(optionalTriggeringEvent); if (!added) { return; } } // For single-instance mode, deactivate if (!_factory.ContextDetailInitiatedTerminated.IsOverlapping) { if (StartCondition.IsRunning) { StartCondition.Deactivate(); } } // For overlapping mode, make sure we activate again or stay activated else { if (!StartCondition.IsRunning) { StartCondition.Activate(null, null, 0, _factory.FactoryContext.IsRecoveringResilient); } } CurrentSubpathId++; var endEndpoint = MakeEndpoint( _factory.ContextDetailInitiatedTerminated.End, filterAddendum, false, CurrentSubpathId); var matchedEventMap = GetMatchedEventMap(builtinProperties); endEndpoint.Activate(null, matchedEventMap, 0, false); var startTime = _factory.SchedulingService.Time; var endTime = endEndpoint.ExpectedEndTime; var builtinProps = GetBuiltinProperties(_factory.FactoryContext.ContextName, startTime, endTime, builtinProperties); var instanceHandle = ActivationCallback.ContextPartitionInstantiate( null, CurrentSubpathId, null, this, optionalTriggeringEvent, optionalTriggeringPattern, new ContextControllerInitTermState( _factory.SchedulingService.Time, matchedEventMap.MatchingEventsAsMap), builtinProps, null, filterAddendum, _factory.FactoryContext.IsRecoveringResilient, ContextPartitionState.STARTED); EndConditions.Put( endEndpoint, new ContextControllerInitTermInstance( instanceHandle, builtinProperties, startTime, endTime, CurrentSubpathId)); // install filter fault handlers, if necessary InstallFilterFaultHandler(instanceHandle); var state = new ContextControllerInitTermState( _factory.FactoryContext.ServicesContext.SchedulingService.Time, builtinProperties); _factory.FactoryContext.StateCache.AddContextPath( _factory.FactoryContext.OutermostContextName, _factory.FactoryContext.NestingLevel, _pathId, CurrentSubpathId, instanceHandle.ContextPartitionOrPathId, state, _factory.Binding); } } finally { if (agentInstancesLocksHeld != null) { foreach (var agentInstance in agentInstancesLocksHeld) { agentInstance.AgentInstanceContext.EpStatementAgentInstanceHandle.StatementFilterVersion.StmtFilterVersion = long.MaxValue; if (agentInstance.AgentInstanceContext.StatementContext.EpStatementHandle.HasTableAccess) { agentInstance.AgentInstanceContext.TableExprEvaluatorContext.ReleaseAcquiredLocks(); } agentInstance.AgentInstanceContext.AgentInstanceLock.WriteLock.Release(); } } } } }