Updated scheduling API for better usability

November 23, 2017 11:51 am Published by Leave your thoughts

The whole scheduling API has been deprecated and replaced by a more user-friendly API from Starcounter version 2.3.1.7870.

Motivation

Unhandled exceptions in Scheduling.ScheduleTask crashes the code-host. This requires the developer to be extremely careful to handle exception when scheduling tasks, otherwise the code-host might crash and stop all the apps.

This was problematic, especially for production environments running tens of apps. When the code-host died, restarting all the apps was too slow. More explanations and discussion can be found in https://github.com/Starcounter/Home/issues/301.

Solution

All the scheduling methods that crashed the code-host have been depracated and replaced by an API where exceptions are logged instead. This is documented on the Running background jobs page of the documentation.

In short, these are the changes:

  • Exceptions thrown in synchronous tasks are brought to the waiting thread and logged.
  • Exceptions thrown in asynchronous tasks are logged.
  • Exceptions thrown in scheduled tasks do not bring down the code host.
  • Code after awaited scheduled tasks is executed on a thread picked by .NET, this is explained in Await with scheduled tasks.

The logged exceptions are available from the Administrator log.

Examples

Scheduling.ScheduleTask

// Deprecated:
Scheduling.ScheduleTask(() => { });

// New syntax:
Scheduling.RunTask(() => { });
// Deprecated:
Scheduling.ScheduleTask(() => { }, true);

// New syntax:
Scheduling.RunTask(() => { }).Wait();

Session.ScheduleTask

// Deprecated:
Session.ScheduleTask("", (s, id) => { });

// New syntax:
Session.RunTask("", (s, id) => { });
// Deprecated:
Session.ScheduleTask("", (s, id) => { }, true);

// New syntax:
Session.RunTask("", (s, id) => { }).Wait();

Session.ForAll

// Deprecated:
Session.ForAll((s, id) => { });

// New syntax:
Session.RunTaskForAll((s, id) => { });
// Deprecated:
Session.ForAll("", (s, id) => { }, true);

// New syntax:
Session.RunTaskForAll("", (s, id) => { }).Wait();

await with scheduled tasks

// The await keyword lets .NET pick the thread
await Scheduling.RunTask(() => Thread.Sleep(2000));

// .NET might pick a .NET thread or Starcounter thread. If a 
// .NET thread is picked, this code will throw an exception
Db.Transact(() => new Person());
// Synchronously waiting for the task.
Scheduling.RunTask(() => Thread.Sleep(2000)).Wait();

// Guaranteed to be on a Starcounter thread
Db.Transact(() => new Person());

Summary

We hope that these changes will make it easier to use scheduled tasks. If you have any questions, you can post them either on StackOverflow under the tag Starcounter or in our Home repository on GitHub.

Categorised in:

This post was written by Erlend Landrö

Leave a Reply

Your email address will not be published. Required fields are marked *