Esempio n. 1
0
 /// <summary>
 /// Gets the owner from the database. If not found null is returned.
 /// </summary>
 /// <param name="id">Instance owner id</param>
 /// <returns></returns>
 public static Models.LockOwner GetOwnerInformation(Guid id)
 {
     using (SqlPersistanceContext db = new SqlPersistanceContext())
     {
         return(db.LockOwners.FirstOrDefault(row => row.Id == id));
     }
 }
Esempio n. 2
0
        /// <summary>
        /// Find any workflows that are not completed and load them up to start running.  If an activity has found to have another owner, it will wait 30 seconds and try again to reload it. If a lock still exists an exception will bubble up.
        /// </summary>
        /// <param name="maxLockWaitInSeconds">Maximum allowed lockExpiration time to wait.</param>
        /// <param name="maxDegreeOfParallelism">How many to load at once.</param>
        /// <exception cref="System.Runtime.DurableInstancing.InstanceLockedException"></exception>
        public static void ReconstituteRunnableInstances(int maxLockWaitInSeconds = 30, int maxDegreeOfParallelism = 4)
        {
            var maxParallelization = new ParallelOptions {
                MaxDegreeOfParallelism = maxDegreeOfParallelism
            };

            using (var db = new SqlPersistanceContext())
            {
                //Only get the instances that are not completed.
                var result = from i in db.Instances where !i.IsCompleted select i;

                //Run each item in parallel they will block automatically.
                Parallel.ForEach(result, maxParallelization, (item) =>
                {
                    bool shouldTryAgain = false;
                    int tryAgainCount   = 0;
                    do
                    {
                        using (ApplicationHelper application = new ApplicationHelper(item.GetActivity(), item.GetIdentity()))
                        {
                            application.IdleAction = IdleAction;
                            try
                            {
                                _log.Debug($"Reloading InstanceId={item.InstanceId} IdleAction={IdleAction}");
                                application.ReloadAndRun(item.InstanceId);
                            }
                            catch (InstanceLockedException ex)
                            {
                                var owner = GetOwnerInformation(ex.InstanceOwnerId);
                                //If the lock is less then 30 seconds just sit back and relax and wait
                                if (owner != null && owner.TimeToLockExpire <= maxLockWaitInSeconds)
                                {
                                    _log.Warn("Sleep thread to wait for the owner to expire then trying again", ex);
                                    System.Threading.Thread.Sleep((int)(owner.TimeToLockExpire + 5d) * 1000);
                                    shouldTryAgain = true;
                                }
                                else
                                {
                                    throw ex;
                                }
                            }
                        }

                        //Make sure it does not try too many times
                        tryAgainCount++;
                    } while (shouldTryAgain && tryAgainCount <= 1);
                });
            }
        }