internal static SecurityActivityHistory GetHistory() { SecurityActivityHistory result; var list = new List <SecurityActivityHistoryItem>(_history.Length); lock (_lock) { for (var i = _position; i < _history.Length; i++) { if (_history[i] != null) { list.Add(_history[i]); } } for (var i = 0; i < _position; i++) { if (_history[i] != null) { list.Add(_history[i]); } } result = new SecurityActivityHistory { State = SecurityActivityQueue.GetCurrentState(), Recent = list.ToArray() }; } return(result); }
public static void Execute(SecurityActivity activity) { if (!_enabled) { return; } SecurityActivityHistory.Start(activity.Id); try { using (var op = SnTrace.SecurityQueue.StartOperation("SAQ: EXECUTION START SA{0} .", activity.Id)) { activity.ExecuteInternal(); op.Successful = true; } } catch (Exception e) { SnTrace.Security.Write("SAQ: EXECUTION ERROR SA{0}: {1}", activity.Id, e.Message); SecurityActivityHistory.Error(activity.Id, e); } finally { DependencyManager.Finish(activity); } }
} // Property injection internal SecurityActivityHistory GetHistory() { SecurityActivityHistory result; var list = new List <SecurityActivityHistoryItem>(_history.Length); lock (_lock) { for (var i = _position; i < _history.Length; i++) { if (_history[i] != null) { list.Add(_history[i]); } } for (var i = 0; i < _position; i++) { if (_history[i] != null) { list.Add(_history[i]); } } result = new SecurityActivityHistory { State = SecurityActivityQueue.GetCurrentState(), Recent = list.ToArray(), Message = _unfinished < 1 ? null : "RECENT ARRAY TOO SHORT. Cannot register the full activity lifecycle. Unfinished items: " + _unfinished }; } return(result); }
internal static void Finish(SecurityActivity activity) { lock (_waitingSetLock) { // activity is done in the ActivityQueue _waitingSet.Remove(activity); // terminate and release waiting threads if there is any. activity.Finish(); // register activity termination in the log. SecurityActivityHistory.Finish(activity.Id); // register activity termination. TerminationHistory.FinishActivity(activity); // execute all activities that are completely freed. foreach (var dependentItem in activity.WaitingForMe.ToArray()) { dependentItem.FinishWaiting(activity); if (dependentItem.WaitingFor.Count == 0) { Task.Run(() => Executor.Execute(dependentItem)); } } } }
public static void EnqueueActivity(SecurityActivity activity) { SnTrace.SecurityQueue.Write("SAQ: SA{0} arrived{1}. {2}", activity.Id, activity.FromReceiver ? " from another computer" : "", activity.TypeName); SecurityActivityHistory.Arrive(activity); lock (_arrivalQueueLock) { if (activity.Id <= _lastQueued) { var sameActivity = _arrivalQueue.FirstOrDefault(a => a.Id == activity.Id); if (sameActivity != null) { sameActivity.Attach(activity); SnTrace.SecurityQueue.Write("SAQ: SA{0} attached to another one in the queue", activity.Id); return; } DependencyManager.AttachOrFinish(activity); return; } if (activity.Id > _lastQueued + 1) { //var loadedActivities = LoadActivities(_lastQueued + 1, activity.Id - 1); var from = _lastQueued + 1; var to = activity.Id - 1; var expectedCount = to - from + 1; var loadedActivities = Retrier.Retry( 3, 100, () => LoadActivities(from, to), (r, i, e) => { if (i < 3) { SnTrace.SecurityQueue.Write("SAQ: Loading attempt {0}", 4 - i); } if (e != null) { return(false); } return(r.Count() == expectedCount); }); foreach (var loadedActivity in loadedActivities) { SecurityActivityHistory.Arrive(loadedActivity); _arrivalQueue.Enqueue(loadedActivity); _lastQueued = loadedActivity.Id; SnTrace.SecurityQueue.Write("SAQ: SA{0} enqueued from db.", loadedActivity.Id); DependencyManager.ActivityEnqueued(); } } _arrivalQueue.Enqueue(activity); _lastQueued = activity.Id; SnTrace.SecurityQueue.Write("SAQ: SA{0} enqueued.", activity.Id); DependencyManager.ActivityEnqueued(); } }
internal static void AttachOrFinish(SecurityActivity activity) { lock (_waitingSetLock) { var sameActivity = _waitingSet.FirstOrDefault(a => a.Id == activity.Id); if (sameActivity != null) { sameActivity.Attach(activity); SnTrace.SecurityQueue.Write("SAQ: SA{0} attached to another in the waiting set.", activity.Id); return; } } activity.Finish(); // release blocked thread SecurityActivityHistory.Finish(activity.Id); SnTrace.SecurityQueue.Write("SAQ: SA{0} ignored: finished but not executed.", activity.Id); }
internal static SecurityActivityHistory Reset() { SecurityActivityHistory result; lock (_lock) { for (var i = 0; i < _history.Length; i++) { _history[i] = null; } _position = 0; _unfinished = 0; result = new SecurityActivityHistory { State = SecurityActivityQueue.GetCurrentState(), Recent = new SecurityActivityHistoryItem[0] }; } return(result); }
private static void MakeDependencies(SecurityActivity newerActivity) { lock (_waitingSetLock) { foreach (var olderActivity in _waitingSet) { Debug.Assert(olderActivity.Id != newerActivity.Id); if (newerActivity.MustWaitFor(olderActivity)) { newerActivity.WaitFor(olderActivity); SnTrace.SecurityQueue.Write("SAQ: SA{0} depends from SA{1}", newerActivity.Id, olderActivity.Id); SecurityActivityHistory.Wait(newerActivity); } } _waitingSet.Add(newerActivity); if (newerActivity.WaitingFor.Count == 0) { Task.Run(() => Executor.Execute(newerActivity)); } } }
/// <summary> /// MUST BE SYNCHRON /// GAPS MUST BE ORDERED /// </summary> internal static void Start(int lastDatabaseId, int lastExecutedId, int[] gaps) { var hasUnprocessed = gaps.Length > 0 || lastDatabaseId != lastExecutedId; SnLog.WriteInformation(EventMessage.Information.StartTheSystem, EventId.RepositoryLifecycle, // ReSharper disable once ArgumentsStyleOther properties: new Dictionary <string, object> { { "LastDatabaseId", lastDatabaseId }, { "LastExecutedId", lastExecutedId }, { "CountOfGaps", gaps.Length }, { "Gaps", string.Join(", ", gaps) } }); DependencyManager.Start(); var count = 0; if (gaps.Any()) { var loadedActivities = new SecurityActivityLoader(gaps, true); foreach (var loadedActivity in loadedActivities) { SnTrace.SecurityQueue.Write("SAQ: Startup: SA{0} enqueued from db.", loadedActivity.Id); SecurityActivityHistory.Arrive(loadedActivity); _arrivalQueue.Enqueue(loadedActivity); _lastQueued = loadedActivity.Id; count++; } } if (lastExecutedId < lastDatabaseId) { var loadedActivities = new SecurityActivityLoader(lastExecutedId + 1, lastDatabaseId, true); foreach (var loadedActivity in loadedActivities) { SnTrace.SecurityQueue.Write("SAQ: Startup: SA{0} enqueued from db.", loadedActivity.Id); SecurityActivityHistory.Arrive(loadedActivity); SnTrace.SecurityQueue.Write("SecurityActivityArrived SA{0}", loadedActivity.Id); _arrivalQueue.Enqueue(loadedActivity); _lastQueued = loadedActivity.Id; count++; } } if (_lastQueued < lastExecutedId) { _lastQueued = lastExecutedId; } // ensure that the arrival activity queue is not empty at this pont. DependencyManager.ActivityEnqueued(); if (lastDatabaseId != 0 || lastExecutedId != 0 || gaps.Any()) { while (IsWorking()) { Thread.Sleep(200); } } if (hasUnprocessed) { SnLog.WriteInformation(string.Format(EventMessage.Information.ExecutingUnprocessedActivitiesFinished, count), EventId.RepositoryLifecycle); } }