示例#1
0
        public void Only_one_thread_can_acquire_the_lock_at_a_time()
        {
            var l       = new Lock <int>(1);
            var trigger = new ManualResetEvent(false);
            var first   = AsyncUtil.Fork(() =>
            {
                trigger.WaitOne();
                Thread.Sleep(200);
                l.Capture(new Result()).Wait();
            }, new Result());
            Result secondInternal = null;
            var    second         = AsyncUtil.Fork(() =>
            {
                trigger.WaitOne();
                secondInternal = l.Capture(new Result());
            }, new Result());

            trigger.Set();
            Assert.IsFalse(first.HasValue);
            second.Wait();
            l.Release();
            Assert.IsTrue(secondInternal.HasValue);
            Assert.IsFalse(first.HasValue);
            secondInternal.Wait();
            first.Wait();
            Assert.IsTrue(first.HasValue);
        }
示例#2
0
        public void Forked_thread_has_copy_of_current_state()
        {
            var state = new State();

            TaskEnv.Current.SetState(state);
            Assert.IsTrue(AsyncUtil.Fork(() => (state == TaskEnv.Current.GetState <State>()), new Result <bool>()).Wait());
        }
示例#3
0
        /// <summary>
        /// Asynchronous copying of one stream to another.
        /// </summary>
        /// <param name="source">Source <see cref="Stream"/>.</param>
        /// <param name="target">Target <see cref="Stream"/>.</param>
        /// <param name="length">Number of bytes to copy from source to target.</param>
        /// <param name="result">The <see cref="Result"/> instance to be returned by the call.</param>
        /// <returns>Synchronization handle for the number of bytes copied.</returns>
        public static Result <long> CopyToStream(this Stream source, Stream target, long length, Result <long> result)
        {
            if (!SysUtil.UseAsyncIO)
            {
                return(AsyncUtil.Fork(() => CopyToStream(source, target, length), result));
            }

            // NOTE (steveb): intermediary copy steps already have a timeout operation, no need to limit the duration of the entire copy operation

            if ((source == Stream.Null) || (length == 0))
            {
                result.Return(0);
            }
            else if (source.IsStreamMemorized() && target.IsStreamMemorized())
            {
                // source & target are memory streams; let's do the copy inline as fast as we can
                result.Return(CopyToStream(source, target, length));
            }
            else
            {
                // use new task environment so we don't copy the task state over and over again
                TaskEnv.ExecuteNew(() => Coroutine.Invoke(CopyTo_Helper, source, target, length, result));
            }
            return(result);
        }
示例#4
0
        public void Matches_request_doc_to_expectations()
        {
            AutoMockPlug autoPlug = MockPlug.Register(new XUri("http://auto/plug"));

            autoPlug.Expect().Verb("POST").Uri(new XUri("http://auto/plug/a")).RequestDocument(new XDoc("foo"));
            AsyncUtil.Fork(() => Plug.New("http://auto/plug/a").PostAsync(new XDoc("foo")), new Result());
            Assert.IsTrue(autoPlug.WaitAndVerify(TimeSpan.FromSeconds(1)), autoPlug.VerificationFailure);
        }
示例#5
0
        public void Ignores_excess_headers()
        {
            AutoMockPlug autoPlug = MockPlug.Register(new XUri("http://auto/plug"));

            autoPlug.Expect().Verb("POST").Uri(new XUri("http://auto/plug/a"));
            AsyncUtil.Fork(() => Plug.New("http://auto/plug/a").WithHeader("Foo", "123").PostAsync(), new Result());
            Assert.IsTrue(autoPlug.WaitAndVerify(TimeSpan.FromSeconds(1)), autoPlug.VerificationFailure);
        }
