private void CheckTimer(DateTime when)
 {
     if (_expireTimer.Status == TaskTimerStatus.Done || _expireTimer.When > when)
     {
         _expireTimer.Change(when, TaskEnv.New());
     }
 }
Example #2
0
        public void New_TaskEnv_does_not_carry_state()
        {
            var state = new State();

            TaskEnv.Current.SetState("foo", state);
            Assert.IsNull(TaskEnv.New().GetState <State>("foo"));
        }
Example #3
0
        private void InsertRecord(DirectoryRecord record)
        {
            // add value to directory
            lock (_directory) {
                _directory[record.Name] = record;
            }

            // check if value has an expiration time
            if (record.HasExpiration)
            {
                TimerFactory.New(record.Expiration, OnExpire, record.Name, TaskEnv.New());
            }

            SaveToFileSystem(record.Name, record.Value);

            // notify event channel
            XDoc notify = new XDoc("insert").Attr("name", record.Name);

            if (record.HasExpiration)
            {
                notify.Attr("expire", record.Expiration);
            }
            notify.Add(record.Value);
            _events.Post(notify, new Result <DreamMessage>(TimeSpan.MaxValue));
        }
Example #4
0
        public void TaskEnv_invoke_with_custom_dispatchqueue_sets_task_state()
        {
            var dispatchQueue = new TestDispatchQueue();

            _log.Debug("setting up envs");
            var   currentState = new State();
            State newState     = null;

            TaskEnv.Current.SetState(currentState);
            var  copiedEnv  = TaskEnv.Clone(dispatchQueue);
            var  newEnv     = TaskEnv.New(dispatchQueue);
            var  resetEvent = new AutoResetEvent(false);
            bool?hasState   = null;

            // Note: have to over acquire otherwise env is wiped after invokenow
            copiedEnv.Acquire();
            copiedEnv.Acquire();
            copiedEnv.Invoke(() => {
                _log.Debug("copied env invoke");
                hasState = currentState == TaskEnv.Current.GetState <State>();
                resetEvent.Set();
            });
            resetEvent.WaitOne();
            dispatchQueue.LastItem.Wait();
            Assert.IsTrue(hasState.HasValue);
            Assert.IsTrue(hasState.Value);
            hasState = null;

            // Note: have to over acquire otherwise env is wiped after invokenow
            newEnv.Acquire();
            newEnv.Acquire();
            newEnv.Acquire();
            newEnv.Invoke(() => {
                _log.Debug("new env invoke");
                hasState = currentState == TaskEnv.Current.GetState <State>();
                newState = new State();
                TaskEnv.Current.SetState(newState);
                resetEvent.Set();
            });
            resetEvent.WaitOne();
            dispatchQueue.LastItem.Wait();
            Assert.IsTrue(hasState.HasValue);
            Assert.IsFalse(hasState.Value);
            Assert.IsNotNull(newState);
            Assert.AreEqual(currentState, TaskEnv.Current.GetState <State>());
            Assert.AreNotEqual(currentState, newState);
            hasState = null;
            newEnv.Invoke(() => {
                _log.Debug("new env invoke 2");
                hasState = newState == TaskEnv.Current.GetState <State>();
                newEnv   = TaskEnv.Current;
                resetEvent.Set();
            });
            resetEvent.WaitOne();
            dispatchQueue.LastItem.Wait();
            Assert.IsTrue(hasState.HasValue);
            Assert.IsTrue(hasState.Value);
        }
Example #5
0
        private static void FibonacciThreadPool(IDispatchQueue stp, int n, TimeSpan delay, out int value, out TimeSpan elapsed)
        {
            _log.Debug("FibonacciThreadPool");

            var sw = Stopwatch.StartNew();

            value = Fibonacci(stp, n, delay, new Result <int>(TimeSpan.MaxValue, TaskEnv.New(stp))).Wait();
            sw.Stop();
            elapsed = sw.Elapsed;
        }
