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(); } }
public void Dispose() { lock (_expirationLookup) { _expireTimer.Change(DateTime.MaxValue, TaskEnv.None); _expirationLookup.Clear(); OnEntriesExpired(_orderedExpirations); _orderedExpirations.Clear(); } }
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; } } }
/// <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); }
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); } }); } }
private void Flush(TaskTimer flushTimer) { if (_isDisposed) { return; } Flush(); flushTimer.Change(TimeSpan.FromSeconds(1), TaskEnv.None); }
//--- 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); }
//--- 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(); } } }
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()); } } } }
/// <summary> /// Dispose all values currently in the cache. /// </summary> public void Dispose() { _isDisposed = true; _flushTimer.Change(TimeSpan.MaxValue, TaskEnv.None); _cache.Dispose(); }
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()); } } } }
//--- 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); }
public void Dispose() { _pollTimer.Change(DateTime.MinValue, TaskEnv.None); _queueTimer.Change(DateTime.MinValue, TaskEnv.None); _persistentQueue.Dispose(); }
//--- Methods --- public void ResetMemoryExpiration() { _memoryExpire.Change(TimeSpan.FromSeconds(_memoryCacheTime), TaskEnv.Clone()); }