Blog

Queueing With DreamFactory Scripting

Written by Terence Bennett | July 6, 2018

DreamFactory has long supported scripting as a way of allowing users to extend the handling capabilities of existing APIs (i.e. performing actions pre- and post-processing like modifying the request or response), or adding new APIs altogether via scripted services. This has proven to be a very popular feature of DreamFactory, but until release 2.3 it was missing a very big "nice to have", that being a way to save or queue the scripts to be run at a later time and not take the hit of processing the script at the time of the API call. Thus the advent of queued scripting.



Event Scripting

Like I mentioned, event scripting in DreamFactory has always supported the pre-process scriptable events (allowing validation and modification of the service request) and post-process scriptable events (allowing validation and modification of the service response). Nothing has changed there, but we have added a third option, the queued scriptable event.

For example, for the database record retrieve request (api/v2/db/_table/<table_name>), there are 3 events that fire.

The queued event, when fired, will save the following into a job that is queued for later processing…

  • the script identifier
  • the full request and response of the event
  • a snapshot of the environment at the time of the API call 

The scripts that you write can access the event structure like normal, as well as make platform calls to internal and external services. The only obvious caveat is that they cannot affect the processed API request or response to the client. But that's the point! Based on your queueing configuration, these scripts are run well after the API call has been handled, allowing you to do time consuming things like send emails, externally log events, or trigger some other background processing. Check out the docs for more details.

Scripting Services

Have a script that is triggered by a client, or one that isn't tied to a particular event that you want to queue? Just create a script service (based on the language you prefer), and select the "Queue For Later Execution" option on the Config tab of the service UI (the queued option in the API). When called, the API will respond immediately with a HTTP 202 "Accepted" status, queueing the script like the event scripts for later processing.

Check out the docs for more details.

Setup and Options

By default, every DreamFactory instance is set up so that queueing uses the system database, the default "database"

connection, and the default queue. The only thing required to get the queueing working is to start the listener. This

can done by a simple command-line command issued in the install directory...

$ php artisan queue:listen &

 For a quick setup, you can use a '&' to run the listener in the background. For production environments, see this documentation on setting up a more stable and resilient environment.

 The queue listener can be run with several options, made evident by running the command with the --help option.

    $ php artisan queue:listen --help
Usage:
queue:listen [options] [--] [connection]

Arguments:
connection The name of connection

Options:
--queue[=QUEUE] The queue to listen on
--delay[=DELAY] Amount of time to delay failed scripts [default: 0]
--memory[=MEMORY] The memory limit in megabytes [default: 128]
--timeout[=TIMEOUT] Seconds a script may run before timing out [default: 60]
--sleep[=SLEEP] Seconds to wait before checking queue for scripts [default: 3]
--tries[=TRIES] Number of times to attempt a script before logging it failed [default: 0]

Each script queued can be optionally configured to use a different configured connection (other than the default database connection found in config/queued.php), a specific queue, or a delay to postpone the execution of the script on retries. These three settings can be set in the config section of the event script or script service.

{
"name": "queued_script",
"label": "Queued Script",
"description": "",
"is_active": true,
"type": "v8js",
"config": {
"queued": true,
"content": "platform.api.post('db/_table/todo', {'name': 'queue_test'});",
"config": {
"connection": "redis",
"queue": "slow_queue",
"delay": 300
}
}
}

Check out the docs for more configuration options and detailed information.