Example #6
0
        public void TaskEnv_invoke_sets_task_state()
        {
            _log.Debug("setting up envs");
            var   currentState = new State();
            State newState     = null;

            TaskEnv.Current.SetState(currentState);
            var  currentEnv = TaskEnv.Current;
            var  newEnv     = TaskEnv.New();
            var  resetEvent = new AutoResetEvent(false);
            bool?hasState   = null;

            // Note: have to over acquire otherwise env is wiped after invokenow
            currentEnv.Acquire();
            currentEnv.Acquire();
            currentEnv.Invoke(() => {
                _log.Debug("current env invoke");
                hasState = currentState == TaskEnv.Current.GetState <State>();
                resetEvent.Set();
            });
            resetEvent.WaitOne();
            Assert.IsTrue(hasState.HasValue);
            Assert.IsTrue(hasState.Value);
            hasState = null;

            // Note: have to over acquire otherwise env is wiped after invokenow
            newEnv.Acquire();
            newEnv.Acquire();
            newEnv.Acquire();
            newEnv.Invoke(() => {
                _log.Debug("new env invoke");
                hasState = currentState == TaskEnv.Current.GetState <State>();
                newState = new State();
                TaskEnv.Current.SetState(newState);
                resetEvent.Set();
            });
            resetEvent.WaitOne();
            Assert.IsTrue(hasState.HasValue);
            Assert.IsFalse(hasState.Value);
            Assert.IsNotNull(newState);
            Assert.AreEqual(currentState, TaskEnv.Current.GetState <State>());
            Assert.AreNotEqual(currentState, newState);
            hasState = null;
            newEnv.Invoke(() => {
                _log.Debug("new env invoke 2");
                hasState = newState == TaskEnv.Current.GetState <State>();
                newEnv   = TaskEnv.Current;
                resetEvent.Set();
            });
            resetEvent.WaitOne();
            Assert.IsTrue(hasState.HasValue);
            Assert.IsTrue(hasState.Value);
        }
        private void OnExpire(TaskTimer timer)
        {
            var          now         = DateTime.UtcNow;
            List <Entry> expirations = null;

            lock (_expirationLookup) {
                // Note (arnec): Sort is cheap here since we're generally dealing with an already sorted or mostly sorted set at this point
                _orderedExpirations.Sort((a, b) => a.When.CompareTo(b.When));
                while (_orderedExpirations.Count > 0)
                {
                    var entry = _orderedExpirations[0];
                    if (entry.Removed)
                    {
                        // this item was already removed from the set, and no longer requires expiration, but does need removal from ordered set
                        _orderedExpirations.RemoveAt(0);
                        continue;
                    }
                    if (entry.When > now)
                    {
                        _expireTimer.Change(entry.When, TaskEnv.New());
                        break;
                    }
                    entry.Removed = true;
                    _expirationLookup.Remove(entry.Key);
                    _orderedExpirations.RemoveAt(0);
                    _log.DebugFormat("expired item with key '{0}'", entry.Key);
                    if (EntriesExpired == null)
                    {
                        continue;
                    }
                    if (expirations == null)
                    {
                        expirations = new List <Entry>();
                    }
                    expirations.Add(entry);
                }
            }
            if (expirations == null)
            {
                return;
            }
            OnEntriesExpired(expirations);
            OnCollectionChange();
        }
Example #8
0
        public void TaskEnv_invokenow_sets_task_state()
        {
            var   currentState = new State();
            State newState     = null;

            TaskEnv.Current.SetState(currentState);
            var  currentEnv = TaskEnv.Current;
            var  newEnv     = TaskEnv.New();
            bool?hasState   = null;

            // Note: have to over acquire otherwise env is wiped after invokenow
            currentEnv.Acquire();
            currentEnv.Acquire();
            currentEnv.InvokeNow(() => {
                hasState = currentState == TaskEnv.Current.GetState <State>();
            });
            Assert.IsTrue(hasState.HasValue);
            Assert.IsTrue(hasState.Value);
            hasState = null;

            // Note: have to over acquire otherwise env is wiped after invokenow
            newEnv.Acquire();
            newEnv.Acquire();
            newEnv.Acquire();
            newEnv.InvokeNow(() => {
                hasState = currentState == TaskEnv.Current.GetState <State>();
                newState = new State();
                TaskEnv.Current.SetState(newState);
            });
            Assert.IsTrue(hasState.HasValue);
            Assert.IsFalse(hasState.Value);
            Assert.IsNotNull(newState);
            Assert.AreEqual(currentState, TaskEnv.Current.GetState <State>());
            Assert.AreNotEqual(currentState, newState);
            hasState = null;
            newEnv.InvokeNow(() => {
                hasState = newState == TaskEnv.Current.GetState <State>();
                newEnv   = TaskEnv.Current;
            });
            Assert.IsTrue(hasState.HasValue);
            Assert.IsTrue(hasState.Value);
        }
