예제 #1
0
		public async Task Test_Queue_Fast()
		{
			// without high contention protecction

			using (var db = await OpenTestPartitionAsync())
			{
				var location = await GetCleanDirectory(db, "queue");

				var queue = new FdbQueue<int>(location, highContention: false);

				Console.WriteLine("Clear Queue");
				await queue.ClearAsync(db, this.Cancellation);

				Console.WriteLine("Empty? " + await queue.EmptyAsync(db, this.Cancellation));

				Console.WriteLine("Push 10, 8, 6");
				await queue.PushAsync(db, 10, this.Cancellation);
				await queue.PushAsync(db, 8, this.Cancellation);
				await queue.PushAsync(db, 6, this.Cancellation);

#if DEBUG
				await DumpSubspace(db, location);
#endif

				Console.WriteLine("Empty? " + await queue.EmptyAsync(db, this.Cancellation));

				Console.WriteLine("Pop item: " + await queue.PopAsync(db, this.Cancellation));
				Console.WriteLine("Next item: " + await queue.PeekAsync(db, this.Cancellation));
#if DEBUG
				await DumpSubspace(db, location);
#endif

				Console.WriteLine("Pop item: " + await queue.PopAsync(db, this.Cancellation));
#if DEBUG
				await DumpSubspace(db, location);
#endif

				Console.WriteLine("Pop item: " + await queue.PopAsync(db, this.Cancellation));
#if DEBUG
				await DumpSubspace(db, location);
#endif


				Console.WriteLine("Empty? " + await queue.EmptyAsync(db, this.Cancellation));

				Console.WriteLine("Push 5");
				await queue.PushAsync(db, 5, this.Cancellation);
#if DEBUG
				await DumpSubspace(db, location);
#endif

				Console.WriteLine("Clear Queue");
				await queue.ClearAsync(db, this.Cancellation);
#if DEBUG
				await DumpSubspace(db, location);
#endif

				Console.WriteLine("Empty? " + await queue.EmptyAsync(db, this.Cancellation));
			}
		}
예제 #2
0
		private static async Task RunMultiClientTest(IFdbDatabase db, FdbSubspace location, bool highContention, string desc, int K, int NUM, CancellationToken ct)
		{
			Console.WriteLine("Starting {0} test with {1} threads and {2} iterations", desc, K, NUM);

			var queue = new FdbQueue<string>(location, highContention);
			await queue.ClearAsync(db, ct);

			// use a CTS to ensure that everything will stop in case of problems...
			using (var go = new CancellationTokenSource(TimeSpan.FromSeconds(30)))
			{
				var tok = go.Token;

				var pushLock = new AsyncCancelableMutex(tok);
				var popLock = new AsyncCancelableMutex(tok);

				int pushCount = 0;
				int popCount = 0;
				int stalls = 0;

				var pushTreads = Enumerable.Range(0, K)
					.Select(async id =>
					{
						// wait for the signal
						await pushLock.Task.ConfigureAwait(false);

						var res = new List<string>(NUM);

						for (int i = 0; i < NUM; i++)
						{
							var item = id.ToString() + "." + i.ToString();
							await queue.PushAsync(db, item, tok).ConfigureAwait(false);

							Interlocked.Increment(ref pushCount);
							res.Add(item);
						}

						return res;
					}).ToArray();

				var popThreads = Enumerable.Range(0, K)
					.Select(async id =>
					{
						// make everyone wait a bit, to ensure that they all start roughly at the same time
						await popLock.Task.ConfigureAwait(false);

						var res = new List<string>(NUM);

						int i = 0;
						while (i < NUM)
						{
							var item = await queue.PopAsync(db, tok).ConfigureAwait(false);
							if (item.HasValue)
							{
								Interlocked.Increment(ref popCount);
								res.Add(item.Value);
								++i;
							}
							else
							{
								Interlocked.Increment(ref stalls);
								await Task.Delay(10).ConfigureAwait(false);
							}
						}

						return res;
					}).ToArray();

				var sw = Stopwatch.StartNew();

				pushLock.Set(async: true);
				await Task.Delay(100);
				popLock.Set(async: true);

				//using (var timer = new Timer((_) =>
				//{
				//	var __ = TestHelpers.DumpSubspace(db, location);
				//}, null, 1000, 4000))
				{

					await Task.WhenAll(pushTreads);
					await Task.WhenAll(popThreads);
				}

				sw.Stop();
				Console.WriteLine("> Finished {0} test in {1} seconds", desc, sw.Elapsed.TotalSeconds);
				Console.WriteLine("> Pushed {0}, Popped {1} and Stalled {2}", pushCount, popCount, stalls);

				var pushedItems = pushTreads.SelectMany(t => t.Result).ToList();
				var poppedItems = popThreads.SelectMany(t => t.Result).ToList();

				Assert.That(pushCount, Is.EqualTo(K * NUM));
				Assert.That(popCount, Is.EqualTo(K * NUM));

				// all pushed items should have been popped (with no duplicates)
				Assert.That(poppedItems, Is.EquivalentTo(pushedItems));

				// the queue should be empty
				Assert.That(await queue.EmptyAsync(db, ct), Is.True);
			}
		}
예제 #3
0
		public async Task Test_Single_Client()
		{
			using (var db = await OpenTestPartitionAsync())
			{
				var location = await GetCleanDirectory(db, "queue");

				var queue = new FdbQueue<int>(location, highContention: false);

				await queue.ClearAsync(db, this.Cancellation);

				for (int i = 0; i < 10; i++)
				{
					await queue.PushAsync(db, i, this.Cancellation);
				}

				for (int i = 0; i < 10; i++)
				{
					var r = await queue.PopAsync(db, this.Cancellation);
					Assert.That(r.HasValue, Is.True);
					Assert.That(r.Value, Is.EqualTo(i));
				}

				Assert.That(await queue.EmptyAsync(db, this.Cancellation), Is.True);
			}

		}