Timers

Timers are asynchronous compute which offers Function execution in reference to wall-clock events. Timers also measure and track the amount of elapsed time and can be used while archiving of expired documents at a preconfigured time.

Few important aspects related to timers are listed below:

  • Timers follow the same timeout semantics as their Parent Functions. So, if a Function has an execution timeout of 60 seconds, each of the timers created from the Function inherits the same execution timeout value of 60 seconds.

  • Timers may run on a different node than the one on which it was created.

  • One execution of timers is guaranteed despite node failures and cluster rebalances.

  • During Function backlogs, timers get eventually executed.

  • The metadata bucket stores information about timers and its association with a Function.

  • Ensure that the metadata bucket is not deleted or flushed, or the keys in metadata bucket gets updated.

  • With an increase in the usage of timers, the metadata memory assignment must also be increased. Due to runtime or programmatic errors in the function handler code, if triggering of a timer fails, then timer execution may get permanently blocked.

  • Bindings can be reused in timers. Bindings, created during the Function definition, can be accessed by the timer constructs in the Function handler code.

  • Timers get deleted when the associated Function is deleted or undeployed.

Language Constructs

The timers language construct is added to support requirements of Couchbase Functions.

To create a timer use the below syntax:

createTimer(callback, timestamp, reference, context)

In the createTimer syntax:

  • callback - is the function called when the timer gets triggered. You need to ensure that the callback function is the top-level function that takes a single argument, the context.

  • timestamp - is the JavaScript Date object timestamp at which the Function handler code must be executed.

  • reference - is a unique string that gets passed. This string helps to identify the timer that is being created. All callback and references are scoped to the Function definition. Also, all references must be unique within the Function scope. When multiple timers are created with the same unique reference, old timers (with the same unique reference) get canceled.

  • context - is any JavaScript object that can be serialized. When the timer gets triggered, the context specified during timer creation gets passed to the callback Function. For optimal performance, the context object payload needs to be lesser than 100 KB.

A sample createTimer language construct is provided for reference.

createTimer(DocTimerCallback, twoMinsPrior, meta.id, context)

In the sample construct:

  • DocTimerCallback is the name of the function used in the Function handler code.

  • twoMinsPrior is a JavaScript Date object.

  • meta.id is a generic reference string that can be used in the Couchbase cluster.

  • context is the JavaScript object that is used in the Function handler code.

Sharding of Timers

Timers get automatically sharded across Eventing nodes and therefore are elastically scalable. Triggering of timers at or after a specified time interval is guaranteed. However, triggering of timers may either be on the same node (where the timer was created), or on a different node. Relative ordering between two specific timers cannot be maintained.

Debugging and Logs

Timers cannot be debugged using the Visual Debugger. For debugging, Couchbase recommends enclosing of timers in a try-catch block. When logging is enabled, timer related logs get captured as part of the Application logs.

Elapsed Timestamps

During runtime, when a Function handler code contains a timestamp in the past (elapsed timestamp), the system executes the code in the next available time window, as soon as the required resources are available.

Handling Delays

During Function backlogs, execution of timers may be delayed. To handle these delays, you need to program additional time window in your code. If your business logic is time-sensitive after this additional time window the code should refrain from its Function execution.

The following is a sample code snippet which performs a timestamp check (my_deadline) before code execution.

func callback(context)
{
  //context.my_deadline is the parameter in the timer payload
    if new Date().getTime() > context.my_deadline
      {
        // timestamp is back-dated, do not execute the rest of the timer
        return;
       }
}

Examples

The Eventing Example section provides an example for Timers, Document Expiry and Archival.