Пример #1
0
        public async Task <Stream> Handler(Stream request, Context context, NextIOHandler next)
        {
            try {
                var response = await next(request, context).ConfigureAwait(false);

                Config.OnSuccess?.Invoke(context);
                return(response);
            }
            catch (Exception) {
                Config.OnFailure?.Invoke(context);
                if (Config.OnRetry != null)
                {
                    bool idempotent = context.Contains("idempotent") ? Config.Idempotent : (bool)context["idempotent"];
                    int  retry      = context.Contains("retry") ? Config.Retry :(int)context["retry"];
                    if (!context.Contains("retried"))
                    {
                        context["retried"] = 0;
                    }
                    if (idempotent && (int)context["retried"] < retry)
                    {
                        var interval = Config.OnRetry(context);
                        if (interval > TimeSpan.Zero)
                        {
#if NET40
                            await TaskEx.Delay(interval).ConfigureAwait(false);
#else
                            await Task.Delay(interval).ConfigureAwait(false);
#endif
                        }
                        return(await Handler(request, context, next).ConfigureAwait(false));
                    }
                }
                throw;
            }
        }
Пример #2
0
        public async Task <Stream> IOHandler(Stream request, Context context, NextIOHandler next)
        {
            if (failCount > Threshold)
            {
                var interval = DateTime.Now - lastFailTime;
                if (interval < RecoverTime)
                {
                    throw new BreakerException();
                }
                failCount = Threshold >> 1;
            }
            try {
                var response = await next(request, context).ConfigureAwait(false);

                if (failCount > 0)
                {
                    failCount = 0;
                }
                return(response);
            }
            catch (Exception) {
                Interlocked.Increment(ref failCount);
                lastFailTime = DateTime.Now;
                throw;
            }
        }
Пример #3
0
        public override Task <Stream> Handler(Stream request, Context context, NextIOHandler next)
        {
            int  n       = uris.Length;
            bool gotlock = false;

            try {
                spanlock.Enter(ref gotlock);
                while (true)
                {
                    index = (index + 1) % n;
                    if (index == 0)
                    {
                        currentWeight -= gcdWeight;
                        if (currentWeight <= 0)
                        {
                            currentWeight = maxWeight;
                        }
                        if (weights[index] >= currentWeight)
                        {
                            (context as ClientContext).Uri = uris[index];
                            break;
                        }
                    }
                }
            }
            finally {
                if (gotlock)
                {
                    spanlock.Exit();
                }
            }
            return(next(request, context));
        }
Пример #4
0
        public static async Task <Stream> Forking(Stream request, Context context, NextIOHandler next)
        {
            var deferred      = new TaskCompletionSource <Stream>();
            var clientContext = context as ClientContext;
            var uris          = clientContext.Client.Uris;
            var n             = uris.Count;
            var count         = n;

            for (int i = 0; i < n; ++i)
            {
                var forkingContext = clientContext.Clone() as ClientContext;
                forkingContext.Uri = uris[i];
                Task result = next(request, forkingContext).ContinueWith(task => {
                    if (task.Exception != null)
                    {
                        if (Interlocked.Decrement(ref count) == 0)
                        {
                            deferred.TrySetException(task.Exception);
                        }
                    }
                    else
                    {
                        deferred.TrySetResult(task.Result);
                    }
                }, TaskScheduler.Current);
            }
            return(await deferred.Task.ConfigureAwait(false));
        }
Пример #5
0
        public Task <Stream> IOHandler(Stream request, Context context, NextIOHandler next)
        {
            var clientContext = new ClientContext {
                Timeout = Timeout
            };

            clientContext.Init(client);
            return(client.Request(request, clientContext));
        }
Пример #6
0
        public Task <Stream> Handler(Stream request, Context context, NextIOHandler next)
        {
            var clientContext = context as ClientContext;
            var uris          = clientContext.Client.Uris;
            var n             = uris.Count;

            clientContext.Uri = uris[random.Value.Next(n)];
            return(next(request, context));
        }
