Esempio n. 1
0
            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);
                }
            }
Esempio n. 2
0
        /// <summary>
        /// Ensures an exclusive (only one) object for the activity. Returns the new lock object or null.
        /// </summary>
        public SecurityActivityExecutionLock AcquireSecurityActivityExecutionLock(
            SecurityActivity securityActivity, int timeoutInSeconds)
        {
            var maxTime = timeoutInSeconds == int.MaxValue ? DateTime.MaxValue : DateTime.UtcNow.AddSeconds(timeoutInSeconds);

            while (DateTime.UtcNow < maxTime)
            {
                string result;
                using (var db = Db())
                    result = db.AcquireSecurityActivityExecutionLock(
                        securityActivity.Id, securityActivity.Context.MessageProvider.ReceiverName, timeoutInSeconds);

                // ReSharper disable once SwitchStatementMissingSomeCases
                switch (result)
                {
                case ExecutionState.LockedForYou:
                    // enable full executing
                    return(new SecurityActivityExecutionLock(securityActivity, true));

                case ExecutionState.Executing:
                case ExecutionState.Done:
                    // enable partially executing
                    return(new SecurityActivityExecutionLock(securityActivity, false));
                }
            }
            throw new SecurityActivityTimeoutException(
                      $"Waiting for a SecurityActivityExecutionLock timed out: #{securityActivity.Id}/{securityActivity.TypeName}");
        }
Esempio n. 3
0
 internal static void ReleaseSecurityActivityExecutionLock(SecurityActivity securityActivity, bool fullExecutionEnabled)
 {
     if (fullExecutionEnabled)
     {
         securityActivity.Context.DataProvider.ReleaseSecurityActivityExecutionLock(securityActivity);
     }
 }
Esempio n. 4
0
        internal void SaveActivity(SecurityActivity activity)
        {
            var id = _dataProvider.SaveSecurityActivity(activity, out var bodySize);

            activity.BodySize = bodySize;
            activity.Id       = id;
        }
Esempio n. 5
0
            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));
                        }
                    }
                }
            }
Esempio n. 6
0
            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();
                }
            }
Esempio n. 7
0
        internal static void SaveActivity(SecurityActivity activity)
        {
            int bodySize;
            var id = activity.Context.DataProvider.SaveSecurityActivity(activity, out bodySize);

            activity.BodySize = bodySize;
            activity.Id       = id;
        }
Esempio n. 8
0
        public static void ExecuteActivity(SecurityActivity activity)
        {
            if (!activity.FromDatabase && !activity.FromReceiver)
            {
                DataHandler.SaveActivity(activity);
            }

            Serializer.EnqueueActivity(activity);
        }
Esempio n. 9
0
 public int SaveSecurityActivity(SecurityActivity activity, out int bodySize)
 {
     lock (_messageLock)
     {
         var id   = Interlocked.Increment(ref _lastActivityId);
         var body = SecurityActivity.SerializeActivity(activity);
         bodySize = body.Length;
         _storage.Messages.Add(new Tuple <int, DateTime, byte[]>(id, DateTime.UtcNow, body));
         return(id);
     }
 }
        /// <summary>
        /// Initializes a new instance of the SecurityActivityExecutionLock
        /// </summary>
        /// <param name="activity">Activity that is locked.</param>
        /// <param name="fullExecutionEnabled">If true, all activity operation must be executed:
        /// storing, distributing, applying in the memory. Otherwise only the memor operations are allowed.</param>
        public SecurityActivityExecutionLock(SecurityActivity activity, bool fullExecutionEnabled)
        {
            _activity            = activity;
            FullExecutionEnabled = fullExecutionEnabled;

            var interval = Configuration.SecurityActivityExecutionLockRefreshPeriodInSeconds * 1000.0;

            _timer = new Timer(interval)
            {
                Enabled = true
            };
            _timer.Elapsed  += Refresh;
            _timer.Disposed += Refresh;
        }
 internal static void Wait(SecurityActivity activity)
 {
     lock (_lock)
     {
         foreach (var item in _history)
         {
             if (item != null && item.Id == activity.Id)
             {
                 item.WaitedFor = activity.WaitingFor.Select(a => a.Id).ToArray();
                 break;
             }
         }
     }
 }
Esempio n. 12
0
        public virtual SecurityActivity LoadSecurityActivity(int id)
        {
            lock (_messageLock)
            {
                var item = _storage.Messages.Where(x => x.Item1 == id).FirstOrDefault();
                if (item == null)
                {
                    return(null);
                }

                var activity = SecurityActivity.DeserializeActivity(item.Item3);
                activity.Id = item.Item1;
                return(activity);
            }
        }
