Exemplo n.º 1
0
        private async Task SetOrResetTimerValue(Guid processId, string timerName, DateTime?newValue)
        {
            var parameterName = GetTimerValueParameterName(timerName);

            var processInstance = _runtime.Builder.GetProcessInstance(processId);
            var oldStatus       = _runtime.PersistenceProvider.GetInstanceStatus(processId);
            await _runtime.SetProcessNewStatus(processInstance, ProcessStatus.Running, true).ConfigureAwait(false);

            try
            {
                _runtime.PersistenceProvider.FillProcessParameters(processInstance);

                if (newValue.HasValue)
                {
                    processInstance.SetParameter(parameterName, newValue.Value, ParameterPurpose.Persistence);
                }
                else
                {
                    processInstance.SetParameter <DateTime?>(parameterName, null, ParameterPurpose.Persistence);
                }

                var currentTimers = processInstance.ProcessScheme.GetTimerTransitionForActivity(processInstance.CurrentActivity, ForkTransitionSearchType.Both).ToList();
                var timer         = currentTimers.Where(t => t.Trigger.Timer != null && t.Trigger.Timer.Name.Equals(timerName)).Select(t => t.Trigger.Timer).FirstOrDefault();

                if (timer != null && !timer.NotOverrideIfExists)
                {
                    if (_startStopSemaphore.Wait(DefaultWaitTimeout))
                    {
                        try
                        {
                            var wasRunning = !_stopped;
                            _stopped = true;
                            _timer.Change(Timeout.Infinite, Timeout.Infinite);
                            _cancellationTokenSource.Cancel();
                            var needToClearTimer = !newValue.HasValue && (timer.Value.Equals(ImmediateTimerValue) || timer.Value.Equals(InfinityTimerValue));
                            if (needToClearTimer)
                            {
                                var timersIgnoreList = currentTimers.Where(t => t.Trigger.Timer != null && !t.Trigger.Timer.Name.Equals(timerName))
                                                       .Select(t => t.Trigger.Timer.Name)
                                                       .Distinct()
                                                       .ToList();
                                _runtime.PersistenceProvider.ClearTimers(processInstance.ProcessId, timersIgnoreList);
                            }
                            RefreshOrRegisterTimer(processInstance, new List <TimerDefinition> {
                                timer
                            });
                            _runtime.PersistenceProvider.SavePersistenceParameters(processInstance);
                            await _runtime.SetProcessNewStatus(processInstance, oldStatus, true).ConfigureAwait(false);

                            if (wasRunning)
                            {
                                _stopped = false;
                                _cancellationTokenSource = new CancellationTokenSource();
                                RefreshInterval();
                            }
                        }
                        finally
                        {
                            _startStopSemaphore.Release();
                        }
                    }
                    else
                    {
                        throw new TimerManagerException("Can't start change timer value. Wait timeout expired.");
                    }
                }
                else
                {
                    _runtime.PersistenceProvider.SavePersistenceParameters(processInstance);
                    await _runtime.SetProcessNewStatus(processInstance, oldStatus, true).ConfigureAwait(false);
                }
            }
            catch
            {
                await _runtime.SetProcessNewStatus(processInstance, oldStatus, true).ConfigureAwait(false);

                throw;
            }
        }