예제 #1
0
        private Yield Upload_Helper(DreamContext context, DreamMessage request, Result <DreamMessage> response)
        {
            using (var stream = request.ToStream()) {
                var total  = 0;
                var buffer = new byte[1024 * 1024];
                while (total < request.ContentLength)
                {
                    Result <int> read;
                    yield return(read = stream.Read(buffer, 0, buffer.Length, new Result <int>()));

                    //int read = stream.Read(buffer, 0, buffer.Length);
                    if (read.Value == 0)
                    {
                        break;
                    }
                    total += read.Value;
                    //fake some latency
                    yield return(AsyncUtil.Sleep(TimeSpan.FromMilliseconds(1), new Result(TimeSpan.MaxValue)));
                }
                _log.DebugFormat("read {0}/{1} bytes", total, request.ContentLength);
                if (total != request.ContentLength)
                {
                    throw new DreamBadRequestException(string.Format("was supposed to read {0} bytes, only read {1}", request.ContentLength, total));
                }
            }
            response.Return(DreamMessage.Ok());
        }
예제 #2
0
        /// <summary>
        /// Shutdown the ElasticThreadPool instance.  This method blocks until all pending items have finished processing.
        /// </summary>
        public void Dispose()
        {
            if (!_disposed)
            {
                _disposed = true;
                _log.DebugFormat("Dispose @{0}", this);

                // TODO (steveb): make dispose more reliable
                // 1) we can't wait indefinitively!
                // 2) we should progressively sleep longer and longer to avoid unnecessary overhead
                // 3) this pattern feels useful enough to be captured into a helper method

                // wait until all threads have been decommissioned
                while (ThreadCount > 0)
                {
                    AsyncUtil.Sleep(100.Milliseconds());
                }

                // discard all reserved threads
                KeyValuePair <DispatchThread, Result <DispatchWorkItem> > reserved;
                while (_reservedThreads.TryPop(out reserved))
                {
                    DispatchThreadScheduler.ReleaseThread(reserved.Key, reserved.Value);
                }
                DispatchThreadScheduler.UnregisterHost(this);
            }
        }
예제 #3
0
            internal void LongPollSqs(SqsPollingClientSettings settings)
            {
                var failCounter = 0;

                while (true)
                {
                    IEnumerable <SqsMessage> messages;
                    try {
                        messages    = _container._client.ReceiveMessages(settings.QueueName, settings.LongPollInterval, settings.MaxNumberOfMessages);
                        failCounter = 0;
                    } catch (Exception e) {
                        LogError(e, string.Format("ReceiveMessages (fail count: {0:#,##0})", ++failCounter));
                        AsyncUtil.Sleep(settings.WaitTimeOnError);
                        continue;
                    }
                    if (_isDisposed)
                    {
                        break;
                    }
                    if (messages.None())
                    {
                        continue;
                    }
                    try {
                        settings.Callback(messages);
                    } catch (Exception e) {
                        LogError(e, "callback failed");
                    }
                }
            }
예제 #4
0
        private static Yield Ret_Yield_Throw(int p, Result <int> result)
        {
            yield return(AsyncUtil.Sleep(TimeSpan.FromMilliseconds(10), new Result(TimeSpan.MaxValue)));

            result.Return(p);
            throw new IntentionalException();
        }
예제 #5
0
        private void Receive()
        {
            if (_stopped)
            {
                return;
            }
            var t = Stopwatch.StartNew();

            _client.ReceiveMax(_queue, 10.Minutes(), new Result <IEnumerable <AwsSqsMessage> >()).WhenDone(r => {
                if (r.HasException)
                {
                    Exception = r.Exception;
                    return;
                }
                if (_stopped)
                {
                    return;
                }
                var received = new List <AwsSqsMessage>(r.Value);
                if (!received.Any())
                {
                    _log.DebugFormat("{0}: no messages in queue, sleeping before retry", Id);
                    AsyncUtil.Sleep(1.Seconds(), new Result(TimeSpan.MaxValue)).WhenDone(r2 => Receive());
                    return;
                }
                _log.DebugFormat("{0}: received {1} messages", Id, received.Count);
                Delete(received, 0, t);
            });
        }
예제 #6
0
        /// <summary>
        /// Repeatedly test a <b>condition</b> until the call times out or the condition indicates success.
        /// </summary>
        /// <param name="condition">Func to check whether wait condition has been met.</param>
        /// <param name="timeout">The maximum time to keep testing the condition.</param>
        /// <returns></returns>
        public static bool For(Func <bool> condition, TimeSpan timeout)
        {
            var timer = Stopwatch.StartNew();

            while (timeout > timer.Elapsed)
            {
                if (condition())
                {
                    return(true);
                }
                AsyncUtil.Sleep(50.Milliseconds());
            }
            return(false);
        }
