コード例 #1
0
 public async Task Send(T context, IPipe <T> next)
 {
     using (IRepeatContext repeatContext = _repeatPolicy.GetRepeatContext())
     {
         await Attempt(repeatContext, context, next);
     }
 }
コード例 #2
0
        public static async Task UntilCancelled(CancellationToken cancellationToken, Func <Task> callback)
        {
            if (cancellationToken.IsCancellationRequested)
            {
                return;
            }

            await Task.Yield();

            IRepeatPolicy repeatPolicy = UntilCancelled(cancellationToken);

            using (IRepeatContext repeatContext = repeatPolicy.GetRepeatContext())
            {
                TimeSpan delay = TimeSpan.Zero;
                do
                {
                    if (cancellationToken.IsCancellationRequested)
                    {
                        break;
                    }

                    if (delay > TimeSpan.Zero)
                    {
                        await Task.Delay(delay, repeatContext.CancellationToken).ConfigureAwait(false);
                    }

                    if (cancellationToken.IsCancellationRequested)
                    {
                        break;
                    }

                    await callback().ConfigureAwait(false);
                }while (repeatContext.CanRepeat(out delay));
            }
        }
コード例 #3
0
        /// <summary>
        /// Clear the current context at the end of a batch - should only be used by
        /// IRepeatOperations implementations.
        /// </summary>
        /// <returns> the old value if there was one.</returns>
        public static IRepeatContext Clear()
        {
            IRepeatContext context = GetContext();

            ContextHolder.Value = null;
            return(context);
        }
コード例 #4
0
        /// <summary>
        /// Method for registering a context - should only be used by
        /// IRepeatOperations implementations to ensure that
        /// #GetContext() always returns the correct value.
        /// </summary>
        /// <param name="context"> a new context at the start of a batch.</param>
        /// <returns>the old value if there was one.</returns>
        public static IRepeatContext Register(IRepeatContext context)
        {
            IRepeatContext oldSession = GetContext();

            ContextHolder.Value = context;
            return(oldSession);
        }
コード例 #5
0
        /// <summary>
        ///  Increments the context so the counter is up to date. Do nothing else.
        /// </summary>
        /// <param name="context"></param>
        public void Update(IRepeatContext context)
        {
            var support = context as RepeatContextSupport;
            if (support != null) {
			    support.Increment();
		    }
        }
コード例 #6
0
        /// <summary>
        /// Handling exceptions.
        /// </summary>
        /// <param name="exception"></param>
        /// <param name="context"></param>
        /// <param name="deferred"></param>
        private void DoHandle(System.Exception exception, IRepeatContext context, ICollection <System.Exception> deferred)
        {
            // An exception alone is not sufficient grounds for not continuing
            System.Exception unwrappedException = UnwrapIfRethrown(exception);
            try
            {
                for (int i = _listeners.Length; i-- > 0;)
                {
                    IRepeatListener interceptor = _listeners[i];
                    // This is not an error - only log at debug level.
                    Logger.Debug(unwrappedException, "Exception intercepted ({0} of {1})", (i + 1), _listeners.Length);
                    interceptor.OnError(context, unwrappedException);
                }

                Logger.Debug("Handling exception: {0}, caused by: {1} : {2}",
                             exception.GetType().Name,
                             unwrappedException.GetType().Name,
                             unwrappedException.Message
                             );

                _exceptionHandler.HandleException(context, unwrappedException);
            }
            catch (System.Exception handled)
            {
                deferred.Add(handled);
            }
        }
コード例 #7
0
 /// <summary>
 /// If exit status is not continuable returns <c>true</c>, otherwise
 /// delegates to  #IsComplete(IRepeatContext).
 /// </summary>
 /// <param name="context"></param>
 /// <param name="result"></param>
 /// <returns></returns>
 public virtual bool IsComplete(IRepeatContext context, RepeatStatus result)
 {
     if (result != null && !result.IsContinuable())
     {
         return(true);
     }
     return(IsComplete(context));
 }
コード例 #8
0
 /// <summary>
 /// If exit status is not continuable returns <code>true</code>, otherwise
 /// delegates to  #IsComplete(IRepeatContext).
 /// </summary>
 /// <param name="context"></param>
 /// <param name="result"></param>
 /// <returns></returns>
 public virtual bool IsComplete(IRepeatContext context, RepeatStatus result)
 {
     if (result != null && !result.IsContinuable())
     {
         return true;
     }
     return IsComplete(context);
 }