Пример #7
0
        public async Task <Stream> Handler(Stream request, Context context, NextIOHandler next)
        {
            var clientContext      = context as ClientContext;
            var uris               = clientContext.Client.Uris;
            var n                  = uris.Count;
            var leastActiveIndexes = new List <int>(n);

            rwlock.EnterUpgradeableReadLock();
            if (actives.Length < n)
            {
                rwlock.EnterWriteLock();
                actives = new int[n];
                rwlock.ExitWriteLock();
            }
            rwlock.ExitUpgradeableReadLock();

            rwlock.EnterReadLock();
            var leastActive = (actives.Length > n) ? actives.Take(n).Min() : actives.Min();

            for (int i = 0; i < n; ++i)
            {
                if (actives[i] == leastActive)
                {
                    leastActiveIndexes.Add(i);
                }
            }
            rwlock.ExitReadLock();

            int index = leastActiveIndexes[0];
            var count = leastActiveIndexes.Count;

            if (count > 1)
            {
                index = leastActiveIndexes[random.Next(count)];
            }

            clientContext.Uri = uris[index];

            rwlock.EnterWriteLock();
            actives[index]++;
            rwlock.ExitWriteLock();
            try {
                var response = await next(request, context).ConfigureAwait(false);

                rwlock.EnterWriteLock();
                actives[index]--;
                rwlock.ExitWriteLock();
                return(response);
            }
            catch {
                rwlock.EnterWriteLock();
                actives[index]--;
                rwlock.ExitWriteLock();
                throw;
            }
        }
Пример #8
0
        public async Task <Stream> IOHandler(Stream request, Context context, NextIOHandler next)
        {
            if (!request.CanSeek)
            {
                request = await request.ToMemoryStream().ConfigureAwait(false);
            }
            await Acquire(request.Length).ConfigureAwait(false);

            return(await next(request, context).ConfigureAwait(false));
        }
        public async Task <Stream> Handler(Stream request, Context context, NextIOHandler next)
        {
            await Acquire().ConfigureAwait(false);

            try {
                return(await next(request, context).ConfigureAwait(false));
            }
            finally {
                Release();
            }
        }
Пример #10
0
        public override async Task <Stream> Handler(Stream request, Context context, NextIOHandler next)
        {
            int n     = uris.Length;
            var index = n - 1;

            rwlock.EnterReadLock();
            var totalWeight = effectiveWeights.Sum();

            if (totalWeight > 0)
            {
                var currentWeight = random.Value.Next(totalWeight);
                for (int i = 0; i < n; ++i)
                {
                    currentWeight -= effectiveWeights[i];
                    if (currentWeight < 0)
                    {
                        index = i;
                        break;
                    }
                }
            }
            else
            {
                index = random.Value.Next(n);
            }
            rwlock.ExitReadLock();
            (context as ClientContext).Uri = uris[index];
            try {
                var response = await next(request, context).ConfigureAwait(false);

                rwlock.EnterUpgradeableReadLock();
                if (effectiveWeights[index] < weights[index])
                {
                    rwlock.EnterWriteLock();
                    effectiveWeights[index]++;
                    rwlock.ExitWriteLock();
                }
                rwlock.ExitUpgradeableReadLock();
                return(response);
            }
            catch {
                rwlock.EnterUpgradeableReadLock();
                if (effectiveWeights[index] > 0)
                {
                    rwlock.EnterWriteLock();
                    effectiveWeights[index]--;
                    rwlock.ExitWriteLock();
                }
                rwlock.ExitUpgradeableReadLock();
                throw;
            }
        }
        public Task <Stream> Handler(Stream request, Context context, NextIOHandler next)
        {
            var clientContext = context as ClientContext;
            var uris          = clientContext.Client.Uris;
            var n             = uris.Count;

            if (n > 1)
            {
                if (Interlocked.Increment(ref index) >= n)
                {
                    index = 0;
                }
                clientContext.Uri = uris[index];
            }
            return(next(request, context));
        }
 public abstract Task <Stream> Handler(Stream request, Context context, NextIOHandler next);
Пример #13
0
        public override async Task <Stream> Handler(Stream request, Context context, NextIOHandler next)
        {
            int n = uris.Length;
            var leastActiveIndexes = new List <int>(n);

            rwlock.EnterReadLock();
            var leastActive = actives.Min();
            int totalWeight = 0;

            for (int i = 0; i < n; ++i)
            {
                if (actives[i] == leastActive)
                {
                    leastActiveIndexes.Add(i);
                    totalWeight += effectiveWeights[i];
                }
            }
            rwlock.ExitReadLock();

            int index = leastActiveIndexes[0];
            var count = leastActiveIndexes.Count;

            if (count > 1)
            {
                if (totalWeight > 0)
                {
                    var currentWeight = random.Value.Next(totalWeight);
                    rwlock.EnterReadLock();
                    for (int i = 0; i < count; ++i)
                    {
                        currentWeight -= effectiveWeights[leastActiveIndexes[i]];
                        if (currentWeight < 0)
                        {
                            index = leastActiveIndexes[i];
                            break;
                        }
                    }
                    rwlock.ExitReadLock();
                }
                else
                {
                    index = leastActiveIndexes[random.Value.Next(count)];
                }
            }

            (context as ClientContext).Uri = uris[index];

            rwlock.EnterWriteLock();
            actives[index]++;
            rwlock.ExitWriteLock();
            try {
                var response = await next(request, context).ConfigureAwait(false);

                rwlock.EnterWriteLock();
                actives[index]--;
                rwlock.ExitWriteLock();
                rwlock.EnterUpgradeableReadLock();
                if (effectiveWeights[index] < weights[index])
                {
                    rwlock.EnterWriteLock();
                    effectiveWeights[index]++;
                    rwlock.ExitWriteLock();
                }
                rwlock.ExitUpgradeableReadLock();
                return(response);
            }
            catch {
                rwlock.EnterWriteLock();
                actives[index]--;
                rwlock.ExitWriteLock();
                rwlock.EnterUpgradeableReadLock();
                if (effectiveWeights[index] > 0)
                {
                    rwlock.EnterWriteLock();
                    effectiveWeights[index]--;
                    rwlock.ExitWriteLock();
                }
                rwlock.ExitUpgradeableReadLock();
                throw;
            }
        }
