public async Task HandleAsync(EndGameCommand command) { var game = await _context.Game.SingleOrDefaultAsync(g => g.Id == command.GameId && g.ActualStartTime != null && g.ActualEndTime == null); if (game == null) { throw new InvalidOperationException("Antamallasi ID:llä ei löydy käynnissä olevaa peliä!"); } game.EndGame(LocalTimeProvider.GetLocalTime(command.EndTime)); await _context.SaveChangesAsync(); }
public async Task HandleAsync(SetGamePauseStatusCommand command) { var game = await _context.Game.SingleOrDefaultAsync(g => g.Id == command.GameId && g.ActualEndTime == null); if (game == null) { throw new InvalidOperationException("Antamallasi ID:llä ei löydy aktiivista peliä. Et voi asettaa taukoja!"); } var pause = await GetOrCreatePause(command.GameId, command.TimeStamp); if (command.IsActivePause) { pause.EndTime = LocalTimeProvider.GetLocalTime(command.TimeStamp); } await _context.SaveChangesAsync(); }
public async Task HandleAsync(UpsertGameCommand command) { var game = await GetOrCreateGame(command.GameId); game.TournamentId = command.Request.TournamentId; game.AwayTeamId = command.Request.AwayTeamId; game.HomeTeamId = command.Request.HomeTeamId; game.StartTime = command.Request.StartTime != null ? LocalTimeProvider.GetLocalTime(command.Request.StartTime.Value) : ( DateTime? )null; game.GameDay = command.Request.GameDay != null ? LocalTimeProvider.GetLocalTime(command.Request.GameDay.Value) : (DateTime?)null; game.PlannedLength = command.Request.PlannedLength; await _context.SaveChangesAsync(); }
private async Task <GamePause> GetOrCreatePause(Guid gameId, DateTime timeStamp) { var pause = await _context.GamePause .SingleOrDefaultAsync(gp => gp.GameId == gameId && gp.EndTime == null); if (pause != null) { return(pause); } pause = new GamePause() { GameId = gameId, StartTime = LocalTimeProvider.GetLocalTime(timeStamp) }; _context.GamePause.Add(pause); return(pause); }
private static int GetPlayedSeconds(DateTime gameStartTime, ICollection <GamePause> gamePauses) { var secondsPaused = gamePauses.Where(gp => gp.EndTime != null).Aggregate(0, (total, current) => { if (current.EndTime.HasValue) { return(total + ( int )(current.EndTime.Value - current.StartTime).TotalSeconds); } return(total); }); var activePause = gamePauses.SingleOrDefault(gp => gp.EndTime == null); if (activePause != null) { return(( int )(activePause.StartTime - gameStartTime).TotalSeconds - secondsPaused); } return(( int )(LocalTimeProvider.GetLocalTime(DateTime.Now) - gameStartTime).TotalSeconds - secondsPaused); }
private static void DoFixedWindow() { var fixedWindowRules = new FixedWindowRule[] { new FixedWindowRule() { Id = "1", StatWindow = TimeSpan.FromSeconds(1), LimitNumber = 30, ExtractTarget = (request) => { return((request as SimulationRequest).RequestResource); }, CheckRuleMatching = (request) => { return(true); }, } }; var timeProvider = new LocalTimeProvider(); var algorithm = new InProcessFixedWindowAlgorithm(fixedWindowRules, timeProvider, true); // var redisClient = StackExchange.Redis.ConnectionMultiplexer.Connect("127.0.0.1"); // var algorithm = new RedisFixedWindowAlgorithm(fixedWindowRules, redisClient, timeProvider, true); for (int i = 0; i < 80; i++) { var result = algorithm.Check(new SimulationRequest() { RequestId = Guid.NewGuid().ToString(), RequestResource = "home", Parameters = new Dictionary <string, string>() { { "from", "sample" }, } }, null); var isLimit = result.IsLimit; Console.WriteLine($"IsLimit:{isLimit}"); foreach (var r in result.RuleCheckResults) { Console.WriteLine($"[{i}] Target:{r.Target},IsLimit:{r.IsLimit},Count:{r.Count}."); // If you need to return when a rule is restricted, you can use break. // However, this is not recommended, the count will be lost for the rule is not triggered // if (r.IsLimit) // { // break; // } } // // Do not use the LINQ method after traversal or multiple times in a single request. // // This results in duplicate counts. // var limit = result.Any(d=>d.IsLimit); // var r = result.First(); // Console.WriteLine($"[{i}] Target:{r.Target},IsLimit:{r.IsLimit},Count:{r.Count}."); if (i == 40) { algorithm.UpdateRules(new FixedWindowRule[] { new FixedWindowRule() { Id = "1", StatWindow = TimeSpan.FromSeconds(1), LimitNumber = 60, ExtractTarget = (request) => { return((request as SimulationRequest).RequestResource); }, CheckRuleMatching = (request) => { return(true); }, } }); } if (i == 60) { algorithm.UpdateRules(new FixedWindowRule[] { new FixedWindowRule() { Id = "1", StatWindow = TimeSpan.FromSeconds(1), LimitNumber = 40, ExtractTarget = (request) => { return((request as SimulationRequest).RequestResource); }, CheckRuleMatching = (request) => { return(true); }, } }); } } }
private static void DoLeakyBucket() { var leakyBucketRules = new LeakyBucketRule[] { new LeakyBucketRule(30, 10, TimeSpan.FromSeconds(1)) { Id = "2", ExtractTarget = (request) => { return((request as SimulationRequest).RequestResource); }, CheckRuleMatching = (request) => { return(true); }, } }; var timeProvider = new LocalTimeProvider(); var algorithm = new InProcessLeakyBucketAlgorithm(leakyBucketRules, timeProvider, true); // var redisClient = StackExchange.Redis.ConnectionMultiplexer.Connect("127.0.0.1"); // var algorithm = new RedisLeakyBucketAlgorithm(leakyBucketRules, redisClient, timeProvider, true); for (int i = 0; i < 160; i++) { if (i == 50) { algorithm.UpdateRules(new LeakyBucketRule[] { new LeakyBucketRule(50, 10, TimeSpan.FromSeconds(1)) { Id = "2", ExtractTarget = (request) => { return((request as SimulationRequest).RequestResource); }, CheckRuleMatching = (request) => { return(true); }, } }); } if (i == 70) { // Attention: // If you use delayed processing, such as Task.Delay, // increasing the outflow rate will have a greater damage to the data processing sequence. algorithm.UpdateRules(new LeakyBucketRule[] { new LeakyBucketRule(50, 20, TimeSpan.FromSeconds(1)) { Id = "2", ExtractTarget = (request) => { return((request as SimulationRequest).RequestResource); }, CheckRuleMatching = (request) => { return(true); }, } }); Thread.Sleep(1000); } if (i == 110 || i == 120 || i == 130 || i == 140 || i == 150) { Thread.Sleep(1000); } var result = algorithm.Check(new SimulationRequest() { RequestId = Guid.NewGuid().ToString(), RequestResource = "home", Parameters = new Dictionary <string, string>() { { "from", "sample" }, } }, null); // Wait in the return value is very useful, you can use it in the delay queue, // you can also make the current thread pause for a specified period of time. foreach (var r in result.RuleCheckResults) { Console.WriteLine($"[{i}] Target:{r.Target},IsLimit:{r.IsLimit},Count:{r.Count},Wait:{r.Wait}."); } } }
private static async Task DoFixedWindowAsync() { var fixedWindowRules = new FixedWindowRule[] { new FixedWindowRule() { Id = "1", StatWindow = TimeSpan.FromSeconds(1), LimitNumber = 30, ExtractTargetAsync = (request) => { return(Task.FromResult((request as SimulationRequest).RequestResource)); }, CheckRuleMatchingAsync = (request) => { return(Task.FromResult(true)); }, } }; var timeProvider = new LocalTimeProvider(); var algorithm = new InProcessFixedWindowAlgorithm(fixedWindowRules, timeProvider, true); // var redisClient = StackExchange.Redis.ConnectionMultiplexer.Connect("127.0.0.1"); // var algorithm = new RedisFixedWindowAlgorithm(fixedWindowRules, redisClient, timeProvider, true); for (int i = 0; i < 80; i++) { var result = algorithm.CheckAsync(new SimulationRequest() { RequestId = Guid.NewGuid().ToString(), RequestResource = "home", Parameters = new Dictionary <string, string>() { { "from", "sample" }, } }, null); var resultValue = await result; foreach (var r in resultValue.RuleCheckResults) { Console.WriteLine($"[{i}] Target:{r.Target},IsLimit:{r.IsLimit},Count:{r.Count}."); } if (i == 40) { algorithm.UpdateRules(new FixedWindowRule[] { new FixedWindowRule() { Id = "1", StatWindow = TimeSpan.FromSeconds(1), LimitNumber = 60, ExtractTargetAsync = (request) => { return(Task.FromResult((request as SimulationRequest).RequestResource)); }, CheckRuleMatchingAsync = (request) => { return(Task.FromResult(true)); }, } }); } if (i == 60) { algorithm.UpdateRules(new FixedWindowRule[] { new FixedWindowRule() { Id = "1", StatWindow = TimeSpan.FromSeconds(1), LimitNumber = 40, ExtractTargetAsync = (request) => { return(Task.FromResult((request as SimulationRequest).RequestResource)); }, CheckRuleMatchingAsync = (request) => { return(Task.FromResult(true)); }, } }); } } }