Schedule jobs to run at a time in the future.
The underlying implementation uses a heap of events, one for each job that needs to run in the future. The Async scheduler is responsible for waking up at the right time to run the jobs.