Esempio n. 13
0
        /// <summary>
        /// Returns a SecurityActivity.
        /// </summary>
        public SecurityActivity LoadSecurityActivity(int id)
        {
            using (var db = Db())
            {
                var item = db.EFMessages.FirstOrDefault(x => x.Id == id);
                if (item == null)
                {
                    return(null);
                }

                var activity = SecurityActivity.DeserializeActivity(item.Body);
                activity.Id = item.Id;
                return(activity);
            }
        }
Esempio n. 14
0
 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);
 }
Esempio n. 15
0
 public byte[] SerializeActivity(SecurityActivity activity)
 {
     try
     {
         var ms = new MemoryStream();
         var bf = new BinaryFormatter();
         bf.Serialize(ms, activity);
         ms.Flush();
         ms.Position = 0;
         return(ms.GetBuffer());
     }
     catch (Exception e) // logged and rethrown
     {
         SnLog.WriteException(e, EventMessage.Error.Serialization, EventId.Serialization);
         throw;
     }
 }
Esempio n. 16
0
        public SecurityActivity DeserializeActivity(byte[] bytes)
        {
            Stream data = new MemoryStream(bytes);

            var bf = new BinaryFormatter();
            SecurityActivity activity = null;

            try
            {
                activity         = (SecurityActivity)bf.Deserialize(data);
                activity.Context = _securitySystem.GeneralSecurityContext;
            }
            catch (SerializationException e) // logged
            {
                SnLog.WriteException(e, EventMessage.Error.Deserialization, EventId.Serialization);
            }
            return(activity);
        }
Esempio n. 17
0
        /// <summary>
        /// Stores the full data of the passed activity.
        /// Returns with the generated activity id and the size of the activity's body.
        /// Activity ids in the database must be a consecutive list of numbers.
        /// </summary>
        /// <param name="activity">Activity to save.</param>
        /// <param name="bodySize">Activity size in bytes.</param>
        /// <returns>The generated activity id.</returns>
        public int SaveSecurityActivity(SecurityActivity activity, out int bodySize)
        {
            var body = SecurityActivity.SerializeActivity(activity);

            bodySize = body.Length;
            EntityEntry <EFMessage> result;

            using (var db = Db())
            {
                result = db.EFMessages.Add(new EFMessage
                {
                    ExecutionState = ExecutionState.Wait,
                    SavedBy        = activity.Context.MessageProvider.ReceiverName,
                    SavedAt        = DateTime.UtcNow,
                    Body           = body
                });
                db.SaveChanges();
            }
            return(result.Entity.Id);
        }
        internal static void Arrive(SecurityActivity activity)
        {
            lock (_lock)
            {
                // avoiding duplication
                foreach (var item in _history)
                {
                    if (item != null && item.Id == activity.Id)
                    {
                        return;
                    }
                }

                var retired = _history[_position];
                _history[_position] = new SecurityActivityHistoryItem
                {
                    Id           = activity.Id,
                    TypeName     = activity.TypeName,
                    FromReceiver = activity.FromReceiver,
                    FromDb       = activity.FromDatabase,
                    IsStartup    = activity.IsUnprocessedActivity,
                    ArrivedAt    = DateTime.UtcNow,
                    StartedAt    = DateTime.MinValue,
                    FinishedAt   = DateTime.MinValue
                };

                if (retired != null)
                {
                    if (retired.FinishedAt == DateTime.MinValue)
                    {
                        _unfinished++;
                    }
                }

                _position++;
                if (_position >= HistoryLength)
                {
                    _position = 0;
                }
            }
        }
Esempio n. 19
0
        /// <summary>
        /// Loads a SecurityActivity fragment by the individual id array.
        /// Activities in the result array are sorted by id.
        /// Value of the IsUnprocessedActivity property of every loaded object
        /// vill be the value of the given "executingUnprocessedActivities" parameter.
        /// </summary>
        /// <param name="gaps">Individual id array</param>
        /// <param name="executingUnprocessedActivities">
        /// Value of the IsUnprocessedActivity property of every loaded object.</param>
        public SecurityActivity[] LoadSecurityActivities(int[] gaps, bool executingUnprocessedActivities)
        {
            var result = new List <SecurityActivity>();

            using (var db = Db())
            {
                foreach (var item in db.EFMessages.Where(x => gaps.Contains(x.Id)).OrderBy(x => x.Id))
                {
                    var activity = SecurityActivity.DeserializeActivity(item.Body);
                    if (activity == null)
                    {
                        continue;
                    }
                    activity.Id                    = item.Id;
                    activity.FromDatabase          = true;
                    activity.IsUnprocessedActivity = executingUnprocessedActivities;
                    result.Add(activity);
                }
            }
            return(result.ToArray());
        }