コード例 #9
0
 /// <summary>
 ///  Get the next completed result, possibly executing several callbacks until
 /// one finally finishes. Normally a subclass would have to override both
 /// this method and <see cref="CreateInternalState"/> because the
 /// implementation of this method would rely on the details of the internal
 /// state.
 /// </summary>
 /// <param name="context"></param>
 /// <param name="callback"></param>
 /// <param name="state"></param>
 /// <returns></returns>
 /// <exception cref="Exception">&nbsp;</exception>
 protected virtual RepeatStatus GetNextResult(IRepeatContext context, RepeatCallback callback, IRepeatInternalState state)
 {
     Update(context);
     if (Logger.IsDebugEnabled)
     {
         Logger.Debug("Repeat operation about to start at count={0}", context.GetStartedCount());
     }
     return(callback(context)); //"DoInInteration"
 }
コード例 #10
0
        /// <summary>
        /// Convenience method to set the current repeat operation to complete if it exists.
        /// </summary>
        public static void SetCompleteOnly()
        {
            IRepeatContext context = GetContext();

            if (context != null)
            {
                context.SetCompleteOnly();
            }
        }
コード例 #11
0
        /// <summary>
        ///  Increments the context so the counter is up to date. Do nothing else.
        /// </summary>
        /// <param name="context"></param>
        public void Update(IRepeatContext context)
        {
            var support = context as RepeatContextSupport;

            if (support != null)
            {
                support.Increment();
            }
        }
コード例 #12
0
        /// <summary>
        /// Set current session and all ancestors (via parent) to complete.,
        /// </summary>
        public static void SetAncestorsCompleteOnly()
        {
            IRepeatContext context = GetContext();

            while (context != null)
            {
                context.SetCompleteOnly();
                context = context.Parent;
            }
        }
コード例 #13
0
        /// <summary>
        /// Delegates to the Completion policy.
        /// </summary>
        /// <param name="context"></param>
        /// <param name="result"></param>
        /// <returns></returns>
        protected bool IsComplete(IRepeatContext context, RepeatStatus result)
        {
            bool complete = _completionPolicy.IsComplete(context, result);

            if (complete && Logger.IsDebugEnabled)
            {
                Logger.Debug("Repeat is complete according to policy and result value.");
            }
            return(complete);
        }
コード例 #14
0
        /// <summary>
        /// Delegates to the Completion policy.
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        protected bool IsComplete(IRepeatContext context)
        {
            bool complete = _completionPolicy.IsComplete(context);

            if (complete && Logger.IsDebugEnabled)
            {
                Logger.Debug("Repeat is complete according to policy alone not including result.");
            }
            return(complete);
        }
コード例 #15
0
        /// <summary>
        /// Delegates the start to the Completion policy.
        /// </summary>
        /// <returns></returns>
        protected IRepeatContext Start()
        {
            IRepeatContext parent  = RepeatSynchronizationManager.GetContext();
            IRepeatContext context = _completionPolicy.Start(parent);

            RepeatSynchronizationManager.Register(context);
            if (Logger.IsDebugEnabled)
            {
                Logger.Debug("Starting repeat context.");
            }
            return(context);
        }
コード例 #16
0
 /// <summary>
 ///  Convenience method to execute after interceptors on a callback result.
 /// </summary>
 /// <param name="context"></param>
 /// <param name="value"></param>
 protected void ExecuteAfterInterceptors(IRepeatContext context, RepeatStatus value)
 {
     // Don't re-throw exceptions here: let the exception handler deal with
     // that...
     if (value != null && value.IsContinuable())
     {
         for (int i = _listeners.Length; i-- > 0;)
         {
             IRepeatListener interceptor = _listeners[i];
             interceptor.After(context, value);
         }
     }
 }
コード例 #17
0
        static async Task Attempt(IRepeatContext repeatContext, T context, IPipe <T> next)
        {
            TimeSpan delay = TimeSpan.Zero;

            do
            {
                if (delay > TimeSpan.Zero)
                {
                    await Task.Delay(delay, repeatContext.CancellationToken);
                }

                await next.Send(context);
            }while (repeatContext.CanRepeat(out delay));
        }
