Task Scheduler API Specification

Editor Draft — 13 October 2014

This version:
http://www.w3.org/2012/sysapps/web-alarms/
Participate:
public-sysapps@w3.org (archives)
File a bug
Latest published version:
http://www.w3.org/TR/web-alarms/
Latest editor's draft:
http://www.w3.org/2012/sysapps/web-alarms/
Previous versions:
http://www.w3.org/TR/2013/WD-web-alarms-20130205/
Editors:
Mahesh Kulkarni, Samsung Electronics, Co., Ltd,
Former Editors:
Christophe Dumez, representing Intel and Samsung Electronics (Until January 2013 and mid-August 2014, respectively)

Abstract

This specification defines an API to schedule a task at a specified time. When the indicated time is reached, the application that scheduled the task will be notified via a functional event on a service worker. A task event will be delivered to a service worker, regardless of whether the application is active on user agent. Applications such as an alarm clock or an auto-updater may utilize this API to perform certain action at a specified time.

Table of Contents

  1. 1 Introduction
  2. 2 Conformance
  3. 3 Terminology
  4. 4 Requirements
  5. 5 Task Scheduler API
    1. 5.1 Interface ServiceWorkerRegistration
    2. 5.2 Interface TaskScheduler
    3. 5.3 Interface ScheduledTask
  6. 6 Events
    1. 6.1 Event Handler
    2. 6.2 The TaskEvent Interface
    3. 6.3 Firing task event to service worker
  7. References
  8. Acknowledgments

1 Introduction

This section is non-normative.

Example use of the ScheduledTask API for adding, getting and removing and listening for the alarm clock use cases:

How to set an alarm 10 minutes from now?

    // https://example.com/serviceworker.js
    this.ontask = function(task) {
        alert(task.data.message);
        console.log("Task scheduled at: " + new Date(task.time));
        // From here on we can write the data to IndexedDB, send it to any open windows,
        // display a notification, etc.
    }

    // https://example.com/webapp.js
    function onTaskAdded(task) {
        console.log("Task successfully scheduled.");
    }

    function onError(error) {
        alert("Sorry, couldn't set the alarm: " + error);
    }

    navigator.serviceWorker.ready.then(function(serviceWorkerRegistration) {
        serviceWorkerRegistration.taskScheduler.add(Date.now() + (10 * 60000), {
            message: "It's been 10 minutes, your soup is ready!"
        }).then(onTaskAdded, onError);
    });
        

How to get all the scheduled tasks whose time is in the future?

    navigator.serviceWorker.getRegistration().then(function(registration) {
        registration.taskScheduler.getPendingTasks().then(function(tasks) {
            alert("There are " + tasks.length + " tasks set.");
        }, function(error) {
            alert("An error occurred getting the scheduled tasks.");
        });
    }, function(error) {
        alert("An error occurred getting the scheduled tasks.");
    });
        

How to remove a scheduled task?

    navigator.serviceWorker.getRegistration().then(function(registration) {
        var request = registration.taskScheduler.remove(id).then(function() {
                alert("Task removed");
            }, function(error) {
                alert("Sorry, can't remove the task.");
            });
    }, function(error) {
        alert("An error occurred getting the scheduled tasks.");
    });
        

2 Conformance

This specification defines conformance criteria for a single product: the user agent that implements the interfaces that it contains.

Implementations that use ECMAScript to implement the APIs defined in this specification MUST implement them in a manner consistent with the ECMAScript Bindings defined in the Web IDL specification [WEBIDL], as this specification uses that specification and terminology.

3 Terminology

A JSON-serializable object is an object that when serialized or stringified conforms to the JSON Grammar as defined in [ECMASCRIPT].

The EventHandler interface represents a callback used for handling events as defined in [HTML5].

The Promise interface provides asynchronous access to the result of an operation that is ongoing, has yet to start, or has completed, as defined in [ECMASCRIPT6].

The concepts queue a task, event handler IDL attribute and fire a simple event are defined in [HTML5].

The concepts event and fire an event named eare defined in [DOM].

The terms event handler and event handler event types are defined in [HTML5].

Service worker, service worker registration, ServiceWorker, ServiceWorkerRegistration, ServiceWorkerGlobalScope, ExtendableEvent, and Handle Functional Event are defined in [SERVICE-WORKERS].

4 Requirements

Below is a summary of requirements associated with this API:

  1. An application must only be able to access its own scheduled tasks.
  2. A scheduled task identifier must be unique within the application origin.
  3. A scheduled task must persist if the system is restarted.
  4. A scheduled task must actively wake the system if the scheduled time is reached while sleeping.
  5. A scheduled task that was missed (e.g. because the device was off or the clock jumped past it) should be fired as soon as possible.
  6. A scheduled task and its associated data must be removed when the application's service worker registration is uninstalled.

5 Task Scheduler API

This section is non-normative.

The task scheduler supports the following features:

5.1 Interface ServiceWorkerRegistration

The Service Worker specification defines a ServiceWorkerRegistration interface [SERVICE-WORKERS], which this specification extends.

partial interface ServiceWorkerRegistration {
    readonly attribute TaskScheduler taskScheduler;
}

The taskScheduler attribute provides the developer access to a TaskScheduler.

5.2 Interface TaskScheduler

