Esempio n. 1
0
        public void TestMarkTimeout()
        {
            var workItem = new CWorkItem <bool>();

            var m1 = workItem.MarkTimeout();
            var m2 = workItem.MarkTimeout();
            var m3 = workItem.MarkTimeout();
            var m4 = workItem.MarkTimeout();

            Assert.AreEqual(m1, true);

            Assert.AreNotEqual(m2, true);
            Assert.AreNotEqual(m3, true);
            Assert.AreNotEqual(m4, true);

            workItem = new CWorkItem <bool>();

            var taskCount = 10;
            var tasks     = new Task <bool> [taskCount];

            for (int i = 0; i < taskCount; i++)
            {
                tasks[i] = Task.Factory.StartNew <bool>(() => {
                    return(workItem.MarkTimeout());
                });
            }

            Task.WaitAll(tasks);

            Assert.AreEqual(1, tasks.Count(x => x.Result));
        }
        private Task <T> ExecuteWithThreadPool()
        {
            EventHandler <StatusChangeEventArgs> onStatusChange = null;
            TaskCompletionSource <T>             tcs            = new TaskCompletionSource <T>();

            try
            {
                if (!base.CircuitBreaker.AllowRequest())
                {
                    string message = "Circuit Breaker is open. Execution was short circuited.";
                    base.Log.Log(LogLevelEnum.Error, message, base.GetLogTagInfo().AddLogTagData("FXD303033"));
                    this.Status = CommandStatusEnum.ShortCircuited;
                    base.Metrics.MarkExecutionEvent(CommandExecutionEventEnum.ShortCircuited);
                    throw new HystrixException(FailureTypeEnum.ShortCircuited, base.GetType(), this.Key, message);
                }
                this.Status = CommandStatusEnum.Started;
                if (onStatusChange == null)
                {
                    onStatusChange = delegate(object o, StatusChangeEventArgs e) {
                        CWorkItem <T> item = o as CWorkItem <T>;
                        bool          flag = false;
                        try
                        {
                            if (item.IsCompleted || item.IsCanceled)
                            {
                                ((ThreadIsolationCommand <T>) this).Metrics.MarkTotalExecutionLatency((long)item.ExeuteMilliseconds);
                                ((ThreadIsolationCommand <T>) this).Metrics.MarkExecutionLatency((long)item.RealExecuteMilliseconds);
                            }
                            switch (e.Status)
                            {
                            case CTaskStatus.RanToCompletion:
                                ((ThreadIsolationCommand <T>) this).Status = CommandStatusEnum.Success;
                                ((ThreadIsolationCommand <T>) this).Metrics.MarkExecutionEvent(CommandExecutionEventEnum.Success);
                                ((ThreadIsolationCommand <T>) this).CircuitBreaker.MarkSuccess();
                                tcs.SetResult(item.Result);
                                goto Label_01C0;

                            case CTaskStatus.Running:
                                ((ThreadIsolationCommand <T>) this).Status = CommandStatusEnum.Started;
                                goto Label_01C0;

                            case CTaskStatus.Faulted:
                                ((ThreadIsolationCommand <T>) this).Status = CommandStatusEnum.Failed;
                                if (!item.Exception.IsBadRequestException())
                                {
                                    break;
                                }
                                ((ThreadIsolationCommand <T>) this).Metrics.MarkExecutionEvent(CommandExecutionEventEnum.BadRequest);
                                ((ThreadIsolationCommand <T>) this).Log.Log(LogLevelEnum.Error, "HystrixCommand request is bad.", item.Exception, ((ThreadIsolationCommand <T>) this).GetLogTagInfo().AddLogTagData("FXD303035"));
                                goto Label_0162;

                            case CTaskStatus.Canceled:
                                ((ThreadIsolationCommand <T>) this).Status = CommandStatusEnum.Timeout;
                                ((ThreadIsolationCommand <T>) this).Metrics.MarkExecutionEvent(CommandExecutionEventEnum.Timeout);
                                ((ThreadIsolationCommand <T>) this).Log.Log(LogLevelEnum.Warning, string.Format("timed out before executing run(), the wait time was {0} milliseconds; ", item.ExeuteMilliseconds), ((ThreadIsolationCommand <T>) this).GetLogTagInfo().AddLogTagData("FXD303034"));
                                flag = true;
                                goto Label_01C0;

                            default:
                                goto Label_01C0;
                            }
                            ((ThreadIsolationCommand <T>) this).Metrics.MarkExecutionEvent(CommandExecutionEventEnum.Failed);
                            ((ThreadIsolationCommand <T>) this).Log.Log(LogLevelEnum.Error, "HystrixCommand execution failed.", item.Exception, ((ThreadIsolationCommand <T>) this).GetLogTagInfo().AddLogTagData("FXD303036"));
Label_0162:
                            flag = true;
Label_01C0:
                            if (flag)
                            {
                                if (((ThreadIsolationCommand <T>) this).HasFallback)
                                {
                                    try
                                    {
                                        tcs.SetResult(((ThreadIsolationCommand <T>) this).ExecuteFallback());
                                        return;
                                    }
                                    catch (Exception exception)
                                    {
                                        throw exception;
                                    }
                                }
                                if (e.Status == CTaskStatus.Faulted)
                                {
                                    throw item.Exception;
                                }
                                if (e.Status == CTaskStatus.Canceled)
                                {
                                    throw new HystrixException(FailureTypeEnum.ExecutionTimeout, ((ThreadIsolationCommand <T>) this).GetType(), ((ThreadIsolationCommand <T>) this).Key, string.Format("timed out before executing run(), maxt waiting time was {0} milliseconds,the task waiting time was {1} milliseconds", ((ThreadIsolationCommand <T>) this).ConfigSet.CommandTimeoutInMilliseconds, item.ExeuteMilliseconds), item.Exception, new Exception("no fallback found"));
                                }
                            }
                        }
                        catch (Exception exception2)
                        {
                            ((ThreadIsolationCommand <T>) this).Metrics.MarkExecutionEvent(CommandExecutionEventEnum.ExceptionThrown);
                            tcs.TrySetException(exception2);
                        }
                    };
                }
                ((ThreadIsolationCommand <T>) this).QueueWorkItem <T>(new Func <T>(this.Execute), onStatusChange);
            }
            catch (Exception exception)
            {
                if ((exception is HystrixException) && (((HystrixException)exception).FailureType == FailureTypeEnum.ThreadIsolationRejected))
                {
                    base.Metrics.MarkExecutionEvent(CommandExecutionEventEnum.Rejected);
                    base.Log.Log(LogLevelEnum.Error, "HystrixCommand execution rejected.", exception, base.GetLogTagInfo().AddLogTagData("FXD303037"));
                    this.Status = CommandStatusEnum.Rejected;
                }
                if (this.HasFallback)
                {
                    tcs.Task.ContinueWith(delegate(Task <T> t) {
                        try
                        {
                            exception = t.Exception;
                        }
                        catch
                        {
                        }
                    });
                    return(this.GetFallBack());
                }
                this.Status = CommandStatusEnum.Failed;
                base.Metrics.MarkExecutionEvent(CommandExecutionEventEnum.ExceptionThrown);
                tcs.TrySetException(exception);
            }
            return(tcs.Task);
        }