コード例 #18
0
        /// <summary>
        /// Check that given context is marked as completed.
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        private bool IsMarkedComplete(IRepeatContext context)
        {
            bool complete = context.IsCompleteOnly();

            if (context.Parent != null)
            {
                complete = complete || IsMarkedComplete(context.Parent);
            }
            if (complete && Logger.IsDebugEnabled)
            {
                Logger.Debug("Repeat is complete according to context alone.");
            }
            return(complete);
        }
コード例 #19
0
ファイル: Repeat.cs プロジェクト: modulexcite/MassTransit
        public static async Task UntilCancelled(CancellationToken cancellationToken, Func <Task> callback)
        {
            IRepeatPolicy repeatPolicy = UntilCancelled(cancellationToken);

            using (IRepeatContext repeatContext = repeatPolicy.GetRepeatContext())
            {
                TimeSpan delay = TimeSpan.Zero;
                do
                {
                    if (delay > TimeSpan.Zero)
                    {
                        await Task.Delay(delay, repeatContext.CancellationToken);
                    }

                    await callback();
                }while (repeatContext.CanRepeat(out delay));
            }
        }
コード例 #20
0
        /// <summary>
        /// Execute the batch callback until the completion policy decides that we
        /// are finished. Wait for the whole batch to finish before returning even if
        /// the task executor is asynchronous.
        /// </summary>
        /// <param name="callback"></param>
        /// <returns></returns>
        public RepeatStatus Iterate(RepeatCallback callback)
        {
            IRepeatContext outer = RepeatSynchronizationManager.GetContext();
            RepeatStatus   result;

            try
            {
                // This works with an asynchronous TaskExecutor: the
                // interceptors have to wait for the child processes.
                result = ExecuteInternal(callback);
            }
            finally
            {
                RepeatSynchronizationManager.Clear();
                if (outer != null)
                {
                    RepeatSynchronizationManager.Register(outer);
                }
            }
            return(result);
        }
コード例 #21
0
        /// <summary>
        /// Use the TaskExecutor to generate a result. The
        /// internal state in this case is a queue of unfinished result holders of
        /// IResultHolder. The holder with the return value should not be
        /// on the queue when this method exits. The queue is scoped in the calling
        /// method so there is no need to synchronize access.
        /// </summary>
        /// <param name="context"></param>
        /// <param name="callback"></param>
        /// <param name="state"></param>
        /// <returns></returns>
        protected override RepeatStatus GetNextResult(IRepeatContext context, RepeatCallback callback,
                                                      IRepeatInternalState state)
        {
            ExecutingRunnable            runnable;
            IResultQueue <IResultHolder> queue = ((ResultQueueInternalState)state).ResultQueue;

            do
            {
                // Wrap the callback in a runnable that will add its result to the
                // queue when it is ready.
                runnable = new ExecutingRunnable(callback, context, queue);

                // Tell the runnable that it can expect a result. This could have
                // been in-lined with the constructor, but it might block, so it's
                // better to do it here, since we have the option (it's a private
                // class).
                runnable.Expect();

                //Start the task possibly concurrently / in the future.
                _taskExecutor.Execute(new Task(delegate { runnable.Run(); }));

                // Allow termination policy to update its state. This must happen
                // immediately before or after the call to the task executor.
                Update(context);

                // Keep going until we get a result that is finished, or early
                // termination...
            }while (queue.IsEmpty() && !IsComplete(context));

            IResultHolder result = queue.Take();

            if (result.Error != null)
            {
                throw result.Error;
            }
            return(result.Result);
        }
コード例 #22
0
 /// <summary>
 /// True if the result is null, or a RepeatStatus indicating completion.
 /// </summary>
 /// <param name="context"></param>
 /// <param name="result"></param>
 /// <returns></returns>
 public override bool IsComplete(IRepeatContext context, RepeatStatus result)
 {
     return (result == null || !result.IsContinuable());
 }
コード例 #23
0
 /// <summary>
 ///  Resets the counter.
 /// </summary>
 /// <param name="context"></param>
 /// <returns></returns>
 public override IRepeatContext Start(IRepeatContext context)
 {
     return new SimpleTerminationContext(context);
 }