示例#6
0
        public void Can_match_request_DreamMessages_for_expectation()
        {
            AutoMockPlug autoPlug = MockPlug.Register(new XUri("http://auto/plug"));

            autoPlug.Expect().Verb("POST").Uri(new XUri("http://auto/plug/a")).Request(DreamMessage.Ok(MimeType.TEXT_UTF8, "blah"));
            AsyncUtil.Fork(() => Plug.New("http://auto/plug/a").PostAsync(DreamMessage.Ok(MimeType.TEXT_UTF8, "blah")), new Result());
            Assert.IsTrue(autoPlug.WaitAndVerify(TimeSpan.FromSeconds(1)), autoPlug.VerificationFailure);
        }
示例#7
0
 /// <summary>
 /// Asynchronously read from a <see cref="Stream"/>
 /// </summary>
 /// <param name="stream">Source <see cref="Stream"/></param>
 /// <param name="buffer">Byte array to fill from the source</param>
 /// <param name="offset">Position in buffer to start writing to</param>
 /// <param name="count">Number of bytes to read from the <see cref="Stream"/></param>
 /// <param name="result">The <see cref="Result"/> instance to be returned by the call.</param>
 /// <returns>Synchronization handle for the number of bytes read.</returns>
 public static Result <int> Read(this Stream stream, byte[] buffer, int offset, int count, Result <int> result)
 {
     if (SysUtil.UseAsyncIO)
     {
         return(AsyncUtil.From(stream.BeginRead, stream.EndRead, buffer, offset, count, null, result));
     }
     return(AsyncUtil.Fork(() => SyncRead_Helper(stream, buffer, offset, count), result));
 }
示例#8
0
 /// <summary>
 /// Asynchronously write to a <see cref="Stream"/>.
 /// </summary>
 /// <param name="stream">Target <see cref="Stream"/>.</param>
 /// <param name="buffer">Byte array to write to the target.</param>
 /// <param name="offset">Position in buffer to start reading from.</param>
 /// <param name="count">Number of bytes to read from buffer.</param>
 /// <param name="result">The <see cref="Result"/> instance to be returned by the call.</param>
 /// <returns>Synchronization handle for the number of bytes read.</returns>
 public static Result Write(this Stream stream, byte[] buffer, int offset, int count, Result result)
 {
     if (SysUtil.UseAsyncIO)
     {
         return(AsyncUtil.From(stream.BeginWrite, stream.EndWrite, buffer, offset, count, null, result));
     }
     return(AsyncUtil.Fork(() => stream.Write(buffer, offset, count), result));
 }
示例#9
0
            public Yield Spawn(DreamContext context, DreamMessage request, Result <DreamMessage> response)
            {
                var guid = Guid.NewGuid();

                ContextVar = new ContextLifeSpan(guid);
                context.SetState(guid);
                context.SetState(ContextVar);
                ContextLifeSpan capturedInner = null;

                yield return(AsyncUtil.Fork(() =>
                {
                    var innerContextVar = DreamContext.Current.GetState <ContextLifeSpan>();
                    capturedInner = innerContextVar;
                    if (innerContextVar == ContextVar)
                    {
                        throw new Exception("spawned context instances were same");
                    }
                    if (innerContextVar.Guid != guid)
                    {
                        throw new Exception("spawned context guid is wrong");
                    }
                    if (innerContextVar.IsDisposed)
                    {
                        throw new Exception("subcall: context is disposed");
                    }
                }, new Result()));

                var contextVar = context.GetState <ContextLifeSpan>();

                if (contextVar == null)
                {
                    throw new Exception("context instance is gone");
                }
                if (capturedInner == contextVar)
                {
                    throw new Exception("outer instance was changed to inner");
                }
                if (!capturedInner.IsDisposed)
                {
                    throw new Exception("inner instance wasn't disposed after closure completion");
                }
                if (contextVar.Guid != guid)
                {
                    throw new Exception("context guid is wrong");
                }
                if (contextVar != ContextVar)
                {
                    throw new Exception("context instance changed");
                }
                if (contextVar.IsDisposed)
                {
                    throw new Exception("context is disposed");
                }
                response.Return(DreamMessage.Ok());
                yield break;
            }