Пример #14
0
        public override async Task <Stream> Handler(Stream request, Context context, NextIOHandler next)
        {
            int  n       = uris.Length;
            int  index   = -1;
            bool gotlock = false;

            try {
                spanlock.Enter(ref gotlock);
                var totalWeight = effectiveWeights.Sum();
                if (totalWeight > 0)
                {
                    int currentWeight = int.MinValue;
                    for (int i = 0; i < n; ++i)
                    {
                        int weight = (currentWeights[i] += effectiveWeights[i]);
                        if (currentWeight < weight)
                        {
                            currentWeight = weight;
                            index         = i;
                        }
                    }
                    currentWeights[index] = currentWeight - totalWeight;
                }
                else
                {
                    index = random.Next(n);
                }
            }
            finally {
                if (gotlock)
                {
                    spanlock.Exit();
                }
            }
            (context as ClientContext).Uri = uris[index];
            try {
                var response = await next(request, context).ConfigureAwait(false);

                gotlock = false;
                try {
                    spanlock.Enter(ref gotlock);
                    if (effectiveWeights[index] < weights[index])
                    {
                        effectiveWeights[index]++;
                    }
                }
                finally {
                    if (gotlock)
                    {
                        spanlock.Exit();
                    }
                }
                return(response);
            }
            catch {
                gotlock = false;
                try {
                    spanlock.Enter(ref gotlock);
                    if (effectiveWeights[index] > 0)
                    {
                        effectiveWeights[index]--;
                    }
                }
                finally {
                    if (gotlock)
                    {
                        spanlock.Exit();
                    }
                }
                throw;
            }
        }
Пример #15
0
 public static Task <Stream> IOHandler(Stream request, Context context, NextIOHandler next)
 {
     return(LogExtensions.IOHandler(instance, request, context, next));
 }
Пример #16
0
        public static async Task <Stream> IOHandler(this Log log, Stream request, Context context, NextIOHandler next)
        {
            bool enabled = context.Contains("Log") ? (context as dynamic).Log : log.Enabled;

            if (!enabled)
            {
                return(await next(request, context).ConfigureAwait(false));
            }
            var stream = await request.ToMemoryStream().ConfigureAwait(false);

            Trace.TraceInformation(ToString(stream));
            try {
                var response = await next(stream, context).ConfigureAwait(false);

                stream = await response.ToMemoryStream().ConfigureAwait(false);

                Trace.TraceInformation(ToString(stream));
                return(stream);
            }
            catch (Exception e) {
                Trace.TraceError(e.StackTrace);
                throw;
            }
        }
Пример #17
0
        public static async Task <Stream> IOHandler(this Log log, Stream request, Context context, NextIOHandler next)
        {
            bool enabled = context.Contains("log") ? (bool)context["log"] : log.Enabled;

            if (!enabled)
            {
                return(await next(request, context).ConfigureAwait(false));
            }
            var stream = await request.ToMemoryStream().ConfigureAwait(false);

#if !NET35_CF
            Trace.TraceInformation(ToString(stream));
#else
            Trace.WriteLine(ToString(stream));
#endif
            try {
                var response = await next(stream, context).ConfigureAwait(false);

                stream = await response.ToMemoryStream().ConfigureAwait(false);

#if !NET35_CF
                Trace.TraceInformation(ToString(stream));
#else
                Trace.WriteLine(ToString(stream));
#endif
                return(stream);
            }
            catch (Exception e) {
#if !NET35_CF
                Trace.TraceError(e.StackTrace);
#else
                Trace.WriteLine(e.StackTrace);
#endif
                throw;
            }
        }