コード例 #24
0
 /// <summary>
 ///  Terminates if the chunk size has been reached, or the result is null.
 /// </summary>
 /// <param name="context"></param>
 /// <param name="result"></param>
 /// <returns></returns>
 public override bool IsComplete(IRepeatContext context, RepeatStatus result)
 {
     return base.IsComplete(context, result) ||
         ((SimpleTerminationContext)context).IsComplete(this);
 }
コード例 #25
0
 /// <summary>
 /// Delegates to the completion policy.
 /// </summary>
 /// <param name="context"></param>
 protected void Update(IRepeatContext context)
 {
     _completionPolicy.Update(context);
 }
コード例 #26
0
 /// <summary>
 /// Always true.
 /// </summary>
 /// <param name="context"></param>
 /// <returns></returns>
 public virtual bool IsComplete(IRepeatContext context)
 {
     return(true);
 }
コード例 #27
0
 /// <summary>
 /// Re-throws the exception.
 /// </summary>
 /// <param name="context"></param>
 /// <param name="exception"></param>
 public void HandleException(IRepeatContext context, System.Exception exception)
 {
     throw new System.Exception("Exception encountered", exception);
 }
コード例 #28
0
 /// <summary>
 ///  Constructor for RepeatContextSupport. The parent can be null, but
 /// should be set to the enclosing repeat context if there is one, e.g. if
 /// this context is an inner loop.
 /// </summary>
 /// <param name="parent"></param>
 public RepeatContextSupport(IRepeatContext parent)
 {
     _parent = parent;
 }
コード例 #29
0
 /// <summary>
 /// Delegates to the Completion policy.
 /// </summary>
 /// <param name="context"></param>
 /// <param name="result"></param>
 /// <returns></returns>
 protected bool IsComplete(IRepeatContext context, RepeatStatus result)
 {
     bool complete = _completionPolicy.IsComplete(context, result);
     if (complete && Logger.IsDebugEnabled)
     {
         Logger.Debug("Repeat is complete according to policy and result value.");
     }
     return complete;
 }
コード例 #30
0
 /// <summary>
 /// Delegates to the completion policy.
 /// </summary>
 /// <param name="context"></param>
 protected void Update(IRepeatContext context)
 {
     _completionPolicy.Update(context);
 }
コード例 #31
0
 /// <summary>
 /// Create an internal state object that is used to store data needed
 /// internally in the scope of an iteration. Used by subclasses to manage the
 /// queueing and retrieval of asynchronous results. The default just provides
 /// an accumulation of exceptions instances for processing at the end of the
 /// batch.
 /// </summary>
 /// <param name="context"></param>
 /// <returns></returns>
 protected virtual IRepeatInternalState CreateInternalState(IRepeatContext context)
 {
     return(new RepeatInternalStateSupport());
 }
コード例 #32
0
 /// <summary>
 /// Delegates to the Completion policy.
 /// </summary>
 /// <param name="context"></param>
 /// <returns></returns>
 protected bool IsComplete(IRepeatContext context)
 {
     bool complete = _completionPolicy.IsComplete(context);
     if (complete && Logger.IsDebugEnabled)
     {
         Logger.Debug("Repeat is complete according to policy alone not including result.");
     }
     return complete;
 }
コード例 #33
0
        /// <summary>
        /// Handling exceptions.
        /// </summary>
        /// <param name="exception"></param>
        /// <param name="context"></param>
        /// <param name="deferred"></param>
        private void DoHandle(System.Exception exception, IRepeatContext context, ICollection<System.Exception> deferred)
        {
            // An exception alone is not sufficient grounds for not continuing
            System.Exception unwrappedException = UnwrapIfRethrown(exception);
            try
            {
                for (int i = _listeners.Length; i-- > 0; )
                {
                    IRepeatListener interceptor = _listeners[i];
                    // This is not an error - only log at debug level.
                    Logger.Debug(unwrappedException, "Exception intercepted ({0} of {1})", (i + 1), _listeners.Length);
                    interceptor.OnError(context, unwrappedException);
                }

                Logger.Debug("Handling exception: {0}, caused by: {1} : {2}",
                    exception.GetType().Name,
                    unwrappedException.GetType().Name,
                     unwrappedException.Message
                    );

                _exceptionHandler.HandleException(context, unwrappedException);

            }
            catch (System.Exception handled)
            {
                deferred.Add(handled);
            }
        }