示例#10
0
        public void Catches_missing_headers()
        {
            AutoMockPlug autoPlug = MockPlug.Register(new XUri("http://auto/plug"));

            autoPlug.Expect().Verb("GET").Uri(new XUri("http://auto/plug/a"))
            .RequestHeader("Foo", "123")
            .RequestHeader("Bar", "required");
            AsyncUtil.Fork(() => Plug.New("http://auto/plug/a").WithHeader("Foo", "123").GetAsync(), new Result());
            Assert.IsFalse(autoPlug.WaitAndVerify(TimeSpan.FromSeconds(1)), autoPlug.VerificationFailure);
            Assert.AreEqual("Expectations were unmet:\r\nExpectation #1: Expected header 'Bar', got none\r\n", autoPlug.VerificationFailure);
        }
示例#11
0
        public void Autoplug_without_expectations_should_still_fail_on_excess()
        {
            AutoMockPlug autoPlug = MockPlug.Register(new XUri("http://auto/plug"));

            AsyncUtil.Fork(() => {
                Plug.New("http://auto/plug/b").PutAsync(new XDoc("foo"));
                Plug.New("http://auto/plug/a").PostAsync();
            }, new Result());
            Assert.IsFalse(autoPlug.WaitAndVerify(TimeSpan.FromSeconds(1)), autoPlug.VerificationFailure);
            Assert.AreEqual(2, autoPlug.ExcessInterceptions.Length);
        }
示例#12
0
        public void Catches_mismatched_request_headers()
        {
            AutoMockPlug autoPlug = MockPlug.Register(new XUri("http://auto/plug"));

            autoPlug.Expect().Verb("GET").Uri(new XUri("http://auto/plug/a"))
            .RequestHeader("Foo", "123")
            .RequestHeader("Bar", "right");
            AsyncUtil.Fork(() => Plug.New("http://auto/plug/a").WithHeader("Foo", "123").WithHeader("Bar", "wrong").Get(new Result <DreamMessage>()), new Result());
            Assert.IsFalse(autoPlug.WaitAndVerify(TimeSpan.FromSeconds(1)), autoPlug.VerificationFailure);
            Assert.AreEqual("Expectations were unmet:\r\nExpectation #1: Expected header 'Bar:\r\nExpected: right\r\nGot:      wrong\r\n", autoPlug.VerificationFailure);
        }
示例#13
0
        public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, object state)
        {
            var asyncResult = new MockAsyncResult {
                AsyncState = state,
                Buffer     = buffer,
                Count      = count,
                Offset     = offset
            };

            AsyncUtil.Fork(() => callback(asyncResult));
            return(asyncResult);
        }
示例#14
0
        public void Considers_missordered_expectations_as_unmet()
        {
            AutoMockPlug autoPlug = MockPlug.Register(new XUri("http://auto/plugx"));

            autoPlug.Expect("POST", new XUri("http://auto/plugx/a"));
            autoPlug.Expect("PUT", new XUri("http://auto/plugx/b"), new XDoc("foo"));
            AsyncUtil.Fork(() => {
                Plug.New("http://auto/plugx/b").Put(new XDoc("foo"));
                Plug.New("http://auto/plugx/a").Post();
            }, new Result());
            Assert.IsFalse(autoPlug.WaitAndVerify(TimeSpan.FromSeconds(1)), autoPlug.VerificationFailure);
            Assert.AreEqual(0, autoPlug.MetExpectationCount);
        }
