async Task Run(IEnv env) { _expectedCount = 0M; var endpoints = Servers.Select(m => new SimEndpoint(m, Port)).ToArray(); var lib = new BackendClient(env, endpoints); await lib.AddItem(0, 1); _expectedCount = 1M; for (int i = 0; i < Iterations; i++) { try { var curr = i % RingSize; var next = (i + 1) % RingSize; await lib.MoveItem(curr, next, 1); await env.Delay(Delay); } catch (ArgumentException ex) { env.Error("Unexpected error", ex); } } _actualCount = await lib.Count(); if (HaltOnCompletion) { env.Halt("DONE"); } }
async Task ProjectionThread() { // TODO: deduplication while (!_env.Token.IsCancellationRequested) { try { var position = _store.GetCounter(); var events = await _client.Read(position, int.MaxValue); if (events.Count > 0) { //_env.Debug($"Projecting {events.Count} events"); foreach (var e in events) { _proj.Dispatch(e); } position += events.Count; _store.SetCounter(position); } await _env.Delay(100.Ms()); } catch (TaskCanceledException) { // nothing return; } catch (Exception ex) { _env.Warning($"Projection error: {ex.Message}"); } } }
public static async Task SendWithBackOff(IEnv env, int recipient, object msg) { var counter = 0; while (true) { try { await env.Send(recipient, msg); return; } catch (Exception ex) { if (counter < 10) { counter++; var sleep = TimeSpan.FromSeconds(Math.Pow(2, counter)); env.Debug($"Retrying send on {ex.Message} #{counter} after {sleep.TotalSeconds} seconds"); await env.Delay(sleep); continue; } throw; } } }
async Task <TResponse> Unary <TRequest, TResponse>(TRequest req) { var now = _env.Time; foreach (var(i, ts, mark) in GetEndpoints()) { var endpoint = _endpoints[i]; _env.Debug($"Send '{req}' to {endpoint}"); if (ts != TimeSpan.Zero) { await _env.Delay(ts, _env.Token); } try { using (var conn = await _env.Connect(endpoint)) { await conn.Write(req); var res = await conn.Read(5.Sec()); if (res is ArgumentException ex) { throw new ArgumentException(ex.Message); } return((TResponse)res); } } catch (IOException ex) { if (!mark) { _env.Warning($"! {ex.Message} for '{req}'. Retrying {endpoint}"); continue; } if (_outages[i] > now) { _env.Warning($"! {ex.Message} for '{req}'. {endpoint} already DOWN"); } else { _env.Warning($"! {ex.Message} for '{req}'. {endpoint} DOWN"); _outages[i] = now + _downtime; } } } // we've exhausted all gateways. throw new IOException("No gateways active"); }
async Task ScheduleStore() { var next = TimeSpan.FromSeconds(Math.Ceiling(_env.Time.TotalSeconds * 2) / 2); if (_scheduled != next) { _scheduled = next; await _env.Delay(_scheduled - _env.Time); if (_buffer.Count > 0) { await _env.SimulateWork((5 * _buffer.Count + 10).Ms()); _stored.AddRange(_buffer); _env.Debug($"Store {_buffer.Count} events"); _buffer.Clear(); } } }