Esempio n. 20
0
            internal static void FinishActivity(SecurityActivity activity)
            {
                var id = activity.Id;

                lock (_gapsLock)
                {
                    if (id > _lastId)
                    {
                        if (id > _lastId + 1)
                        {
                            _gaps.AddRange(Enumerable.Range(_lastId + 1, id - _lastId - 1));
                        }
                        _lastId = id;
                    }
                    else
                    {
                        _gaps.Remove(id);
                    }
                    SnTrace.SecurityQueue.Write("SAQ: State after finishing SA{0}: {1}", id, GetCurrentState());
                }
            }
Esempio n. 21
0
        public SecurityActivity[] LoadSecurityActivities(int[] gaps, bool executingUnprocessedActivities)
        {
            lock (_messageLock)
            {
                var result = new List <SecurityActivity>();

                foreach (var item in _storage.Messages.Where(x => gaps.Contains(x.Item1)))
                {
                    var activity = SecurityActivity.DeserializeActivity(item.Item3);
                    if (activity == null)
                    {
                        continue;
                    }
                    activity.Id                    = item.Item1;
                    activity.FromDatabase          = true;
                    activity.IsUnprocessedActivity = executingUnprocessedActivities;
                    result.Add(activity);
                }

                return(result.ToArray());
            }
        }
Esempio n. 22
0
        public SecurityActivity[] LoadSecurityActivities(int from, int to, int count, bool executingUnprocessedActivities)
        {
            lock (_messageLock)
            {
                var result = new List <SecurityActivity>();

                foreach (var item in _storage.Messages.Where(x => x.Item1 >= from && x.Item1 <= to).Take(count))
                {
                    var activity = SecurityActivity.DeserializeActivity(item.Item3);
                    if (activity == null)
                    {
                        continue;
                    }
                    activity.Id                    = item.Item1;
                    activity.FromDatabase          = true;
                    activity.IsUnprocessedActivity = executingUnprocessedActivities;
                    result.Add(activity);
                }

                return(result.ToArray());
            }
        }
Esempio n. 23
0
        private static void MessageProvider_MessageReceived(object sender, MessageReceivedEventArgs args)
        {
            var message = args.Message;

            // debug game
            if (message is PingMessage)
            {
                _messageProvider.SendMessage(new PongMessage());
                return;
            }

            SecurityActivity activity = null;

            // load from database if it was too big to distribute
            var bigActivityMessage = message as BigActivityMessage;

            if (bigActivityMessage != null)
            {
                activity = DataHandler.LoadBigSecurityActivity(bigActivityMessage.DatabaseId);
                if (activity == null)
                {
                    SnTrace.Security.WriteError("Cannot load body of a BigActivity. Id: {0}", bigActivityMessage.DatabaseId);
                }
            }

            // trying to interpret
            if (activity == null)
            {
                activity = message as SecurityActivity;
            }

            // Apply if everything is good
            if (activity != null)
            {
                activity.FromReceiver = true;
                SecurityActivity.Apply(activity);
            }
        }
Esempio n. 24
0
            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));
                    }
                }
            }
Esempio n. 25
0
 public void RefreshSecurityActivityExecutionLock(SecurityActivity securityActivity)
 {
     // do nothing
 }
Esempio n. 26
0
 internal static void RefreshSecurityActivityExecutionLock(SecurityActivity securityActivity)
 {
     securityActivity.Context.DataProvider.RefreshSecurityActivityExecutionLock(securityActivity);
 }
Esempio n. 27
0
        internal static Messaging.SecurityActivityExecutionLock AcquireSecurityActivityExecutionLock(SecurityActivity securityActivity)
        {
            var timeout = Debugger.IsAttached
                ? int.MaxValue
                : Configuration.SecurityActivityExecutionLockTimeoutInSeconds;

            return(securityActivity.Context.DataProvider
                   .AcquireSecurityActivityExecutionLock(securityActivity, timeout));
        }
Esempio n. 28
0
 internal override bool MustWaitFor(SecurityActivity olderActivity)
 {
     return(false);
 }
Esempio n. 29
0
 public void ReleaseSecurityActivityExecutionLock(SecurityActivity securityActivity)
 {
     // do nothing
 }
Esempio n. 30
0
 public Messaging.SecurityActivityExecutionLock AcquireSecurityActivityExecutionLock(SecurityActivity securityActivity, int timeoutInSeconds)
 {
     return(new Messaging.SecurityActivityExecutionLock(securityActivity, true));
 }