void WaitForEmptyQueue(LiteQueue <int> queue) { while (queue.Count() > 0 && !_consumerFailed) { Thread.Sleep(5); } }
LiteQueue <T> CreateQueue <T>() { var logCollection = _db.GetCollection <QueueEntry <T> >(_collectionName); var logs = new LiteQueue <T>(logCollection); return(logs); }
void Consumer(LiteQueue <int> queue) { try { while (_keepRunning) { var entry = queue.Dequeue(); if (entry != null) { if (!_consumedRecords.Add(entry.Payload)) { throw new DuplicateException(entry.Payload); } queue.Commit(entry); } else { Thread.Sleep(1); } } } catch { _consumerFailed = true; throw; } }
public void Duplicate() { var queue = new LiteQueue <int>(_db, _collectionName); Action producer = delegate() { BadProducer(queue); }; Action consumer = delegate() { Consumer(queue); }; RunTasks(producer, consumer, producerCount: 1, consumerCount: 1); }
public void MultipleProducersMultipleConsumers() { var queue = new LiteQueue <int>(_db, _collectionName); Action producer = delegate() { Producer(queue); }; Action consumer = delegate() { Consumer(queue); }; RunTasks(producer, consumer, producerCount: 10, consumerCount: 10); }
void BadProducer(LiteQueue <int> queue) { for (int i = 0; i < _recordsToProduce; i++) { int next = 1; // Should cause DuplicateException in consumer queue.Enqueue(next); } }
void Producer(LiteQueue <int> queue) { for (int i = 0; i < _recordsToProduce; i++) { int next = Interlocked.Increment(ref _producerCounter); queue.Enqueue(next); } }
static void Main(string[] args) { // LiteQueue depends on LiteDB. You can save other things to same database. using (var db = new LiteDatabase("Queue.db")) { // Creates a "logs" collection in LiteDB. You can also pass a user defined object. var logs = new LiteQueue <string>(db, "logs"); // Recommended on startup to reset anything that was checked out but not committed or aborted. // Or call CurrentCheckouts to inspect them and abort yourself. See github page for // notes regarding duplicate messages. logs.ResetOrphans(); // Adds record to queue logs.Enqueue("Test"); // Get next item from queue. Marks it as checked out such that other threads that // call Checkout will not see it - but does not remove it from the queue. var record = logs.Dequeue(); try { // Do something that may potentially fail, i.e. a network call // ... // Removes record from queue logs.Commit(record); } catch { // Returns the record to the queue logs.Abort(record); } } Console.WriteLine("Done"); Console.ReadLine(); }
/// <summary> /// Runs a multi-threaded producer/consumer test /// </summary> /// <param name="producerCount"># of producer threads to run</param> /// <param name="consumerCount"># of consumer threads to run</param> /// <param name="producer">Function to run for each producer</param> /// <param name="consumer">Function to run for each consumer</param> void RunTasks(Action producer, Action consumer, int producerCount, int consumerCount) { var queue = new LiteQueue <int>(_db, _collectionName); List <Task> producers = new List <Task>(); for (int i = 0; i < producerCount; i++) { Task producerTask = new Task(producer); producers.Add(producerTask); producerTask.Start(); } List <Task> consumers = new List <Task>(); for (int i = 0; i < consumerCount; i++) { Task consumerTask = new Task(consumer); consumers.Add(consumerTask); consumerTask.Start(); } Task.WaitAll(producers.ToArray()); WaitForEmptyQueue(queue); _keepRunning = false; try { Task.WaitAll(consumers.ToArray()); } catch (AggregateException ex) { throw ex.InnerException; } VerifyAllConsumed(producerCount); }
public void Ctor_DbCollectionName() { var logs = new LiteQueue <string>(_db, _collectionName); Assert.AreEqual(0, logs.Count()); }