async Task HandleRequest(IConn conn) { using (conn) { var req = await conn.Read(5.Sec()); try { _env.Debug($"{req}"); await _env.SimulateWork(35.Ms()); switch (req) { case AddItemRequest r: await AddItem(conn, r); break; case MoveItemRequest r: await MoveItem(conn, r); break; case CountRequest r: var amount = _store.Count(); await conn.Write(new CountResponse(amount)); break; } } catch (Exception ex) { _env.Error($"Error while processing {req}", ex); } } }
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; } } }
public async Task Commit(params object[] e) { _env.Debug($"Commit '{string.Join(", ", e)}' to {_endpoint}"); using (var conn = await _env.Connect(_endpoint)) { await conn.Write(new CommitRequest(e)); await conn.Read(5.Sec()); } }
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 HandleAsync(IConn conn) { try { using (conn) { var req = await conn.Read(5.Sec()); switch (req) { case DownloadRequest dr: await conn.Write(_stored.Skip((int)dr.From).Take(dr.Count).ToList()); return; case CommitRequest cr: await _env.SimulateWork(5.Ms()); foreach (var e in cr.Events) { _buffer.Enqueue(e); } ScheduleStore(); await conn.Write("OK"); return; default: conn.Write($"Unknown request {req}"); return; } } } catch (Exception ex) { _env.Debug($"Error: {ex.Message}"); } }
public async Task DispatchMessage(object message) { _env.Debug($"A{ThisActor:0000} {message}"); await RetryPolicy.HandleWithRetry(() => DispatchMessageInner(message)); }