コード例 #34
0
 /// <summary>
 /// Create an internal state object that is used to store data needed
 /// internally in the scope of an iteration. Used by subclasses to manage the
 /// queueing and retrieval of asynchronous results. The default just provides
 /// an accumulation of exceptions instances for processing at the end of the
 /// batch.
 /// </summary>
 /// <param name="context"></param>
 /// <returns></returns>
 protected virtual IRepeatInternalState CreateInternalState(IRepeatContext context)
 {
     return new RepeatInternalStateSupport();
 }
コード例 #35
0
 /// <summary>
 /// Check that given context is marked as completed.
 /// </summary>
 /// <param name="context"></param>
 /// <returns></returns>
 private bool IsMarkedComplete(IRepeatContext context)
 {
     bool complete = context.IsCompleteOnly();
     if (context.Parent != null)
     {
         complete = complete || IsMarkedComplete(context.Parent);
     }
     if (complete && Logger.IsDebugEnabled)
     {
         Logger.Debug("Repeat is complete according to context alone.");
     }
     return complete;
 }
コード例 #36
0
 /// <summary>
 ///  Get the next completed result, possibly executing several callbacks until
 /// one finally finishes. Normally a subclass would have to override both
 /// this method and <see cref="CreateInternalState"/> because the
 /// implementation of this method would rely on the details of the internal
 /// state.
 /// </summary>
 /// <param name="context"></param>
 /// <param name="callback"></param>
 /// <param name="state"></param>
 /// <returns></returns>
 /// <exception cref="Exception">&nbsp;</exception>
 protected virtual RepeatStatus GetNextResult(IRepeatContext context, RepeatCallback callback, IRepeatInternalState state)
 {
     Update(context);
     if (Logger.IsDebugEnabled)
     {
         Logger.Debug("Repeat operation about to start at count={0}", context.GetStartedCount());
     }
     return callback(context); //"DoInInteration"
 }
コード例 #37
0
 /// <summary>
 /// Builds a new IRepeatContext and returns it.
 /// </summary>
 /// <param name="parent"></param>
 /// <returns></returns>
 public virtual IRepeatContext Start(IRepeatContext parent)
 {
     return new RepeatContextSupport(parent);
 }
コード例 #38
0
 /// <summary>
 /// Builds a new IRepeatContext and returns it.
 /// </summary>
 /// <param name="parent"></param>
 /// <returns></returns>
 public virtual IRepeatContext Start(IRepeatContext parent)
 {
     return(new RepeatContextSupport(parent));
 }
コード例 #39
0
 public ExecutingRunnable(RepeatCallback callback, IRepeatContext context, IResultQueue<IResultHolder> queue)
 {
     _callback = callback;
     Context = context;
     _queue = queue;
 }
コード例 #40
0
 /// <summary>
 ///  Constructor for RepeatContextSupport. The parent can be null, but
 /// should be set to the enclosing repeat context if there is one, e.g. if
 /// this context is an inner loop.
 /// </summary>
 /// <param name="parent"></param>
 public RepeatContextSupport(IRepeatContext parent)
 {
     _parent = parent;
 }
コード例 #41
0
 /// <summary>
 ///  Terminates if the chunk size has been reached, or the result is null.
 /// </summary>
 /// <param name="context"></param>
 /// <param name="result"></param>
 /// <returns></returns>
 public override bool IsComplete(IRepeatContext context, RepeatStatus result)
 {
     return(base.IsComplete(context, result) ||
            ((SimpleTerminationContext)context).IsComplete(this));
 }
コード例 #42
0
 /// <summary>
 ///  Convenience method to execute after interceptors on a callback result.
 /// </summary>
 /// <param name="context"></param>
 /// <param name="value"></param>
 protected void ExecuteAfterInterceptors(IRepeatContext context, RepeatStatus value)
 {
     // Don't re-throw exceptions here: let the exception handler deal with
     // that...
     if (value != null && value.IsContinuable())
     {
         for (int i = _listeners.Length; i-- > 0; )
         {
             IRepeatListener interceptor = _listeners[i];
             interceptor.After(context, value);
         }
     }
 }