示例#15
0
        public void ExclusiveFileAccess()
        {
            // create the test file
            using (StreamWriter writer = new StreamWriter(File.OpenWrite("test.test"))) {
                writer.Write("Hello World!");
                writer.Close();
            }

            // kick off the thread to do the second open
            ManualResetEvent first  = new ManualResetEvent(false);
            ManualResetEvent second = new ManualResetEvent(false);
            ManualResetEvent third  = new ManualResetEvent(false);
            ManualResetEvent fourth = new ManualResetEvent(false);

            AsyncUtil.Fork(delegate() {
                first.WaitOne();
                try {
                    using (Stream f = StreamUtil.FileOpenExclusive("test.test")) {
                        Assert.IsNull(f, "file open succeeded when it was expected to fail");
                    }
                } catch {
                    third.Set();
                    fourth.Set();
                    throw;
                }
                second.WaitOne();
                third.Set();
                try {
                    using (Stream f = StreamUtil.FileOpenExclusive("test.test")) {
                        Assert.IsNotNull(f, "file open failed when it was expected to succeed");
                    }
                } catch {
                    fourth.Set();
                    throw;
                }
                fourth.Set();
            }, null);

            // open the file first
            using (Stream g = StreamUtil.FileOpenExclusive("test.test")) {
                first.Set();
                Thread.Sleep(2000);
                second.Set();
                Thread.Sleep(500);
                third.WaitOne();
                g.Close();
            }
            fourth.WaitOne();
            File.Delete("test.test");
        }
示例#16
0
        public void Should_be_able_to_call_same_url_with_different_headers()
        {
            AutoMockPlug autoPlug = MockPlug.Register(new XUri("http://auto/plug"));

            autoPlug.Expect().Verb("GET").Uri(new XUri("http://auto/plug/a")).RequestHeader("Foo", "");
            autoPlug.Expect().Verb("GET").Uri(new XUri("http://auto/plug/a")).RequestHeader("Foo", "baz");
            Plug p = Plug.New("http://auto/plug/a");

            AsyncUtil.Fork(() => {
                p.WithHeader("Foo", "").GetAsync().Block();
                p.WithHeader("Foo", "baz").GetAsync().Block();
            }, new Result());
            Assert.IsTrue(autoPlug.WaitAndVerify(TimeSpan.FromSeconds(1)), autoPlug.VerificationFailure);
        }
示例#17
0
        //--- Methods ---

        /// <summary>
        /// Start listening for SQS messages with the provided settings.
        /// </summary>
        /// <param name="settings">Polling settings.</param>
        /// <returns>Object to dispose listener when no longer needed.</returns>
        public IDisposable Listen(SqsPollingClientSettings settings)
        {
            if (settings == null)
            {
                throw new ArgumentNullException("settings");
            }
            var listener = new Listener(this);

            lock (_listeners) {
                _listeners.Add(listener);
            }
            AsyncUtil.Fork(() => listener.LongPollSqs(settings));
            return(listener);
        }
示例#18
0
        public void Complains_about_unmet_expectations_after_timeout()
        {
            AutoMockPlug autoPlug = MockPlug.Register(new XUri("http://auto/plug"));

            autoPlug.Expect("POST", new XUri("http://auto/plug/a"));
            autoPlug.Expect("PUT", new XUri("http://auto/plug/b"), new XDoc("foo"));
            Assert.IsFalse(autoPlug.WaitAndVerify(TimeSpan.FromSeconds(1)), autoPlug.VerificationFailure);

            autoPlug.Reset();
            autoPlug.Expect("POST", new XUri("http://auto/plug/a"));
            autoPlug.Expect("PUT", new XUri("http://auto/plug/b"), new XDoc("foo"));
            AsyncUtil.Fork(() => Plug.New("http://auto/plug/a").Post(), new Result());
            Assert.IsFalse(autoPlug.WaitAndVerify(TimeSpan.FromSeconds(1)), autoPlug.VerificationFailure);
            Assert.AreEqual(1, autoPlug.MetExpectationCount);
        }
示例#19
0
        public void PostAsync_from_nested_async_workers()
        {
            AutoResetEvent resetEvent = new AutoResetEvent(false);

            MockPlug.Register(new XUri("http://foo/bar"), delegate(Plug p, string v, XUri u, DreamMessage r, Result <DreamMessage> r2) {
                resetEvent.Set();
                r2.Return(DreamMessage.Ok());
            });
            Plug.New("http://foo/bar").PostAsync();
            Assert.IsTrue(resetEvent.WaitOne(1000, false), "no async failed");
            AsyncUtil.Fork(() => AsyncUtil.Fork(() => Plug.New("http://foo/bar").PostAsync(), new Result()), new Result());
            Assert.IsTrue(resetEvent.WaitOne(1000, false), "async failed");
            AsyncUtil.Fork(() => AsyncUtil.Fork(() => Plug.New("http://foo/bar").PostAsync(), new Result()), new Result());
            Assert.IsTrue(resetEvent.WaitOne(1000, false), "nested async failed");
            AsyncUtil.Fork(() => AsyncUtil.Fork(() => AsyncUtil.Fork(() => Plug.New("http://foo/bar").PostAsync(), new Result()), new Result()), new Result());
            Assert.IsTrue(resetEvent.WaitOne(1000, false), "double async failed");
        }
