/// <summary> /// Creates a new <see cref="Timer"/> that will send the current time on its channel <see cref="C"/> after at least /// <paramref name="duration" />. /// </summary> public Timer(TimeSpan duration) { _isTimerActive = true; GoFunc.Run(() => { bool ok; Time.After(duration).ReceiveOk(out ok); if (ok) { _isTimerActive = false; _timerChan.Send(DateTime.Now); _timerChan.Close(); } }, string.Format("timer started:{0} duration:{1}", DateTime.Now, duration)); }
private void BenchmarkTcp(int parallel) { string topicName = "test_benchmark_" + DateTime.Now.UnixNano(); try { const int benchmarkNum = 30000; byte[] body = new byte[512]; var p = new Producer("127.0.0.1:4150"); p.Connect(); var startCh = new Chan <bool>(); var wg = new WaitGroup(); for (int j = 0; j < parallel; j++) { wg.Add(1); GoFunc.Run(() => { startCh.Receive(); for (int i = 0; i < benchmarkNum / parallel; i++) { p.Publish(topicName, body); } wg.Done(); }, "ProducerBenchmarkTcpTest: sendLoop"); } var stopwatch = Stopwatch.StartNew(); startCh.Close(); var done = new Chan <bool>(); GoFunc.Run(() => { wg.Wait(); done.Send(true); }, "waiter and done sender"); bool finished = false; Select .CaseReceive(done, b => finished = b) .CaseReceive(Time.After(TimeSpan.FromSeconds(10)), b => finished = false) .NoDefault(); stopwatch.Stop(); if (!finished) { Assert.Fail("timeout"); } Console.WriteLine(string.Format("{0:#,0} sent in {1:mm\\:ss\\.fff}; Avg: {2:#,0} msgs/s; Threads: {3}", benchmarkNum, stopwatch.Elapsed, benchmarkNum / stopwatch.Elapsed.TotalSeconds, parallel)); p.Stop(); } finally { _nsqdHttpClient.DeleteTopic(topicName); _nsqLookupdHttpClient.DeleteTopic(topicName); } }
public void ClosedChannelsWithDataShouldNotReportClosedUntilDrained() { for (var i = 0; i < 10000; i++) { var chan = new Chan <int>(); var wait = new AutoResetEvent(false); GoFunc.Run(() => { chan.Send(1); chan.Close(); }, "send"); bool ok = false, ok2 = false; int actual = -1, actual2 = -1; GoFunc.Run(() => { actual = chan.ReceiveOk(out ok); actual2 = chan.ReceiveOk(out ok2); wait.Set(); }, "receive"); wait.WaitOne(); Assert.AreEqual(true, ok, string.Format("ok iteration {0}", i)); Assert.AreEqual(1, actual, string.Format("actual iteration {0}", i)); Assert.AreEqual(false, ok2, string.Format("ok2 iteration {0}", i)); Assert.AreEqual(default(int), actual2, string.Format("actual2 iteration {0}", i)); } }
public void SingleNumberGeneratorIEnumerableChan() { var c = new Chan <int>(); var t = new Thread(() => { for (var i = 0; i < 10; i++) { c.Send(i); } c.Close(); }); t.IsBackground = true; t.Start(); var list = new List <int>(); foreach (var i in (IEnumerable)c) { list.Add((int)i); } AssertHelper.AreEqual(new[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }, list); }
/// <summary> /// Stops the ticker and closes the channel, exiting the ticker thread. Note: after closing a channel, /// all reads from the channel will return default(T). See <see cref="Stop"/>. /// </summary> public void Close() { lock (_locker) { Stop(); _tickerChan.Close(); } }
public void SendOnClosedChannelThrows() { var c = new Chan <int>(); c.Close(); c.Send(1); }
public void SendOnClosedChannelThrows() { var c = new Chan <int>(); c.Close(); Assert.Throws <ChannelClosedException>(() => c.Send(1)); }
/// <summary> /// Creates a new <see cref="Timer"/> that will send the current time on its channel <see cref="C"/> after at least /// <paramref name="duration" />. /// </summary> public Timer(TimeSpan duration) { _isTimerActive = 1; GoFunc.Run(() => { bool ok; Time.After(duration).ReceiveOk(out ok); if (ok) { if (Interlocked.CompareExchange(ref _isTimerActive, 0, 1) == 1) { _timerChan.Send(DateTime.Now); _timerChan.Close(); } } }, string.Format("timer started:{0} duration:{1}", DateTime.Now, duration)); }
public void ReceiveOnClosedChannelReturnsDefault() { var c = new Chan <int>(); c.Close(); var val = c.Receive(); Assert.AreEqual(default(int), val); }
public void BufferedChannelsSelectSendAndReceiveInGoroutine() { var c = new Chan <int>(10); var list = new List <int>(); var wg = new WaitGroup(); wg.Add(2); GoFunc.Run(() => { var doLoop = true; while (doLoop) { Select .CaseReceiveOk(c, (i, ok) => { if (ok) { list.Add(i); } else { doLoop = false; } }) .NoDefault(); } wg.Done(); }, "bufferChannelsTest:receiveLoop"); GoFunc.Run(() => { for (var i = 0; i < 10; i++) { Select .CaseSend(c, i) .NoDefault(); } c.Close(); wg.Done(); }, "bufferedChannelsTest:sendLoop"); wg.Wait(); AssertHelper.AreEqual(new[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }, list); }
public void Count() { var chan = new Chan<int>(); chan .Send(Enumerable.Range(0, 10)) .ContinueWith(t => chan.Close()); var counting = chan.Count(); if (!counting.Wait(TimeSpan.FromSeconds(10))) { Assert.Fail(); } Assert.AreEqual(10, counting.Result); }
public void BufferedChannelsSelectSendInGoroutine() { var c = new Chan <int>(10); var list = new List <int>(); var wg = new WaitGroup(); wg.Add(1); GoFunc.Run(() => { for (int i = 0; i < 10; i++) { Select .CaseSend(c, i) .NoDefault(); } c.Close(); wg.Done(); }, "bufferedChannelsTest:sendLoop"); wg.Wait(); bool doLoop = true; // ReSharper disable once LoopVariableIsNeverChangedInsideLoop while (doLoop) { Select .CaseReceiveOk(c, (i, ok) => { if (ok) { list.Add(i); } else { doLoop = false; } }) .NoDefault(); } Assert.AreEqual(new[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }, list.ToArray()); }
public void BufferedChannelsReceiveSelectInGoroutineSendOnMainThread() { var c = new Chan <int>(10); var list = new List <int>(); var wg = new WaitGroup(); wg.Add(1); GoFunc.Run(() => { bool doLoop = true; while (doLoop) { Select .CaseReceiveOk(c, (i, ok) => { if (ok) { list.Add(i); } else { doLoop = false; } }) .NoDefault(); } wg.Done(); }, "bufferChannelsTest:receiveLoop"); for (int i = 0; i < 10; i++) { c.Send(i); } c.Close(); wg.Wait(); Assert.AreEqual(new[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }, list.ToArray()); }
private void BenchmarkHttp(int parallel) { string topicName = "test_benchmark_" + DateTime.Now.UnixNano(); try { const int benchmarkNum = 30000; byte[] body = new byte[512]; var startCh = new Chan <bool>(); var wg = new WaitGroup(); for (int j = 0; j < parallel; j++) { wg.Add(1); GoFunc.Run(() => { startCh.Receive(); for (int i = 0; i < benchmarkNum / parallel; i++) { _nsqdHttpClient.Publish(topicName, body); } wg.Done(); }, "ProducerBenchmarkHttpTest: sendLoop"); } var stopwatch = Stopwatch.StartNew(); startCh.Close(); wg.Wait(); stopwatch.Stop(); Console.WriteLine(string.Format("{0:#,0} sent in {1:mm\\:ss\\.fff}; Avg: {2:#,0} msgs/s; Threads: {3}", benchmarkNum, stopwatch.Elapsed, benchmarkNum / stopwatch.Elapsed.TotalSeconds, parallel)); } finally { _nsqdHttpClient.DeleteTopic(topicName); _nsqLookupdHttpClient.DeleteTopic(topicName); } }
private void OneProducer_OneConsumer_Chan(int capacity, int itemCount) { var chan = new Chan <int>(capacity); var producer = Task.Run(() => { foreach (var i in Enumerable.Range(0, itemCount)) { chan.Send(i); } chan.Close(); }); var consumer = Task.Run(() => { foreach (var i in chan.Yield()) { } }); Task.WaitAll(producer, consumer); }
private void sendCommand(Command cmd) { var doneChan = new Chan <ProducerResponse>(); try { sendCommandAsync(cmd, doneChan); } catch (Exception) { doneChan.Close(); throw; } var t = doneChan.Receive(); if (t.Error != null) { throw t.Error; } }
public void BufferedChannelsReceiveSelectInGoroutineSendOnMainThread() { var c = new Chan<int>(10); var list = new List<int>(); var wg = new WaitGroup(); wg.Add(1); GoFunc.Run(() => { bool doLoop = true; while (doLoop) { Select .CaseReceiveOk(c, (i, ok) => { if (ok) list.Add(i); else doLoop = false; }) .NoDefault(); } wg.Done(); }, "bufferChannelsTest:receiveLoop"); for (int i = 0; i < 10; i++) { c.Send(i); } c.Close(); wg.Wait(); Assert.AreEqual(new[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }, list.ToArray()); }
public void CloseSelecting() { var msgChan = new Chan<int>(); var closeChan = new Chan<bool>(); Func<Task> select = async () => { var run = true; while (run) { await new Select() .Case(msgChan, (_, ok) => {}) .Case(closeChan, (_, ok) => { run = false; }) .End(); } }; var t = select(); msgChan.Close(); closeChan.Send(true).ContinueWith(_ => t.Wait()).Wait(); }
public void Forward() { var source = new Chan<int>(); var target = new Chan<int>(); var tasks = new Task[2]; tasks[0] = source.Forward(target); source .Send(Enumerable.Range(0, 10)) .ContinueWith(t => source.Close()); var cnt = 0; tasks[1] = target.ForEach(item => cnt++); if (!Task.WaitAll(tasks, TimeSpan.FromSeconds(10))) { Assert.Fail(); } }
public void ClosedChannelsWithDataShouldNotReportClosedUntilDrained() { for (int i = 0; i < 10000; i++) { var chan = new Chan<int>(); var wait = new AutoResetEvent(initialState: false); GoFunc.Run(() => { chan.Send(1); chan.Close(); }, "send"); bool ok = false, ok2 = false; int actual = -1, actual2 = -1; GoFunc.Run(() => { actual = chan.ReceiveOk(out ok); actual2 = chan.ReceiveOk(out ok2); wait.Set(); }, "receive"); wait.WaitOne(); Assert.AreEqual(true, ok, string.Format("ok iteration {0}", i)); Assert.AreEqual(1, actual, string.Format("actual iteration {0}", i)); Assert.AreEqual(false, ok2, string.Format("ok2 iteration {0}", i)); Assert.AreEqual(default(int), actual2, string.Format("actual2 iteration {0}", i)); } }
public void BufferedChannelsSelectSendInGoroutine() { var c = new Chan<int>(10); var list = new List<int>(); var wg = new WaitGroup(); wg.Add(1); GoFunc.Run(() => { for (int i = 0; i < 10; i++) { Select .CaseSend(c, i) .NoDefault(); } c.Close(); wg.Done(); }, "bufferedChannelsTest:sendLoop"); wg.Wait(); bool doLoop = true; // ReSharper disable once LoopVariableIsNeverChangedInsideLoop while (doLoop) { Select .CaseReceiveOk(c, (i, ok) => { if (ok) list.Add(i); else doLoop = false; }) .NoDefault(); } Assert.AreEqual(new[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }, list.ToArray()); }
public void MultiThreadedSelectTestWithDefer() { var c1 = new Chan <int>(); var c2 = new Chan <int>(); var done = new Chan <bool>(); var start = new Chan <bool>(); int c1Count = 0; int c2Count = 0; int count = 0; int totalReceived = 0; Action receive = () => { start.Receive(); int val1 = 0; int val2 = 0; bool doLoop = true; var select = Select .CaseReceive(c1, i => val1 = i) .CaseReceive(c2, i => val2 = i) .CaseReceive(done, b => doLoop = false) .NoDefault(defer: true); while (doLoop) { val1 = 0; val2 = 0; select.Execute(); if (doLoop) { Assert.IsTrue(val1 == 0 || val2 == 0, "val1 == 0 || val2 == 0"); Assert.IsTrue(val1 == 1 || val2 == 2, "val1 == 1 || val2 == 2"); } Interlocked.Increment(ref totalReceived); } }; Action send = () => { start.Receive(); var select = Select .CaseSend(c1, 1, () => Interlocked.Increment(ref c1Count)) .CaseSend(c2, 2, () => Interlocked.Increment(ref c2Count)) .NoDefault(defer: true); while (count < 30000) { Interlocked.Increment(ref count); select.Execute(); } done.Close(); }; for (int i = 0; i < 8; i++) { GoFunc.Run(receive, "receiver"); GoFunc.Run(send, "sender"); } start.Close(); done.Receive(); Assert.GreaterOrEqual(count, 30000); Assert.Greater(totalReceived, 29900); }
public void Purge() { var chan = new Chan<int>(); chan .Send(Enumerable.Range(0, 10)) .ContinueWith(t => chan.Close()); if (!chan.Purge().Wait(TimeSpan.FromSeconds(10))) { Assert.Fail(); } }
public void Close() { _closeCh.Close(); }
public void SendOnClosedChannelThrows() { var c = new Chan<int>(); c.Close(); Assert.Throws<ChannelClosedException>(() => c.Send(1)); }
private void BenchmarkHttp(int parallel) { string topicName = "test_benchmark_" + DateTime.Now.UnixNano(); try { const int benchmarkNum = 30000; byte[] body = new byte[512]; var startCh = new Chan<bool>(); var wg = new WaitGroup(); for (int j = 0; j < parallel; j++) { wg.Add(1); GoFunc.Run(() => { startCh.Receive(); for (int i = 0; i < benchmarkNum / parallel; i++) { _nsqdHttpClient.Publish(topicName, body); } wg.Done(); }, "ProducerBenchmarkHttpTest: sendLoop"); } var stopwatch = Stopwatch.StartNew(); startCh.Close(); wg.Wait(); stopwatch.Stop(); Console.WriteLine(string.Format("{0:#,0} sent in {1:mm\\:ss\\.fff}; Avg: {2:#,0} msgs/s; Threads: {3}", benchmarkNum, stopwatch.Elapsed, benchmarkNum / stopwatch.Elapsed.TotalSeconds, parallel)); } finally { _nsqdHttpClient.DeleteTopic(topicName); _nsqLookupdHttpClient.DeleteTopic(topicName); } }
public void Spread() { var chan1 = new Chan<int>(); var chan2 = new Chan<int>(); var chan3 = new Chan<int>(); var source = new Chan<int>(); var tasks = new Task[4]; tasks[0] = source.Spread(new[] { chan1, chan2, chan3 }); source .Send(Enumerable.Range(0, 10)) .ContinueWith(t => source.Close()); var cnt1 = 0; tasks[1] = chan1.ForEach(item => cnt1++); var cnt2 = 0; tasks[2] = chan2.ForEach(item => cnt2++); var cnt3 = 0; tasks[3] = chan3.ForEach(item => cnt3++); if (!Task.WaitAll(tasks, TimeSpan.FromSeconds(10))) { Assert.Fail(); } Assert.AreEqual(30, cnt1 + cnt2 + cnt3); }
public void SendReceive() { var chan = new Chan<int>(); chan .Send(Enumerable.Range(0, 10)) .ContinueWith(t => chan.Close()); var cnt = 0; var collection = chan.ForEach(item => cnt++); if (!collection.Wait(TimeSpan.FromSeconds(10))) { Assert.Fail(); } Assert.AreEqual(10, cnt); }
private void BenchmarkTcp(int parallel) { string topicName = "test_benchmark_" + DateTime.Now.UnixNano(); try { const int benchmarkNum = 30000; byte[] body = new byte[512]; var p = new Producer("127.0.0.1:4150"); p.Connect(); var startCh = new Chan<bool>(); var wg = new WaitGroup(); for (int j = 0; j < parallel; j++) { wg.Add(1); //int localj = j; GoFunc.Run(() => { startCh.Receive(); for (int i = 0; i < benchmarkNum / parallel; i++) { //if (i%10 == 0) //{ // Debug.WriteLine(string.Format("{0}: {1}/{2}", localj, i, benchmarkNum/parallel)); //} p.Publish(topicName, body); } wg.Done(); }, "ProducerBenchmarkTcpTest: sendLoop"); } var stopwatch = Stopwatch.StartNew(); startCh.Close(); var done = new Chan<bool>(); GoFunc.Run(() => { wg.Wait(); done.Send(true); }); bool finished = false; Select .CaseReceive(done, b => finished = b) .CaseReceive(Time.After(TimeSpan.FromSeconds(10)), b => finished = false) .NoDefault(); stopwatch.Stop(); if (!finished) { Assert.Fail("timeout"); } Console.WriteLine(string.Format("{0:#,0} sent in {1:mm\\:ss\\.fff}; Avg: {2:#,0} msgs/s; Threads: {3}", benchmarkNum, stopwatch.Elapsed, benchmarkNum / stopwatch.Elapsed.TotalSeconds, parallel)); } finally { _nsqdHttpClient.DeleteTopic(topicName); _nsqLookupdHttpClient.DeleteTopic(topicName); } }
public void MultiThreadedSelectTestWithoutDefer() { var c1 = new Chan<int>(); var c2 = new Chan<int>(); var done = new Chan<bool>(); var start = new Chan<bool>(); int c1Count = 0; int c2Count = 0; int count = 0; int totalReceived = 0; Action receive = () => { start.Receive(); int val1 = 0; int val2 = 0; bool doLoop = true; while (doLoop) { val1 = 0; val2 = 0; Select .CaseReceive(c1, i => val1 = i) .CaseReceive(c2, i => val2 = i) .CaseReceive(done, b => doLoop = false) .NoDefault(); if (doLoop) { Assert.IsTrue(val1 == 0 || val2 == 0, "val1 == 0 || val2 == 0"); Assert.IsTrue(val1 == 1 || val2 == 2, "val1 == 1 || val2 == 2"); } Interlocked.Increment(ref totalReceived); } }; Action send = () => { start.Receive(); while (count < 10000) { Interlocked.Increment(ref count); Select .CaseSend(c1, 1, () => Interlocked.Increment(ref c1Count)) .CaseSend(c2, 2, () => Interlocked.Increment(ref c2Count)) .NoDefault(); Select .CaseSend(c2, 2, () => Interlocked.Increment(ref c2Count)) .CaseSend(c1, 1, () => Interlocked.Increment(ref c1Count)) .NoDefault(); } done.Close(); }; for (int i = 0; i < 8; i++) { GoFunc.Run(receive); GoFunc.Run(send); } start.Close(); done.Receive(); Assert.GreaterOrEqual(count, 10000); Assert.Greater(totalReceived, 19900); }
public void Merge() { var chan1 = new Chan<int>(); var chan2 = new Chan<int>(); chan1 .Send(Enumerable.Range(0, 10)) .ContinueWith(t => chan1.Close()); chan2 .Send(Enumerable.Range(0, 10)) .ContinueWith(t => chan2.Close()); var mergedChan = chan1.Merge(chan2); var cnt = 0; var collection = mergedChan.ForEach(item => cnt++); if (!collection.Wait(TimeSpan.FromSeconds(10))) { Assert.Fail(); } Assert.AreEqual(20, cnt); }
public void ReceiveOnClosedChannelReturnsDefault() { var c = new Chan<int>(); c.Close(); int val = c.Receive(); Assert.AreEqual(default(int), val); }
private static async void WaitAndSend(TimeSpan delay, Chan<DateTime> chan) { await Task.Delay(delay); await chan.Send(DateTime.Now); chan.Close(); }
public void SingleNumberGeneratorIEnumerableChan() { var c = new Chan<int>(); var t = new Thread(() => { for (int i = 0; i < 10; i++) { c.Send(i); } c.Close(); }); t.IsBackground = true; t.Start(); var list = new List<int>(); foreach (var i in (IEnumerable)c) { list.Add((int)i); } Assert.AreEqual(new[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }, list); }
public void MultiThreadedSelectTestWithoutDefer() { var c1 = new Chan <int>(); var c2 = new Chan <int>(); var done = new Chan <bool>(); var start = new Chan <bool>(); var c1Count = 0; var c2Count = 0; var count = 0; var totalReceived = 0; Action receive = () => { start.Receive(); var val1 = 0; var val2 = 0; var doLoop = true; while (doLoop) { val1 = 0; val2 = 0; Select .CaseReceive(c1, i => val1 = i) .CaseReceive(c2, i => val2 = i) .CaseReceive(done, b => doLoop = false) .NoDefault(); if (doLoop) { Assert.IsTrue(val1 == 0 || val2 == 0, "val1 == 0 || val2 == 0"); Assert.IsTrue(val1 == 1 || val2 == 2, "val1 == 1 || val2 == 2"); } Interlocked.Increment(ref totalReceived); } }; Action send = () => { start.Receive(); while (count < 10000) { Interlocked.Increment(ref count); Select .CaseSend(c1, 1, () => Interlocked.Increment(ref c1Count)) .CaseSend(c2, 2, () => Interlocked.Increment(ref c2Count)) .NoDefault(); Select .CaseSend(c2, 2, () => Interlocked.Increment(ref c2Count)) .CaseSend(c1, 1, () => Interlocked.Increment(ref c1Count)) .NoDefault(); } done.Close(); }; for (var i = 0; i < 8; i++) { GoFunc.Run(receive, "receiver"); GoFunc.Run(send, "sender"); } start.Close(); done.Receive(); Assert.IsTrue(count >= 10000); Assert.IsTrue(totalReceived > 19900); }
public void Select() { var chan = new Chan<int>(); chan .Send(Enumerable.Range(0, 10)) .ContinueWith(t => chan.Close()); var sum = 0; var collection = chan .Select(item => item % 2) .ForEach(item => sum += item); if (!collection.Wait(TimeSpan.FromSeconds(10))) { Assert.Fail(); } Assert.AreEqual(5, sum); }
/// <summary> /// Stops the ticker and closes the channel, exiting the ticker thread. Note: after closing a channel, /// all reads from the channel will return default(T). See <see cref="Stop"/>. /// </summary> public void Close() { Stop(); _tickerChan.Close(); }