コード例 #43
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="callback"></param>
        /// <returns></returns>
        private RepeatStatus ExecuteInternal(RepeatCallback callback)
        {
            // Reset the termination policy if there is one...
            IRepeatContext context = Start();

            // Make sure if we are already marked complete before we start then no
            // processing takes place.
            bool running = !IsMarkedComplete(context);

            foreach (IRepeatListener interceptor in _listeners)
            {
                interceptor.Open(context);
                running = running && !IsMarkedComplete(context);
                if (!running)
                {
                    break;
                }
            }

            // Return value, default is to allow continued processing.
            RepeatStatus result = RepeatStatus.Continuable;

            IRepeatInternalState state = CreateInternalState(context);
            // This is the list of exceptions thrown by all active callbacks
            ICollection <System.Exception> exceptions = state.GetExceptions();
            // Keep a separate list of exceptions we handled that need to be
            // rethrown
            ICollection <System.Exception> deferred = new List <System.Exception>();

            try
            {
                while (running)
                {
                    #region WhileRunning

                    /*
                     * Run the before interceptors here, not in the task executor so
                     * that they all happen in the same thread - it's easier for
                     * tracking batch status, amongst other things.
                     */
                    foreach (IRepeatListener interceptor in _listeners)
                    {
                        interceptor.Before(context);
                        // Allow before interceptors to veto the batch by setting
                        // flag.
                        running = running && !IsMarkedComplete(context);
                    }

                    // Check that we are still running (should always be true) ...
                    if (running)
                    {
                        #region Running
                        try
                        {
                            result = GetNextResult(context, callback, state);
                            ExecuteAfterInterceptors(context, result);
                        }
                        catch (System.Exception exception)
                        {
                            DoHandle(exception, context, deferred);
                        }

                        // N.B. the order may be important here:
                        if (IsComplete(context, result) || IsMarkedComplete(context) || deferred.Any())
                        {
                            running = false;
                        }
                        #endregion
                    }
                    #endregion
                }

                result = result.And(WaitForResults(state));
                foreach (System.Exception exception in exceptions)
                {
                    DoHandle(exception, context, deferred);
                }

                // Explicitly drop any references to internal state...
                // useless ?
                state = null;
            }

            /*
             * No need for explicit catch here - if the business processing threw an
             * exception it was already handled by the helper methods. An exception
             * here is necessarily fatal.
             */
            finally
            {
                #region HandleFinally
                HandleFinally(deferred, _listeners, context);
                #endregion
            }
            return(result);
        }
コード例 #44
0
 /// <summary>
 /// Always true.
 /// </summary>
 /// <param name="context"></param>
 /// <returns></returns>
 public virtual bool IsComplete(IRepeatContext context)
 {
     return true;
 }
コード例 #45
0
 /// <summary>
 /// Handling the finally from ExecuteInternal.
 /// </summary>
 /// <param name="deferred"></param>
 /// <param name="listeners"></param>
 /// <param name="context"></param>
 private void HandleFinally(ICollection <System.Exception> deferred, IRepeatListener[] listeners, IRepeatContext context)
 {
     try
     {
         if (deferred.Any())
         {
             System.Exception exception = deferred.First();
             Logger.Debug("Handling fatal exception explicitly (rethrowing first of {0}): {1} : {2}",
                          deferred.Count,
                          exception.GetType().Name,
                          exception.Message
                          );
             Rethrow(exception);
         }
     }
     finally
     {
         try
         {
             foreach (IRepeatListener interceptor in _listeners)
             {
                 interceptor.Close(context);
             }
         }
         finally
         {
             context.Close();
         }
     }
 }