示例#20
0
        public Result <Production> Produce(int messages)
        {
            var production = new Production();
            var final      = new Result <Production>();

            AsyncUtil.Fork(() => {
                try {
                    _log.DebugFormat("{0}: Producing {1} messages", production.Id, messages);
                    var responses = new List <Result <string> >();
                    var client    = new AwsSqsClient(_clientConfig);
                    for (var i = 0; i < messages; i++)
                    {
                        var result = new Result <string>();
                        responses.Add(result);
                        var msg = production.Id + ":" + messages;
                        client.Send(_queue, AwsSqsMessage.FromBody(msg), new Result <AwsSqsSendResponse>()).WhenDone(r => {
                            if (r.HasException)
                            {
                                result.Throw(r.Exception);
                                return;
                            }
                            result.Return(msg);
                        });
                    }
                    responses.Join(new Result()).WhenDone(r => {
                        if (r.HasException)
                        {
                            final.Throw(r.Exception);
                            return;
                        }
                        production.Stopwatch.Stop();
                        production.Sent.AddRange(responses.Select(x => x.Value));
                        _log.DebugFormat("{0}: Sent {1} messages in {2:0.00}s @ {3:0.00}msg/sec",
                                         production.Id,
                                         production.Sent.Count,
                                         production.Stopwatch.Elapsed.TotalSeconds,
                                         production.Sent.Count / production.Stopwatch.Elapsed.TotalSeconds
                                         );
                        final.Return(production);
                    });
                } catch (Exception e) {
                    final.Throw(e);
                }
            });
            return(final);
        }
示例#21
0
        public void Collects_excess_expectations()
        {
            AutoMockPlug autoPlug = MockPlug.Register(new XUri("http://auto/plug"));

            autoPlug.Expect("POST");
            AsyncUtil.Fork(() => {
                Plug.New("http://auto/plug/a").PostAsync().Block();
                Plug.New("http://auto/plug/b").PostAsync().Block();
                Plug.New("http://auto/plug/c").PostAsync().Block();
                Plug.New("http://auto/plug/d").PostAsync().Block();
            }, new Result());
            Assert.IsFalse(autoPlug.WaitAndVerify(TimeSpan.FromSeconds(15)), autoPlug.VerificationFailure);
            Assert.IsTrue(autoPlug.HasInterceptsInExcessOfExpectations);
            Assert.AreEqual(3, autoPlug.ExcessInterceptions.Length);
            Assert.AreEqual("http://auto/plug/b", autoPlug.ExcessInterceptions[0].Uri.ToString());
            Assert.AreEqual("http://auto/plug/c", autoPlug.ExcessInterceptions[1].Uri.ToString());
            Assert.AreEqual("http://auto/plug/d", autoPlug.ExcessInterceptions[2].Uri.ToString());
        }
示例#22
0
        public void PipeTest3()
        {
            Stream writer;
            Stream reader;

            StreamUtil.CreatePipe(1, out writer, out reader);
            byte[] write = new byte[] { 1, 2, 3, 4 };
            AsyncUtil.Fork(delegate() {
                writer.Write(write, 0, write.Length);
                writer.Close();
            }, null);
            byte[] read  = new byte[10];
            int    count = reader.Read(read, 0, read.Length);

            reader.Close();
            Assert.AreEqual(write.Length, count);
            Assert.AreEqual(write, ArrayUtil.SubArray(read, 0, count));
        }
