private void CheckExpire(TaskTimer timer)
        {
            // get the next scheduled item
            UpdateRecord data = null;

            lock (_data) {
                if (_queue.Count == 0)
                {
                    _queueTimer.Change(_delay, TaskEnv.Current);
                    return;
                }
                Tuplet <string, DateTime> key = _queue.Peek();
                if (key.Item2 > DateTime.UtcNow)
                {
                    _queueTimer.Change(key.Item2, TaskEnv.Current);
                    return;
                }
                data = _data[key.Item1];
                _queue.Dequeue();
                _data.Remove(key.Item1);
            }
            _dispatcher.Dispatch(data);

            // check for optimal sleep interval
            lock (_data) {
                if (_queue.Count == 0)
                {
                    _queueTimer.Change(_delay, TaskEnv.Current);
                    return;
                }
                Tuplet <string, DateTime> key = _queue.Peek();
                _queueTimer.Change(key.Item2, TaskEnv.Current);
            }
        }
 public void Dispose()
 {
     lock (_expirationLookup) {
         _expireTimer.Change(DateTime.MaxValue, TaskEnv.None);
         _expirationLookup.Clear();
     }
 }
示例#3
0
 public void Dispose()
 {
     lock (_expirationLookup) {
         _expireTimer.Change(DateTime.MaxValue, TaskEnv.None);
         _expirationLookup.Clear();
         OnEntriesExpired(_orderedExpirations);
         _orderedExpirations.Clear();
     }
 }
示例#4
0
 private void Poll(TaskTimer timer)
 {
     if (!_poll)
     {
         timer.Change(TimeSpan.FromSeconds(1), TaskEnv.Current);
         return;
     }
     _poll = false;
     while (true)
     {
         // pull item from queue to store in out accumulation queue and hold on to it
         var item = _persistentQueue.Dequeue(TimeSpan.MaxValue);
         if (item == null)
         {
             // didn't find an item, drop out of loop and set timer to check again later
             timer.Change(TimeSpan.FromSeconds(1), TaskEnv.Current);
             return;
         }
         var doc    = item.Value;
         var wikiid = doc["@wikiid"].AsText;
         var id     = new XUri("http://" + wikiid + "/" + doc["path"].AsText);
         lock (_data) {
             UpdateRecord data;
             XUri         channel = doc["channel"].AsUri;
             string       action  = channel.Segments[2];
             if (!_data.TryGetValue(id, out data))
             {
                 _log.DebugFormat("queueing '{0}' for '{1}'", action, id);
                 _queue.Enqueue(new Tuplet <DateTime, XUri>(DateTime.UtcNow.Add(_delay), id));
                 data = new UpdateRecord(id, doc, wikiid);
             }
             else
             {
                 _log.DebugFormat("appending existing queue record '{0}' for '{1}'", action, id);
                 data = data.With(doc);
             }
             if (action != "create" && action != "move")
             {
                 data.ActionStack.PushDelete();
             }
             if (action != "delete")
             {
                 data.ActionStack.PushAdd();
             }
             data.QueueIds.Add(item.Id);
             _data[id] = data;
         }
     }
 }
示例#5
0
        /// <summary>
        /// Create a new timer and set its fire time.
        /// </summary>
        /// <param name="when">Relateive time from now until when the timer should fire.</param>
        /// <param name="handler">The action to invoke when the timer fires.</param>
        /// <param name="state">A state object to associate with the timer.</param>
        /// <param name="env">The environment in which the timer should fire.</param>
        /// <returns>New timer instance.</returns>
        public TaskTimer New(TimeSpan when, Action <TaskTimer> handler, object state, TaskEnv env)
        {
            var result = new TaskTimer(this, handler, state);

            result.Change(when, env);
            return(result);
        }
 //--- Constructors ---
 public UpdateDelayQueue(TimeSpan delay, IUpdateRecordDispatcher dispatcher)
 {
     _delay      = delay;
     _dispatcher = dispatcher;
     _queueTimer = new TaskTimer(CheckExpire, null);
     _queueTimer.Change(_delay, TaskEnv.None);
 }
 //--- Constructors ---
 public NotificationDelayQueue(TimeSpan delay, CoroutineHandler <NotificationUpdateRecord, Result> callback)
 {
     _delay      = delay;
     _callback   = callback;
     _queueTimer = new TaskTimer(CheckExpire, null);
     _queueTimer.Change(_delay, TaskEnv.None);
     _dispatchQueue = new ProcessingQueue <NotificationUpdateRecord>(Dispatch, 10);
 }
示例#8
0
 private void CheckExpire(TaskTimer timer)
 {
     while (true)
     {
         // get the next scheduled item
         UpdateRecord data = null;
         lock (_data) {
             if (_queue.Count == 0)
             {
                 _queueTimer.Change(_delay, TaskEnv.None);
                 return;
             }
             Tuplet <DateTime, XUri> key = _queue.Peek();
             if (key.Item1 > DateTime.UtcNow)
             {
                 _queueTimer.Change(key.Item1, TaskEnv.None);
                 return;
             }
             data = _data[key.Item2];
             _queue.Dequeue();
             _data.Remove(key.Item2);
         }
         Interlocked.Increment(ref _pendingCount);
         _dispatcher.Dispatch(data, new Result(TimeSpan.MaxValue)).WhenDone(r => {
             // cleanup items from the queue
             var poll = false;
             foreach (var itemId in data.QueueIds)
             {
                 if (!_persistentQueue.CommitDequeue(itemId))
                 {
                     // if we couldn't take an item, it must have gone back to the queue, so we better poll again
                     poll = true;
                 }
             }
             if (poll)
             {
                 _poll = true;
             }
             Interlocked.Decrement(ref _pendingCount);
             if (r.HasException)
             {
                 _log.Error(string.Format("dispatch of '{0}' encountered an error", data.Id), r.Exception);
             }
         });
     }
 }
