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; } }
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; } }
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)); }
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)); }
public Task <Stream> IOHandler(Stream request, Context context, NextIOHandler next) { var clientContext = new ClientContext { Timeout = Timeout }; clientContext.Init(client); return(client.Request(request, clientContext)); }
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)); }
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; } }
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(); } }
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);
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; } }
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; } }
public static Task <Stream> IOHandler(Stream request, Context context, NextIOHandler next) { return(LogExtensions.IOHandler(instance, request, context, next)); }
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; } }
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; } }