示例#23
0
        public void Async_Result_WhenDone_does_not_get_executed_task_state()
        {
            var state      = new TaskLifeSpanState("baz");
            var allgood    = false;
            var resetEvent = new ManualResetEvent(false);

            AsyncUtil.Fork(() => {
                _log.Debug("setting inner state");
                TaskEnv.Current.SetState("foo", state);
            }, new Result()).WhenDone(r => {
                _log.Debug("executing whendone");
                allgood = !r.HasException && state != TaskEnv.Current.GetState <TaskLifeSpanState>("foo");
                resetEvent.Set();
            });
            _log.Debug("waiting for fork");
            resetEvent.WaitOne();
            _log.Debug("done");
            Assert.IsTrue(allgood);
        }
示例#24
0
        public void Waits_until_expectations_are_met_after_each_reset()
        {
            AutoMockPlug autoPlug = MockPlug.Register(new XUri("http://auto/plug"));

            autoPlug.Expect("POST", new XUri("http://auto/plug/a"));
            autoPlug.Expect("PUT", new XUri("http://auto/plug/b"), new XDoc("foo"));
            AsyncUtil.Fork(() => {
                Plug.New("http://auto/plug/a").Post();
                Plug.New("http://auto/plug/b").Put(new XDoc("foo"));
            }, new Result());
            Assert.IsTrue(autoPlug.WaitAndVerify(TimeSpan.FromSeconds(2)), autoPlug.VerificationFailure);
            autoPlug.Reset();
            autoPlug.Expect("GET", new XUri("http://auto/plug/c"));
            autoPlug.Expect("GET", new XUri("http://auto/plug/d"));
            AsyncUtil.Fork(() => {
                Plug.New("http://auto/plug/c").Get();
                Plug.New("http://auto/plug/d").Get();
            }, new Result());
            Assert.IsTrue(autoPlug.WaitAndVerify(TimeSpan.FromSeconds(2)), autoPlug.VerificationFailure);
        }
示例#25
0
        public void Copied_state_on_another_thread_is_independent_of_original()
        {
            var state = new State();

            TaskEnv.Current.SetState(state);
            var resetEvent = new AutoResetEvent(true);
            var result     = AsyncUtil.Fork(() => {
                resetEvent.WaitOne();
                TaskEnv.Current.SetState(new State());
                resetEvent.WaitOne();
            }, new Result());

            Assert.AreEqual(state, TaskEnv.Current.GetState <State>());
            resetEvent.Set();
            Thread.Sleep(100);
            Assert.AreEqual(state, TaskEnv.Current.GetState <State>());
            resetEvent.Set();
            result.Wait();
            Assert.AreEqual(state, TaskEnv.Current.GetState <State>());
        }
示例#26
0
        //--- Methods ---
        protected override Yield Start(XDoc config, Result result)
        {
            yield return(Coroutine.Invoke(base.Start, config, new Result()));

            // are we a private storage service?
            _private = config["sid"].Contents == "sid://mindtouch.com/2007/07/dream/storage.private";
            _log.DebugFormat("storage is {0}", _private ? "private" : "public");

            // is the root blocked from access?
            _privateRoot = config["private-root"].AsBool.GetValueOrDefault();
            _log.DebugFormat("storage root is {0}accessible", _privateRoot ? "not " : "");
            _expirationEntries = new ExpiringHashSet <string>(TimerFactory);
            _expirationEntries.EntryExpired += OnDelete;

            // check if folder exists
            _path = Environment.ExpandEnvironmentVariables(config["folder"].Contents);
            _log.DebugFormat("storage path: {0}", _path);
            if (!Path.IsPathRooted(_path))
            {
                throw new ArgumentException(string.Format("storage path must be absolute: {0}", _path));
            }

            // make sure path ends with a '\' as it makes processing simpler later on
            if ((_path.Length != 0) && ((_path[_path.Length - 1] != '/') || (_path[_path.Length - 1] != '\\')))
            {
                _path += Path.DirectorySeparatorChar;
            }

            if (!_private && !Directory.Exists(_path))
            {
                throw new ArgumentException(string.Format("storage path does not exist: {0}", _path));
            }

            // Fire off meta data scanning
            AsyncUtil.Fork(ScanMetaData);
            result.Return();
        }