示例#9
0
 private void Flush(TaskTimer flushTimer)
 {
     if (_isDisposed)
     {
         return;
     }
     Flush();
     flushTimer.Change(TimeSpan.FromSeconds(1), TaskEnv.None);
 }
示例#10
0
 //--- Constructors ---
 public Listener(string queuename, Action <AwsSqsMessage> callback, IAwsSqsClient client, TaskTimerFactory timerFactory, TimeSpan interval)
 {
     _queuename  = queuename;
     _callback   = callback;
     _client     = client;
     _cache      = new ExpiringHashSet <string>(timerFactory);
     _cacheTimer = ((interval.TotalSeconds * 2 < 60) ? 60 : interval.TotalSeconds * 2 + 1).Seconds();
     _pollTimer  = timerFactory.New(tt => Coroutine.Invoke(PollSqs, new Result()).WhenDone(r => _pollTimer.Change(interval, TaskEnv.None)), null);
     _pollTimer.Change(0.Seconds(), TaskEnv.None);
 }
        private void CheckExpire(TaskTimer timer)
        {
            // get the next scheduled item
            NotificationUpdateRecord data;

            lock (_pending) {
                if (_queue.Count == 0)
                {
                    _queueTimer.Change(_delay, TaskEnv.Current);
                    return;
                }
                Tuplet <DateTime, string> key = _queue.Peek();
                if (key.Item1 > DateTime.UtcNow)
                {
                    _queueTimer.Change(key.Item1, TaskEnv.Current);
                    return;
                }
                data = _pending[key.Item2];
                _queue.Dequeue();
                _pending.Remove(key.Item2);
            }

            // stuff data into dispatch queue so our worker thread can pick it up and process all data synchronously
            if (!_dispatchQueue.TryEnqueue(data))
            {
                throw new InvalidOperationException(string.Format("Enqueue for user '{0}' failed.", data.UserId));
            }

            // check for optimal sleep interval
            lock (_pending) {
                if (_queue.Count == 0)
                {
                    _queueTimer.Change(_delay, TaskEnv.Current);
                    return;
                }
                Tuplet <DateTime, string> key = _queue.Peek();
                _queueTimer.Change(key.Item1, TaskEnv.Current);
            }
        }
 private void Commit(TaskTimer tt)
 {
     if (_hasUncommittedData)
     {
         _disposalLock.ExecuteWithReadLock(() => {
             EnsureInstanceNotDisposed();
             lock (_updateSyncroot) {
                 _writer.Commit();
                 _searcherIsStale    = true;
                 _hasUncommittedData = false;
             }
         });
     }
     tt.Change(_commitInterval, TaskEnv.None);
 }
示例#13
0
 //--- Methods ---
 public void Update(Action <T> callback)
 {
     lock (_syncRoot) {
         if (_disposed)
         {
             throw new ObjectDisposedException("instance has been disposed");
         }
         callback(_state);
         var updatesCounter = ++_pendingUpdates;
         if ((updatesCounter == 1) && (_maxUpdates > 1))
         {
             _autoFlushTimer.Change(_autoFlushDelay, TaskEnv.None);
         }
         else if (updatesCounter == _maxUpdates)
         {
             Flush();
         }
     }
 }
示例#14
0
        private void OnExpire(TaskTimer timer)
        {
            string name = (string)timer.State;

            lock (_directory) {
                // check if the record still exists
                DirectoryRecord record;
                if (_directory.TryGetValue(name, out record))
                {
                    // verify if the record should still be deleted
                    if (record.Expiration <= timer.When)
                    {
                        _directory.Remove(record.Name);
                    }
                    else
                    {
                        timer.Change(record.Expiration, TaskEnv.Clone());
                    }
                }
            }
        }
示例#15
0
 /// <summary>
 /// Dispose all values currently in the cache.
 /// </summary>
 public void Dispose()
 {
     _isDisposed = true;
     _flushTimer.Change(TimeSpan.MaxValue, TaskEnv.None);
     _cache.Dispose();
 }
示例#16
0
        private void OnExpire(TaskTimer timer)
        {
            string name = (string)timer.State;
            lock(_directory) {

                // check if the record still exists
                DirectoryRecord record;
                if(_directory.TryGetValue(name, out record)) {

                    // verify if the record should still be deleted
                    if(record.Expiration <= timer.When) {
                        _directory.Remove(record.Name);
                    } else {
                        timer.Change(record.Expiration, TaskEnv.Clone());
                    }
                }
            }
        }
示例#17
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);
        }
示例#18
0
 public void Dispose()
 {
     _pollTimer.Change(DateTime.MinValue, TaskEnv.None);
     _queueTimer.Change(DateTime.MinValue, TaskEnv.None);
     _persistentQueue.Dispose();
 }
示例#19
0
 //--- Methods ---
 public void ResetMemoryExpiration()
 {
     _memoryExpire.Change(TimeSpan.FromSeconds(_memoryCacheTime), TaskEnv.Clone());
 }