public async Task Start() { while (true) { State = SchedulerState.StartingChallenge; // Find the currently running challenge var current = await _challenges.GetCurrentChallenge(); // If there is no challenge running try to start a new one if (current == null) { Console.WriteLine("There is no current challenge - attempting to start a new one"); // Start the next challenge, if there isn't one wait a while var next = await _challenges.StartNext(); if (next == null) { Console.WriteLine("No challenges available, waiting for a while..."); State = SchedulerState.WaitingNoChallengesInPool; await Task.Delay(TimeSpan.FromMinutes(1)); continue; } Console.WriteLine($"Starting new challenge {next.Name}"); // Notify all subscribed channels about the new challenge await NotifyStart(next); current = next; } else { Console.WriteLine($"{current.Name} challenge is currently running"); } //There is a challenge running, wait until the end time or until someone externally pokes us awake var endTime = current.EndTime; while (endTime != null && endTime > DateTime.UtcNow) { var delay = endTime.Value - DateTime.UtcNow; if (delay > TimeSpan.Zero) { State = SchedulerState.WaitingChallengeEnd; await Task.WhenAny(_poker.WaitAsync(), Task.Delay(delay)); } } // If endtime is after now then something else poked the scheduler awake, reset scheduler logic if (endTime != null && endTime > DateTime.UtcNow) { continue; } State = SchedulerState.EndingChallenge; // Finish the current challenge await _challenges.EndCurrentChallenge(); // Transfer scores to leaderboard await UpdateLeaderboard(current, _solutions.GetSolutions(current.Id, uint.MaxValue)); // Get the leaderboard for the challenge that just finished and notify everyone await NotifyEnd(current, _solutions.GetSolutions(current.Id, uint.MaxValue)); // Wait for a cooldown period State = SchedulerState.WaitingCooldown; await Task.WhenAny(_poker.WaitAsync(), Task.Delay(TimeSpan.FromHours(23))); } }
public async Task AbruptEnd() { await _challenges.EndCurrentChallenge(); await _scheduler.Poke(); }