Create a Recurring Timer
- Capella Operational
Create a Timer that continues to execute until you manually cancel it.
The OnUpdate
JavaScript handler listens to mutations or data changes within a specified source collection.
When you create or modify data in the source collection, the Eventing Function executes its JavaScript code.
The Timer callback function relies on a control document which, if mutated, controls whether a recurring Timer is created or cancelled.
This page contains the following:
-
An example where a control document is created or mutated, which creates a Timer. This Timer fires every 30 seconds and writes a document to the source collection. The original document in the source collection does not change. The Timer continues to execute until you cancel it.
-
An example where a control document is mutated, which cancels any existing Timer with a reference that matches the control document’s
meta.id
. This has no effect if the Timer created has already fired.
Prerequisites
Before trying out the examples on this page, you must first:
-
Create two buckets called
bulk
andrr100
with a minimum size of 100MB. -
Inside the
bulk
bucket, create one keyspace calledbulk.data.source
. -
Inside the
rr100
bucket, create one keyspace calledrr100.eventing.metadata
.
For more information about creating buckets, scopes, and collections, see Manage Buckets.
Do not add, modify, or delete documents in the Eventing storage keyspace rr100.eventing.metadata while your Eventing Functions are in a deployed state.
|
Setup
Before following the examples on this page, you must set up a control document and an Eventing Function.
Create the Control Document
To create the control document:
-
Go to
. -
Select the keyspace
bulk.data.source
in the Get documents from list. -
Click Create Document.
-
In the Document ID field, enter recurring_timer::1.
-
Replace the JSON text with the following:
{ "type": "recurring_timer", "id": 1, "active": false }
-
Click Save to create the document.
Create an Eventing Function
To create a new Eventing Function:
-
Go to
. -
Click Add Function.
-
In the Settings page, enter the following Function settings:
-
recurring_timer under Name.
-
Test recurring timers. under Description.
-
The keyspace
bulk.data.source
under Listen to Location. -
The keyspace
rr100.eventing.metadata
under Eventing Storage.
-
-
Click Next.
-
In the Bindings page, click Add Binding and create the following binding:
-
Select Bucket.
-
Enter src_col as the Alias Name.
-
Enter the keyspace
bulk.data.source
under Bucket, Scope, and Collection. -
Select Read and Write under Permission.
-
-
Click Next.
-
In the code editor, replace the placeholder JavaScript code with the following code sample:
function CreateRecurringTimer(context) { log('From CreateRecurringTimer: creating timer', context.mode, context.id); // Creates a timestamp 30 seconds from now var thirtySecFromNow = new Date(); // Gets current time & adds 30 seconds to it thirtySecFromNow.setSeconds(thirtySecFromNow.getSeconds() + 30); // Creates a document to use as the context createTimer(RecurringTimerCallback, thirtySecFromNow, context.id, context); } function RecurringTimerCallback(context) { log('From RecurringTimerCallback: timer fired', context); // Re-executes the timer ASAP to ensure the Timer keeps running in case // errors or script timeouts happen in later "recurring work" CreateRecurringTimer({ "id": context.id, "mode": "via_callback" }); // Any sort of recurring work happens here and updates a date_stamp in a document src_col["cur_" + context.id] = { "last_update": new Date() }; } function OnUpdate(doc, meta) { // Filters mutations of interest if (doc.type !== 'recurring_timer') return; if (doc.active === false) { if (cancelTimer(RecurringTimerCallback, meta.id)) { log('From OnUpdate: canceled active Timer, doc.active', doc.active, meta.id); } else { log('From OnUpdate: no active Timer to cancel, doc.active', doc.active, meta.id); } } else { log('From OnUpdate: create/overwrite doc.active', doc.active, meta.id); CreateRecurringTimer({ "id": meta.id, "mode": "via_onupdate" }); } }
-
Click Create function to create your Eventing Function.
When a change happens to the data inside the source collection, the OnUpdate
handler targets the control document by ignoring all documents that do not have a doc.type
of recurring_timer
.
It then uses the field active
to determine which action to take:
-
If
active
is true, the Eventing Function creates a series of Timers that fire 30 seconds into the future. -
If
active
is false, the Eventing Function cancels any existing Timers.
When a Timer created by the Eventing Function fires, the callback RecurringTimerCallback
executes and writes a new document in the source collection with a similar key as another document in the source collection.
Example: Create a Recurring Timer and Allow the Timer to Fire and Rearm
This example walks you through how to create a Timer, have the Timer fire, and then have the Timer rearm.
Edit the Control Document
To edit the control document:
-
Go to
. -
Select the keyspace
bulk.data.source
in the Get documents from list. -
Click the control document recurring_timer::1 to open the Edit Document dialog.
-
Change
active
totrue
:{ "type": "recurring_timer", "id": 1, "active": true }
-
Click Save to create a mutation.
The document mutation causes the Eventing Function to create a Timer.
Check the Eventing Function Log
To check the Eventing Function log:
-
Go to
. -
Click the Log icon next to the recurring_timer Eventing Function. You should see the following in the debug log:
2021-07-18T10:50:37.879-07:00 [INFO] "From OnUpdate: create/overwrite doc.active" true "recurring_timer::1" 2021-07-18T10:50:37.879-07:00 [INFO] "From CreateRecurringTimer: creating timer" "via_onupdate" "recurring_timer::1" 2021-07-18T10:50:06.147-07:00 [INFO] "From OnUpdate: no active Timer to cancel, doc.active" false "recurring_timer::1"
-
Wait a few minutes and click the Log icon again. The Timer should have fired and executed the
RecurringTimerCallback
callback, and you should see the following in the debug log:2021-07-18T10:54:04.705-07:00 [INFO] "From RecurringTimerCallback: timer fired" {"id":"recurring_timer::1","mode":"via_callback"} 2021-07-18T10:54:04.705-07:00 [INFO] "From CreateRecurringTimer: creating timer" "via_callback" "recurring_timer::1" 2021-07-18T10:53:22.712-07:00 [INFO] "From RecurringTimerCallback: timer fired" {"id":"recurring_timer::1","mode":"via_callback"} 2021-07-18T10:53:22.712-07:00 [INFO] "From CreateRecurringTimer: creating timer" "via_callback" "recurring_timer::1" 2021-07-18T10:52:40.708-07:00 [INFO] "From RecurringTimerCallback: timer fired" {"id":"recurring_timer::1","mode":"via_callback"} 2021-07-18T10:52:40.708-07:00 [INFO] "From CreateRecurringTimer: creating timer" "via_callback" "recurring_timer::1" 2021-07-18T10:51:58.703-07:00 [INFO] "From RecurringTimerCallback: timer fired" {"id":"recurring_timer::1","mode":"via_callback"} 2021-07-18T10:51:58.703-07:00 [INFO] "From CreateRecurringTimer: creating timer" "via_callback" "recurring_timer::1" 2021-07-18T10:51:16.713-07:00 [INFO] "From RecurringTimerCallback: timer fired" {"id":"recurring_timer::1","mode":"via_onupdate"} 2021-07-18T10:51:16.713-07:00 [INFO] "From CreateRecurringTimer: creating timer" "via_callback" "recurring_timer::1" 2021-07-18T10:50:37.879-07:00 [INFO] "From OnUpdate: create/overwrite doc.active" true "recurring_timer::1" 2021-07-18T10:50:37.879-07:00 [INFO] "From CreateRecurringTimer: creating timer" "via_onupdate" "recurring_timer::1" 2021-07-18T10:50:06.147-07:00 [INFO] "From OnUpdate: no active Timer to cancel, doc.active" false "recurring_timer::1"
Check the Results in the Source Collection
To check that a new document has been created in the source collection:
-
Go to
. -
Select the keyspace
bulk.data.source
in the Get documents from list. -
Click the new document cur_recurring_timer::1 to open the Edit Document dialog. The JSON document includes data written by the Timer’s callback.
{ "last_update": "2021-07-18T17:56:10.707Z" }
-
Click Cancel to close the editor.
The Eventing Function you created writes a timestamp to the cur_recurring_timer::1 document every 30 seconds.
Example: Cancel the Recurring Timer
This example walks you through how to cancel the recurring Timer.
Edit the Control Document
To edit the control document:
-
Go to
. -
Select the keyspace
bulk.data.source
in the Get documents from list. -
Click the control document recurring_timer::1 to open the Edit Document dialog.
-
Change
active
tofalse
:{ "type": "recurring_timer", "id": 2, "active": false }
-
Click Save to create a mutation.
The document mutation causes the Eventing Function to create a Timer.
Check the Eventing Function Log
To check the Eventing Function log:
-
Go to
. -
Click the Log icon next to the recurring_timer Eventing Function. You should see the line
"From OnUpdate: canceled active Timer, doc.active" false "recurring_timer::1"
in the debug log.
The recurring Timer has been cancelled.