示例#27
0
        public void LIVE_STRESS_TEST_multiple_producers_multiple_queues_one_consumer_per_queue()
        {
            var messagesPerProducer = 100;
            var producerCount       = 1;
            var client = CreateLiveClient();
            var queues = new List <string>();

            foreach (var x in new[] { "a", "b", "c", "d" })
            {
                var queue = "test-" + x + "-" + StringUtil.CreateAlphaNumericKey(4);
                client.CreateQueue(queue, new Result <AwsSqsResponse>()).Wait();
                queues.Add(queue);
            }
            try {
                var producers = new List <Result <List <string> > >();
                for (var i = 0; i < producerCount; i++)
                {
                    var producer = i;
                    producers.Add(AsyncUtil.Fork(() => {
                        _log.DebugFormat("producer {0} started", producer);
                        var c    = CreateLiveClient();
                        var msgs = new List <string>();
                        for (var j = 0; j < messagesPerProducer; j++)
                        {
                            var msg = StringUtil.CreateAlphaNumericKey(1024);
                            foreach (var queue in queues)
                            {
                                c.Send(queue, AwsSqsMessage.FromBody(msg), new Result <AwsSqsSendResponse>()).Wait();
                            }
                            msgs.Add(msg);
                            if (msgs.Count % 10 == 0)
                            {
                                _log.DebugFormat("producer {0} sent {1}/{2} msgs", producer, msgs.Count, messagesPerProducer);
                            }
                        }
                        _log.DebugFormat("producer {0} finished", producer);
                        return(msgs);
                    }, new Result <List <string> >()));
                }
                var consumers = queues.ToDictionary(queue => queue, queue => AsyncUtil.Fork(() => {
                    _log.DebugFormat("consumer {0} started", queue);
                    var c          = CreateLiveClient();
                    var msgs       = new List <string>();
                    var expected   = messagesPerProducer * producerCount;
                    var lastReport = 0;
                    while (msgs.Count < expected)
                    {
                        var received = c.ReceiveMax(queue, new Result <IEnumerable <AwsSqsMessage> >()).Wait();
                        var count    = 0;
                        foreach (var msg in received)
                        {
                            count++;
                            msgs.Add(msg.Body);
                            c.Delete(msg, new Result <AwsSqsResponse>()).Wait();
                        }
                        if (count > 0 && msgs.Count > lastReport + 10)
                        {
                            _log.DebugFormat("consumer '{0}' received: {1}/{2}", queue, msgs.Count, expected);
                            lastReport = msgs.Count;
                        }
                    }
                    return(msgs);
                }, new Result <List <string> >()));
                producers.Join(new Result()).Wait();
                consumers.Values.Join(new Result()).Wait();
                var allMessages = producers.SelectMany(x => x.Value).OrderBy(x => x).ToArray();
                foreach (var consumed in consumers)
                {
                    var queue    = consumed.Key;
                    var messages = consumed.Value.Value.OrderBy(x => x).ToArray();
                    Assert.AreEqual(allMessages, messages, string.Format("message list for queue '{0}' is wrong", queue));
                }
            } finally {
                foreach (var queue in queues)
                {
                    _log.DebugFormat("cleaning up queue '{0}'", queue);
                    client.DeleteQueue(queue, new Result <AwsSqsResponse>()).Wait();
                }
            }
        }
示例#28
0
        public IEnumerator <IYield> Invoke(Plug plug, string verb, XUri uri, DreamMessage request, Result <DreamMessage> response)
        {
            var match = GetBestMatch(uri);

            yield return(AsyncUtil.Fork(() => match.Invoke(plug, verb, uri, MemorizeAndClone(request), response), new Result(TimeSpan.MaxValue)));
        }