The TaskScheduler interface exposes methods to get, set or remove scheduled tasks. ScheduledTasks are application specific, so there is no way to see the tasks scheduled by other applications nor to modify them. Developers should set an ontask event handler in the associated service worker to listen for the task event when scheduled tasks should be executed.

interface TaskScheduler {
    Promise getPendingTasks();
    Promise add(DOMTimeStamp time, optional any data);
    Promise remove(DOMString taskId);
};

When invoked, the getPendingTasks() method must run the following steps:

  1. Make a request to the system to retrieve the tasks that were registered by the current application and whose scheduled time is in the future.
  2. Let promise be a new Promise object and resolver its associated resolver.
  3. Return promise and run the remaining steps asynchronously.
  4. If an error occurs, run these substeps and then terminate these steps:
    1. Let error be a new DOMException exception whose name is the same as the error returned.
    2. Run resolver's internal reject algorithm with error as value.
  5. When the operation completes successfully, run these substeps:
    1. Let tasks be a new array containing the ScheduledTask objects that were retrieved.
    2. Run resolver's intenal fulfill algorithm with tasks as value.

When invoked, the add(time[, data]) method must run the following steps:

  1. Make a request to the system to schedule a new task for the current application that will trigger at the given time (number of milliseconds since the epoch). If the time argument is in the past, the task will be executed as soon as possible, asynchronously. The system must associate the JSON-serializable data with the task if provided.
  2. Let promise be a new Promise object and resolver its associated resolver.
  3. Return promise and run the remaining steps asynchronously.
  4. If an error occurs, run these substeps and then terminate these steps:
    1. Let error be a new DOMException exception whose name is "QuotaExceededError" if the data argument exceeds an implementation-dependent size limit, or whose name is the same as the error returned otherwise.
    2. Run resolver's internal reject algorithm with error as value.
  5. When the operation completes successfully, run these substeps:
    1. Let task be a new ScheduledTask object.
    2. Set task's id attribute to the unique identifier returned by the system for the newly registered task.
    3. Set task's time attribute to the time argument.
    4. Set task's data attribute to the data argument, if provided.
    5. Run resolver's internal fulfill algorithm with task as value.

When invoked, the remove(taskId) method must run the following steps:

  1. Make a request to the system to unregister the task with the given unique taskId identifier.
  2. Let promise be a new Promise object and resolver its associated resolver.
  3. Return promise and run the remaining steps asynchronously.
  4. If an error occurs, run these substeps and then terminate these steps:
    1. Let error be a new DOMException exception whose name is the same as the error returned.
    2. Run resolver's internal reject algorithm with error as value.
  5. When the operation completes successfully, run these substeps:
    1. Let removed be a boolean value.
    2. Set removed to true if the task was removed, and to false if there was no task with the given identifier.
    3. Run resolver's intenal fulfill algorithm with removed as value.

5.3 Interface ScheduledTask

The ScheduledTask interface captures the properties of a scheduled task.

interface ScheduledTask {
    readonly attribute DOMString id;
    readonly attribute DOMTimeStamp time;
    readonly attribute any data;
};

The id attribute returns an identifier for the given ScheduledTask object that is unique within the origin. An implementation must maintain this identifier when a ScheduledTask is added.

The time attribute is the time at which this task is scheduled to fire, in milliseconds past the epoch (e.g. Date.now() + n). Due to performance, the task may be delayed past this time.

The data attribute optionally represents the JSON-serializable data associated with the task.

6 Events

The Service Worker specification defines a ServiceWorkerGlobalScope interface [SERVICE-WORKERS], which this specification extends.

partial interface ServiceWorkerGlobalScope {
    attribute EventHandler ontask;
};

6.1 Event Handler

The following is the event handler (and its corresponding event handler event type) that must be supported as attribute by the ServiceWorkerGlobalScope object.
event handler event handler event type
ontask task

6.2 The TaskEvent Interface

The TaskEvent interface represents a scheduled task.

interface TaskEvent : ExtendableEvent {
    readonly attribute ScheduledTask task;
};

6.3 Firing task event to service worker

A task event is fired when a scheduled task should be executed. The scheduled task is originated from the system and will wake up a service worker if it is not currently running.

When the scheduled task task went off by the system, the user agent must (unless otherwise specified) run these steps:

  1. Let callback be an algorithm that when invoked with a global, fires a service worker task event named task given task on global.
  2. Then run Handle Functional Event with task's service worker registration and callback.

To fire a service worker task event named e given task, fire an event named e with an event using the TaskEvent interface whose task attribute is initialized to a new ScheduledEvent object representing task.

References

[B2G-ALARM]
B2G Alarm API Specification, Mounir Lamouri, Kan-Ru Chen and Jonas Sicking. Mozilla.
[DOM]
DOM, Anne van Kesteren, Aryeh Gregor and Ms2ger. WHATWG.
[ECMASCRIPT]
ECMAScript Language Specification. ECMA.
[ECMASCRIPT6]
ECMAScript Language Specification (6th edition, draft). ECMA.
[HTML5]
HTML5, Ian Hickson. W3C.
[SERVICE-WORKERS]
Service Workers, Alex Russell and Jungkee Song. W3C.
[WEBIDL]
Web IDL, Cameron McCormack. W3C.

Acknowledgments

We would like to thank Kan-Ru Chen, Mounir Lamouri, Gene Lian and Jonas Sicking for their work on the API design, as well as the WebAPI/B2G teams at Mozilla [B2G-ALARM].