An utility that was added to the DWScript sample WebServer during the 4 TeraPixel Mandelbrot experiment is the BackgroundWorkers API.

This is a rather low-level threading facility that can work well with Global Queues to handle background tasks or serializing tasks.

BackgroundWorkers static class

It’s found in the dwsBackgroundWorkersLibModule module, which exposes a System.Workers unit to the script. It has only 4 methods:

CreateWorkQueue ( name ) : create a work queue of the given name

( name ) : create a work queue of the given name DestroyWorkQueue ( name ) : destroys the work queue of given name, aborting all queued work

( name ) : destroys the work queue of given name, aborting all queued work QueueWork ( name, task, data ) : queues a work unit

( name, task, data ) : queues a work unit QueueSize( name ) : queries the number of work units for a given queue (size of the queue)

Each queue will process its work units sequentially, you can have as many queues as you want (or rather as memory and OS allows, but that’s a lot). The queues exist outside of the script contexts, and are shared by all scripts running in the same executable.

Under the hood queue rely on IOCP and are thus quite cheap both in terms of memory and overhead.

Usage

The dwsBackgroundWorkersLibModule offers an OnBackgroundWork event which you’re supposed to tie to whatever code you’ll use to process the queued work units.

In the context of the DWS sample WebServer, tasks are programs (scripts) that will be executed as if they had been invoked by an http request (ie. their WebRequest.ContentData will hold the data you passed)

Typically, you’ll start by creating your work queues in the startup script (the “.startup.pas” file default), then proceed to give them work. From that point on:

asynchronous workers: other requests will either immediately queue work, or accumulate in a global queue, and then create a work unit

background (polling) task: these will usually queue themselves, perform some work, sleep & terminate (note that the sleep() function in DWS is interruptible), rinse and repeat

You’re thus free to use the BackgroundWorkers as a basic MultiThreading API, to spread work over multiple threads, or as a serialization API, to ensure a strictly sequential execution.