Example #9
0
        private static Result <int> Fibonacci(IDispatchQueue stp, int n, TimeSpan delay, Result <int> result)
        {
            if (!ReferenceEquals(result.Env.DispatchQueue, stp))
            {
                _log.Error(string.Format("ERROR: wrong task env {0}, expected {1}.", result.Env.DispatchQueue, stp));
            }
            stp.QueueWorkItem(delegate {
                Interlocked.Increment(ref _counter);
                switch (n)
                {
                case 0:
                    if (delay > TimeSpan.Zero)
                    {
                        Thread.Sleep(delay);
                    }
                    result.Return(0);
                    break;

                case 1:
                    if (delay > TimeSpan.Zero)
                    {
                        Thread.Sleep(delay);
                    }
                    result.Return(1);
                    break;

                default:
                    Result <int> a = Fibonacci(stp, n - 1, delay, new Result <int>(TimeSpan.MaxValue, TaskEnv.New(stp)));
                    Result <int> b = Fibonacci(stp, n - 2, delay, new Result <int>(TimeSpan.MaxValue, TaskEnv.New(stp)));
                    new AResult[] { a, b }.Join(new Result(TimeSpan.MaxValue, TaskEnv.New(stp))).WhenDone(_ => {
                        if (!ReferenceEquals(AsyncUtil.CurrentDispatchQueue, stp))
                        {
                            _log.Error(string.Format("ERROR: wrong queue {0}, expected {1}.", AsyncUtil.CurrentDispatchQueue, stp));
                        }
                        result.Return(a.Value + b.Value);
                    });
                    break;
                }
            });
            return(result);
        }
Example #10
0
        public void ElasticThreadPool_Multi_Staged_Fibonacci_Min_1_Max_30()
        {
            const int test = 4;

            // initialize data structures
            ElasticThreadPool[] stp     = new ElasticThreadPool[test];
            Result <int>[]      results = new Result <int> [test];
            for (int i = 0; i < test; ++i)
            {
                stp[i]     = new ElasticThreadPool(1, 30);
                results[i] = new Result <int>(TimeSpan.MaxValue, TaskEnv.New(stp[i]));
            }

            // start test
            var sw = Stopwatch.StartNew();

            for (int i = 0; i < results.Length; ++i)
            {
                _log.DebugFormat("--- FIBONACCI KICK-OFF: {0}", i);
                Fibonacci(stp[i], 30, TimeSpan.Zero, results[i]);
                Thread.Sleep(TimeSpan.FromSeconds(1));
            }
            results.Join(new Result(TimeSpan.MaxValue)).Wait();
            sw.Stop();
            TimeSpan elapsed = sw.Elapsed;

            // check results
            for (int i = 0; i < test; ++i)
            {
                Assert.AreEqual(832040, results[i].Value, "result {0} did not match", i);
            }
            _log.Debug("Time: " + elapsed);
            _log.Debug("Work items processed: " + _counter);
            for (int i = 0; i < test; ++i)
            {
                stp[i].Dispose();
                Assert.AreEqual(0, stp[i].WorkItemCount, "WorkQueue[{0}] items", i);
                Assert.AreEqual(0, stp[i].ThreadCount, "WorkQueue[{0}] threads", i);
            }
        }
Example #11
0
        //--- Class Methods ---

        /// <summary>
        /// Set an interval at which Garbage collection should be forced.
        /// </summary>
        /// <param name="t">Interval length.</param>
        public static void SetCollectionInterval(TimeSpan t)
        {
            _collectInterval = t;
            _collectTimer.Change(t, TaskEnv.New());
            _log.DebugFormat("set collection interval to {0:0} seconds", t.TotalSeconds);
        }