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}");
                }
            }
        }
Beispiel #3
0
        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");
        }
Beispiel #5
0
        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();
                }
            }
        }