예제 #7
0
 /// <summary>
 /// Try to open a file for exclusive read/write access
 /// </summary>
 /// <param name="filename">Path to file</param>
 /// <returns>A <see cref="Stream"/> for the opened file, or <see langword="null"/> on failure to open the file.</returns>
 public static Stream FileOpenExclusive(string filename)
 {
     for (int attempts = 0; attempts < 10; ++attempts)
     {
         try {
             return(File.Open(filename, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None));
         } catch (IOException e) {
             _log.TraceExceptionMethodCall(e, "FileOpenExclusive", filename, attempts);
         } catch (UnauthorizedAccessException e) {
             _log.TraceExceptionMethodCall(e, "FileOpenExclusive", filename, attempts);
         }
         AsyncUtil.Sleep(((attempts + 1) * Randomizer.Next(100)).Milliseconds());
     }
     return(null);
 }
예제 #8
0
        /// <summary>
        /// Repeatedly test a <b>condition</b> until the call times out or the condition indicates success.
        /// </summary>
        /// <typeparam name="T">The type of the result <see cref="WaitResult{T}"/> returned on success.</typeparam>
        /// <param name="condition">Func to check whether wait condition has been met.</param>
        /// <param name="timeout">The maximum time to keep testing the condition.</param>
        /// <returns>The value produced by successful execution of the condition.</returns>
        public static T For <T>(Func <WaitResult <T> > condition, TimeSpan timeout)
        {
            var timer = Stopwatch.StartNew();

            while (timeout > timer.Elapsed)
            {
                var waitresult = condition();
                if (waitresult.Success)
                {
                    return(waitresult.Value);
                }
                AsyncUtil.Sleep(50.Milliseconds());
            }
            throw new TimeoutException("gave up waiting for value");
        }
예제 #9
0
        private Yield BubbleCoroutine(int depth, Result result)
        {
            _log.DebugFormat("{0} levels remaining", depth);
            yield return(AsyncUtil.Sleep(TimeSpan.FromMilliseconds(10), new Result(TimeSpan.MaxValue)));

            if (depth > 0)
            {
                _log.Debug("invoking BubbleCoroutine again");
                yield return(Coroutine.Invoke(BubbleCoroutine, depth - 1, new Result()));

                result.Return();
                yield break;
            }
            _log.Debug("throwing");
            throw new BubbledException();
        }
예제 #10
0
        /// <summary>
        /// Receive zero or more messages from name queue.
        /// </summary>
        /// <param name="queueName">Queue name.</param>
        /// <param name="waitTimeSeconds">Max amount of time to wait until this method returns.</param>
        /// <param name="maxNumberOfMessages">Max number of messages to request.</param>
        /// <returns>Enumeration of received messages.</returns>
        public IEnumerable <SqsMessage> ReceiveMessages(SqsQueueName queueName, TimeSpan waitTimeSeconds, uint maxNumberOfMessages)
        {
            var start = GlobalClock.UtcNow;

            // keep checking for messages until the wait-timeout kicks in
            while (true)
            {
                var msgQueue = GetQueue(queueName);
                AssertQueueIsNotNull(queueName, msgQueue);
                QueueEntry[] entries;
                var          now = GlobalClock.UtcNow;
                lock (msgQueue) {
                    var visibilityTimeout = 30.Seconds();
                    entries = msgQueue
                              .Where(x => x.VisibleTime <= now)
                              .OrderBy(x => _random.Next())
                              .Take(10)
                              .ToArray();
                    foreach (var entry in entries)
                    {
                        entry.VisibleTime = now + visibilityTimeout;
                    }
                }
                if (entries.Any())
                {
                    return(entries.Select(e => new SqsMessage(e.Message.MessageId, e.Message.MessageReceipt, e.Message.Body)).ToArray());
                }
                if ((now - start) > waitTimeSeconds)
                {
                    return(Enumerable.Empty <SqsMessage>());
                }

                // no message found; go to sleep for 100ms and try again
                AsyncUtil.Sleep(100.Milliseconds());
            }
        }
예제 #11
0
        private static Yield Yield_Ret(int p, Result <int> result)
        {
            yield return(AsyncUtil.Sleep(TimeSpan.FromMilliseconds(10), new Result(TimeSpan.MaxValue)));

            result.Return(p);
        }
예제 #12
0
        private static Yield Yield_Throw(int p, Result <int> result)
        {
            yield return(AsyncUtil.Sleep(TimeSpan.FromMilliseconds(10)));

            throw new IntentionalException();
        }