Exemplo n.º 1
0
        private int Dequeue(ITransactionalQueue <XDoc> queue, ManualResetEvent trigger)
        {
            trigger.WaitOne();
            var j = 0;
            ITransactionalQueueEntry <XDoc> value = queue.Dequeue();

            while (value != null)
            {
                bool success = queue.CommitDequeue(value.Id);
                if (!success)
                {
                    throw new InvalidOperationException();
                }
                j++;
                value = queue.Dequeue();
            }
            return(j);
        }
 private void TryDequeue()
 {
     _dequeueHandler(_currentItem.Value).WhenDone(r => {
         lock(_queue) {
             if(_isDisposed) {
                 return;
             }
             if(r.HasException || !r.Value) {
                 if(_failureWindowStart == DateTime.MinValue) {
                     _failureWindowStart = DateTime.UtcNow;
                 }
                 _queueTimer.Change(_retryTime, TaskEnv.None);
                 return;
             }
             _failureWindowStart = DateTime.MinValue;
             _queue.CommitDequeue(_currentItem.Id);
             _currentItem = _queue.Dequeue();
             if(_currentItem == null) {
                 return;
             }
         }
         TryDequeue();
     });
 }
Exemplo n.º 3
0
        private void Load_test(Func <TransactionalQueue <XDoc> > ctor)
        {
            var rand  = new Random();
            var queue = new QHandle(ctor);

            try {
                var  pending  = new Queue <ITransactionalQueueEntry <XDoc> >();
                var  n        = 10000;
                var  w        = 10;
                var  start    = new int[n * w];
                var  end      = new HashSet <int>();
                var  expired  = 0;
                var  dropped  = 0;
                var  enqueued = 0;
                bool done     = false;
                var  trigger  = new ManualResetEvent(false);
                var  results  = new List <Result>();
                int  v        = 0;
                for (var i = 0; i < w; i++)
                {
                    var values = new List <int>();
                    for (var j = 0; j < n; j++)
                    {
                        values.Add(v);
                        start[v] = v;
                        v++;
                    }
                    results.Add(AsyncUtil.ForkThread(() => {
                        trigger.WaitOne();
                        foreach (var vx in values)
                        {
                            queue.Execute(q => q.Enqueue(new XDoc("doc").Attr("id", vx).Elem("rand", StringUtil.CreateAlphaNumericKey(rand.Next(2, 8)))));
                            Interlocked.Increment(ref enqueued);
                            Thread.Sleep(rand.Next(0, 1));
                        }
                    }, new Result()));
                }
                for (var i = 0; i < 10; i++)
                {
                    results.Add(AsyncUtil.ForkThread(() => {
                        trigger.WaitOne();
                        while (!done)
                        {
                            ITransactionalQueueEntry <XDoc> vx = null;
                            queue.Execute(q => vx = q.Dequeue());
                            if (vx == null)
                            {
                                Thread.Sleep(1000);
                                continue;
                            }
                            lock (pending) {
                                pending.Enqueue(vx);
                            }
                        }
                    }, new Result()));
                }
                for (var i = 0; i < 5; i++)
                {
                    results.Add(AsyncUtil.ForkThread(() => {
                        trigger.WaitOne();
                        while (!done)
                        {
                            ITransactionalQueueEntry <XDoc> vx = null;
                            lock (pending) {
                                if (pending.Count == 0)
                                {
                                    Thread.Sleep(1);
                                    continue;
                                }
                                vx = pending.Dequeue();
                            }
                            var success = false;
                            queue.Execute(q => success = q.CommitDequeue(vx.Id));
                            if (!success)
                            {
                                Interlocked.Increment(ref expired);
                                continue;
                            }
                            lock (end) {
                                end.Add(vx.Value["@id"].AsInt ?? -1);
                            }
                        }
                    }, new Result()));
                }
                results.Add(AsyncUtil.ForkThread(() => {
                    trigger.WaitOne();
                    while (!done)
                    {
                        ITransactionalQueueEntry <XDoc> vx = null;
                        lock (pending) {
                            if (pending.Count == 0)
                            {
                                Thread.Sleep(1000);
                                continue;
                            }
                            vx = pending.Dequeue();
                        }
                        queue.Execute(q => q.RollbackDequeue(vx.Id));
                        Interlocked.Increment(ref dropped);
                        Thread.Sleep(500);
                    }
                }, new Result()));
                trigger.Set();
                int waitCounter = 0;
                while (end.Count != start.Length)
                {
                    var qcount = 0;
                    queue.Execute(q => qcount = q.Count);
                    Console.WriteLine("enqueued: {0}, queue size: {1}, output size: {2}, dropped items: {3}, expired items: {4}",
                                      enqueued,
                                      qcount,
                                      end.Count,
                                      dropped,
                                      expired);
                    foreach (var r in results)
                    {
                        if (r.HasException)
                        {
                            r.Wait();
                        }
                    }

                    Thread.Sleep(1000);
                    waitCounter++;
                    if (waitCounter > 5)
                    {
                        waitCounter = 0;
                        Console.WriteLine("refreshing queue");
                        queue.Refresh();
                    }
                }
                done = true;
                foreach (var r in results)
                {
                    r.Wait();
                }
                Assert.AreEqual(start, (from x in end orderby x select x).ToArray());
                Console.WriteLine("total queue items expired: {0}", expired);
            } finally {
                queue.Dispose();
            }
        }
 private void Kick()
 {
     if(_currentItem != null || _dequeueHandler == null) {
         return;
     }
     lock(_queue) {
         if(_currentItem != null) {
             return;
         }
         _currentItem = _queue.Dequeue();
         if(_currentItem == null) {
             return;
         }
         Async.Fork(TryDequeue);
     }
 }