コード例 #46
0
        /// <summary>
        /// Use the TaskExecutor to generate a result. The
        /// internal state in this case is a queue of unfinished result holders of
        /// IResultHolder. The holder with the return value should not be
        /// on the queue when this method exits. The queue is scoped in the calling
        /// method so there is no need to synchronize access.
        /// </summary>
        /// <param name="context"></param>
        /// <param name="callback"></param>
        /// <param name="state"></param>
        /// <returns></returns>
        protected override RepeatStatus GetNextResult(IRepeatContext context, RepeatCallback callback,
            IRepeatInternalState state)
        {
            ExecutingRunnable runnable;
            IResultQueue<IResultHolder> queue = ((ResultQueueInternalState)state).ResultQueue;
            do
            {
                // Wrap the callback in a runnable that will add its result to the
                // queue when it is ready.                
                runnable = new ExecutingRunnable(callback, context, queue);

                // Tell the runnable that it can expect a result. This could have
                // been in-lined with the constructor, but it might block, so it's
                // better to do it here, since we have the option (it's a private
                // class).
                runnable.Expect();

                //Start the task possibly concurrently / in the future.
                _taskExecutor.Execute(new Task(delegate { runnable.Run(); }));

                // Allow termination policy to update its state. This must happen
                // immediately before or after the call to the task executor.
                Update(context);

                // Keep going until we get a result that is finished, or early
                // termination...                 
            }
            while (queue.IsEmpty() && !IsComplete(context));

            IResultHolder result = queue.Take();
            if (result.Error != null)
            {
                throw result.Error;
            }
            return result.Result;
        }
コード例 #47
0
 /// <summary>
 /// Re-throws the exception.
 /// </summary>
 /// <param name="context"></param>
 /// <param name="exception"></param>
 public void HandleException(IRepeatContext context, System.Exception exception)
 {
     throw new System.Exception("Exception encountered", exception);
 }
コード例 #48
0
 /// <summary>
 /// see RepeatTemplate#CreateInternalState .
 /// </summary>
 /// <param name="context"></param>
 /// <returns></returns>
 protected override IRepeatInternalState CreateInternalState(IRepeatContext context)
 {
     // Queue of pending results:
     return new ResultQueueInternalState(_throttleLimit);
 }
コード例 #49
0
 /// <summary>
 /// True if the result is null, or a RepeatStatus indicating completion.
 /// </summary>
 /// <param name="context"></param>
 /// <param name="result"></param>
 /// <returns></returns>
 public override bool IsComplete(IRepeatContext context, RepeatStatus result)
 {
     return(result == null || !result.IsContinuable());
 }
コード例 #50
0
 /// <summary>
 ///  Terminates if the chunk size has been reached.
 /// </summary>
 /// <param name="context"></param>
 /// <returns></returns>
 public override bool IsComplete(IRepeatContext context)
 {
     return ((SimpleTerminationContext)context).IsComplete(this);
 }
コード例 #51
0
 /// <summary>
 /// Always false.
 /// </summary>
 /// <param name="context"></param>
 /// <returns></returns>
 public override bool IsComplete(IRepeatContext context)
 {
     return(false);
 }
コード例 #52
0
 /// <summary>
 ///  Custom Constructor.
 /// </summary>
 /// <param name="context"></param>
 public SimpleTerminationContext(IRepeatContext context)
     : base(context)
 {
 }
コード例 #53
0
 /// <summary>
 /// Method for registering a context - should only be used by
 /// IRepeatOperations implementations to ensure that
 /// #GetContext() always returns the correct value.
 /// </summary>
 /// <param name="context"> a new context at the start of a batch.</param>
 /// <returns>the old value if there was one.</returns>
 public static IRepeatContext Register(IRepeatContext context)
 {
     IRepeatContext oldSession = GetContext();
     ContextHolder.Value = context;
     return oldSession;
 }
コード例 #54
0
 /// <summary>
 /// Always false.
 /// </summary>
 /// <param name="context"></param>
 /// <returns></returns>
 public override bool IsComplete(IRepeatContext context)
 {
     return false;
 }
コード例 #55
0
        /// <summary>
        /// Handling the finally from ExecuteInternal.
        /// </summary>
        /// <param name="deferred"></param>
        /// <param name="listeners"></param>
        /// <param name="context"></param>
        private void HandleFinally(ICollection<System.Exception> deferred,IRepeatListener[] listeners,IRepeatContext context)
        {
            try
            {
                if (deferred.Any())
                {
                    System.Exception exception = deferred.First();
                    Logger.Debug("Handling fatal exception explicitly (rethrowing first of {0}): {1} : {2}",
                        deferred.Count,
                        exception.GetType().Name,
                        exception.Message
                        );
                    Rethrow(exception);
                }
            }
            finally
            {
                try
                {
                    foreach (IRepeatListener interceptor in _listeners)
                    {
                        interceptor.Close(context);
                    }
                }
                finally
                {
                    context.Close();
                }

            }
        }