public async Task ToArms(TimeoutPolicyKey policyKey) { var policy = _policyRegistry.Get <IAsyncPolicy>(policyKey.ToString()); var watch = new Stopwatch(); watch.Start(); await policy .ExecuteAndCaptureAsync( _ => Task.WhenAll(_howitzers.Select(howitzer => howitzer.ToArms())), new Context("Battery to arms.")); _howitzers.RemoveAll(h => !h.IsOperational); watch.Stop(); _console.Out.WriteLine($"Battery {Id} with {_howitzers.Count} howitzers reporting for duty within {watch.ElapsedMilliseconds} ms."); }
public async Task Aim(double angleHorizontal, double angleVertical, TimeoutPolicyKey timeoutPolicyKey) { var timeoutPolicy = _policyRegistry.Get <IAsyncPolicy>(timeoutPolicyKey.ToString()); var watch = new Stopwatch(); watch.Start(); await timeoutPolicy.ExecuteAndCaptureAsync( (policyContext, token) => Task.WhenAll(_howitzers.Select(h => h.Aim( angleHorizontal, angleVertical, token))), new Context("Battery aiming"), CancellationToken.None); // CancellationToken.None means we don't want independent cancellation control watch.Stop(); _console.Out.WriteLine($"Battery {Id} with {_howitzers.Count(h=>h.AimingDone)} howitzers ready to fire within {watch.ElapsedMilliseconds} ms."); }
public async Task Fire(int ammunitionPerHowitzer, TimeoutPolicyKey timeoutPolicyKey) { var timeoutPolicy = _policyRegistry.Get <IAsyncPolicy>(timeoutPolicyKey.ToString()); var watch = new Stopwatch(); watch.Start(); await timeoutPolicy.ExecuteAndCaptureAsync( (policyContext, token) => Task.WhenAll(_howitzers .Where(h => h.AimingDone) .Select(h => h.Fire(ammunitionPerHowitzer, token))), new Context("Battery firing"), CancellationToken.None); // CancellationToken.None means we don't want independent cancellation control); watch.Stop(); _console.Out.WriteLine($"Battery {Id} firing done within {watch.ElapsedMilliseconds} ms."); foreach (var howitzer in _howitzers) { _console.Out.WriteLine($"Howitzer {howitzer.Id} ammunition consumption {howitzer.AmmunitionConsumption}."); } }
public async Task Assault( double targetLatitude, double targetLongitude, double directionDeviation, [Option(ShortName = "t")] TimeoutPolicyKey timeoutPolicyKey = TimeoutPolicyKey.NoTimeout, [Option(ShortName = "c")] TimeoutPolicyKey correctionTimeoutPolicyKey = TimeoutPolicyKey.NoTimeout) { var(horizontal, vertical) = GetAngles(targetLatitude, targetLongitude, directionDeviation); await _battery.Aim(horizontal, vertical, timeoutPolicyKey); await _battery.Fire(40, timeoutPolicyKey); var correctionTimeoutPolicy = _policyRegistry.Get <IAsyncPolicy>(correctionTimeoutPolicyKey.ToString()); var correctionFallbackPolicy = Policy .Handle <RpcException>() .Or <TimeoutRejectedException>() .FallbackAsync( async token => { var coordBoundaries = new CoordinateBoundaries(_battery.Latitude, _battery.Longitude, 2, DistanceUnit.Kilometers); _battery.RePosition( _faker.Random.Double(coordBoundaries.MinLatitude, coordBoundaries.MaxLatitude), _faker.Random.Double(coordBoundaries.MinLongitude, coordBoundaries.MaxLongitude) ); var assaultCommand = await _client.InPositionAsync(new Position { Latitude = _battery.Latitude, Longitude = _battery.Longitude }, deadline: DateTime.UtcNow.AddMilliseconds(1000)); _console.Out.WriteLine( $"Assault command received. Target: lat: {assaultCommand.Position.Latitude}; lon:{assaultCommand.Position.Longitude}" + $" direction: {assaultCommand.DirectionDeviation};"); }, async exception => { _console.Out.WriteLine($"Could not get correction, falling back to new position. Exception: {exception.Message}"); await Task.CompletedTask; }); var lastResortPolicy = Policy .Handle <RpcException>() .Or <TimeoutRejectedException>() .FallbackAsync(token => _battery.Disengage()); var policyWrap = Policy.WrapAsync(lastResortPolicy, correctionFallbackPolicy, correctionTimeoutPolicy); await policyWrap.ExecuteAsync(async token => { var correction = await _client.GetCorrectionAsync( new Position { Latitude = _battery.Latitude, Longitude = _battery.Longitude }, cancellationToken: token); token.ThrowIfCancellationRequested(); _console.Out.WriteLine( $"Assault command correction received. Target: lat: {correction.Position.Latitude}; lon:{correction.Position.Longitude}" + $" direction: {correction.DirectionDeviation};"); }, CancellationToken.None); }