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();
        }