Exemplo n.º 1
0
        public async Task ToArms(
            [Option(ShortName = "r")] RetryPolicyKey retryPolicyKey     = RetryPolicyKey.NoRetry,
            [Option(ShortName = "c")] CachePolicyKey cachePolicyKey     = CachePolicyKey.NoCache,
            [Option(ShortName = "t")] TimeoutPolicyKey timeoutPolicyKey = TimeoutPolicyKey.NoTimeout,
            double?latitude = null, double?longitude = null)
        {
            var retryPolicy = _policyRegistry.Get <IAsyncPolicy>(retryPolicyKey.ToString());
            var cachePolicy = _policyRegistry.Get <IAsyncPolicy>(cachePolicyKey.ToString());
            var meteoPolicy = Policy.WrapAsync(cachePolicy, retryPolicy);

            await _battery.ToArms(timeoutPolicyKey);

            var coords = new Coordinate(latitude ?? DefaultLatitude, longitude ?? DefaultLongitude);

            var meteoTask        = meteoPolicy.ExecuteAndCaptureAsync(_ => GetMeteo(coords), new Context("Get meteo"));
            var registrationTask = retryPolicy.ExecuteAndCaptureAsync(_ => RegisterAsync(coords), new Context("Register unit"));
            await Task.WhenAll(registrationTask, meteoTask);

            var registrationPolicyCapture = registrationTask.Result;
            var meteoPolicyCapture        = meteoTask.Result;

            if (registrationPolicyCapture.Outcome == OutcomeType.Failure)
            {
                _console.Out.WriteLine($"Register unit failed: {registrationPolicyCapture.FinalException.Message}");
            }
            else
            {
                _mainFiringDirection = registrationPolicyCapture.Result.MainFiringDirection;
            }

            if (meteoPolicyCapture.Outcome == OutcomeType.Failure)
            {
                _console.Out.WriteLine($"Get meteo failed: {meteoPolicyCapture.FinalException.Message}");
            }
        }
Exemplo n.º 2
0
        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.");
        }
Exemplo n.º 3
0
        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.");
        }
Exemplo n.º 4
0
        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}.");
            }
        }
Exemplo n.º 5
0
        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);
        }