Under development — the help is being filled in plugin by plugin.
Help/Plugin reference/callbackworker
Plugin reference

callbackworker

A background worker pool that runs script callbacks off the main thread.

21 functionsnamespace callbackworkersource plugins/callback_worker/CallbackWorkerPlugin.c

Written from a line-by-line source review; every example output is from a real run.

Introduction

The callbackworker plugin is an async job runner: an `Start` call makes a scheduled job from a script-level callback and an input blob, which a background thread runs in FIFO order. Meanwhile, the script can do other work and at any time query the job's state via the asyncmeta-compatible verbs (Phase, Status, JobMeta). After the job completes, the response blob can be taken with `Wait`, `Take`, or `TakeBlob`, and the async lifecycle is closed by `Cancel` and the plugin-level `Close`.

Connection to the asyncmeta vocabulary

The plugin is built fully on the asyncmeta constants. `Capabilities()` returns exactly the `asyncmeta.ProfileBlobJob()` bitmask (=3701), which signals the worker supports the complete “blob-job” profile: WaitComplete, JobMeta, PhaseText, StatusText, JobInfo, Known, BlobTake, and BlobResultMeta. `Phase()` returns the asyncmeta `PhaseQueued`/`PhaseRunning`/`PhaseCompleted` value (0/1/2), and `JobMeta(jobId, key)` knows the `JobMetaPhase`, `JobMetaStatus`, `JobMetaTimeout`, `JobMetaKnown`, `JobMetaHasBlobResult`, `JobMetaBlobResultSize` keys. This shared vocabulary makes it possible to query a callbackworker job with the same functions as another asyncmeta-compatible backend's job.

Two start styles

`Start(callback, blob, timeoutMs)` passes a script-level blob to the callback in ref-style: the callback can modify the blob bytes in place, and these become the response blob's bytes. `StartBorrowedText(callback, text, timeoutMs)` works the same way, but the input is a string — the plugin passes it to the callback as a borrowed blob buffer.

Wait styles

Two functions are available for waiting on the job's completion. `Wait(jobId, timeoutMs)` BLOCKS, and when the job completes, returns the response blob — the job is destroyed afterward (one-step sync style). `WaitComplete(jobId, timeoutMs)` also blocks but only returns a 1/0 (did it complete?), and does NOT destroy the job — afterward `Phase`/`Status`/`JobMeta` can be queried, and `Take` or `TakeBlob` collects the response blob when and how the script wants.

Loading the plugin

plugin "../plugins/print/PrintPlugin";
plugin "../plugins/async_meta/AsyncMetaPlugin";
plugin "../plugins/callback_worker/CallbackWorkerPlugin";

A typical flow — one-step Start+Wait

callback i32 Echo(ref blob $Request)
{
// you may modify the request bytes; these will be the response
blob
return(1);
}
i32 main()
{
i64 $jobId;
blob $req[3];
blob $resp[8];
$req[0] = 65;
$req[1] = 66;
$req[2] = 67;
$jobId = callbackworker.Start("Echo", $req, 5000);
$resp = callbackworker.Wait($jobId, 5000);
// $resp.Length == 3, [65,66,67]
callbackworker.Close();
return(0);
}

A typical flow — two-step WaitComplete + Take

i64 $jobId;
$jobId = callbackworker.Start("Echo", $req, 5000);
// ... the script does other things ...
callbackworker.WaitComplete($jobId, 5000);
if (callbackworker.Status($jobId) == 0)
{
blob $resp[8];
$resp = callbackworker.TakeBlob($jobId);
// ... processing ...
}

What to know about every function (the basics)

  • The background thread is single-threaded FIFO: jobs run in Start order, one at a time.

  • timeoutMs is the callback's run time limit, NOT the Wait wait time. -1 = infinite (without forced shutdown).

  • Wait DESTROYS the job; the jobId is invalid afterward. Take and TakeBlob also destroy, but only if the job has completed (Phase = Completed).

  • WaitComplete does NOT destroy: afterward you can still query Phase, Status, JobMeta, and use Take/TakeBlob to collect the response.

  • Capabilities always returns the same fixed mask (3701 = ProfileBlobJob) — it does not change during runtime.

  • JobMeta(jobId, JobMetaKnown) does NOT fail on an unknown jobId, but returns 0 (the Known semantics). For other keys, an unknown jobId raises a runtime error.

  • Phase returns 0/1/2 (Queued/Running/Completed), matching the asyncmeta constants.

  • Status 0 = success; non-zero = the job ran with errors. ErrorText describes more precisely what happened.

  • Close shuts down the entire plugin-level worker thread: pending jobs break with DOMIN_STATUS_SHUTDOWN.

  • An error (stopping the script) is caused by an invalid jobId, a wrong argument count or type, an out-of-range timeoutMs, and touching an already-closed plugin.

How to read the signatures

callback is the name of the script-level callback (with signature `callback i32 NAME(ref blob $X)`). request is a blob the callback may modify in place; it becomes the response blob. timeoutMs is the callback's run-time limit in ms; -1 = infinite. jobId is the positive id returned by Start*. metaKey is one of the asyncmeta.JobMeta* constants. The type after the -> arrow is the return type.

Lifecycle

The plugin-level capability query and full worker-thread shutdown.

callbackworker.Capabilities

callbackworker.Capabilities() -> int

Returns the worker's capability bitmask matching the asyncmeta constants.

Parameters

This function takes no arguments.

Return value

asyncmeta.ProfileBlobJob (=3701): WaitComplete | JobMeta | PhaseText | StatusText | JobInfo | Known | BlobTake | BlobResultMeta.

Example
printf("%d\n", callbackworker.Capabilities());
printf("%d\n", (callbackworker.Capabilities() ==
asyncmeta.ProfileBlobJob()));
Output after running
3701
1
When to use

For checking against another asyncmeta-compatible backend: with the Supports* helpers you can verify whether a given profile package is supported. The worker's value is FIXED — it doesn't change during runtime.

callbackworker.Close

callbackworker.Close() -> int

Shuts down the worker thread: closes pending jobs and rejects new Start requests.

Parameters

This function takes no arguments.

Return value

0 (always). A subsequent Start raises a runtime error.

Example
callbackworker.Close();
printf("Close done\n");
Output after running
Close done
When to use

At the end of the script, for clean resource shutdown. A currently running callback can finish, but no new job is started. If you call Start afterward, you get a runtime error.

Job submission

Scheduling async jobs: a callback and an input (blob or text) → a job running on the background thread. Both forms return immediately with the jobId.

callbackworker.Start

callbackworker.Start(callback, request, timeoutMs) -> int

Schedules an async job: the callback gets the request blob's bytes in ref-style; these become the response blob's bytes.

Parameters
Parameter Type Description
callback string The script-level callback name. Signature: `callback i32 NAME(ref blob $X)`.
request blob The input data passed to the callback. The callback may modify it in place; the modification is visible in the response blob.
timeoutMs int The callback's RUN-time limit in ms (NOT Wait's wait time). -1 = infinite; otherwise 0..2147483647.
Return value

The jobId (positive i64) to pass to the other operations. A bad argument or a closed worker raises a runtime error.

Example
blob $req[3];
$req[0] = 65;
$req[1] = 66;
$req[2] = 67;
i64 $jobId;
$jobId = callbackworker.Start("Echo", $req, 5000);
printf("%d\n", ($jobId > 0));
Output after running
1
When to use

For the classic “work in the background” pattern: Start returns immediately, so the script can do other things. The callback may do any logic and modify the blob content — this becomes the response blob.

callbackworker.StartBorrowedText

callbackworker.StartBorrowedText(callback, text, timeoutMs) ->
int

Schedules an async job with a text input — the string is passed to the callback as a borrowed blob.

Parameters
Parameter Type Description
callback string The script-level callback name.
text string The text passed to the callback. The callback may modify the bytes in place (as a blob).
timeoutMs int The callback's run-time limit in ms. -1 = infinite.
Return value

The jobId (positive i64).

Example
i64 $jobId;
$jobId = callbackworker.StartBorrowedText("Echo", "hello", 5000);
printf("%d\n", ($jobId > 0));
Output after running
1
When to use

Use it when the input is already text (a command, a JSON string, a newline-separated record). The borrowed buffer requires less memory copying than an explicit blob allocation + copy.

Wait and take

Waiting for the job to complete and taking the response (response blob). Wait is one-step; WaitComplete + Take/TakeBlob is the two-step pattern.

callbackworker.Wait

callbackworker.Wait(jobId, timeoutMs) -> blob

Blocks until the job completes, then returns the response blob. The job is destroyed afterward.

Parameters
Parameter Type Description
jobId int The jobId from Start.
timeoutMs int Maximum wait in milliseconds; -1 = infinite.
Return value

The response blob (the request bytes as modified by the callback). A timeout raises a DOMIN_STATUS_TIMEOUT runtime error.

Example
blob $req[3];
blob $resp[8];
$req[0] = 65;
$req[1] = 66;
$req[2] = 67;
i64 $jobId;
$jobId = callbackworker.Start("Echo", $req, 5000);
$resp = callbackworker.Wait($jobId, 5000);
printf("%d\n", $resp.Length);
Output after running
3
When to use

One-step sync pattern: if the script actually wants to wait and needs the result. The jobId is INVALID after Wait — any further query raises a runtime error.

callbackworker.WaitComplete

callbackworker.WaitComplete(jobId, timeoutMs) -> int

Blocks until the job completes, but does NOT destroy the job — the status and result can be queried afterward.

Parameters
Parameter Type Description
jobId int The jobId.
timeoutMs int Maximum wait in ms; -1 = infinite.
Return value

1 if the job completed; 0 if the timeout expired and the job is still running.

Example
i64 $jobId;
$jobId = callbackworker.Start("Echo", $req, 5000);
printf("%d\n", callbackworker.WaitComplete($jobId, 5000));
Output after running
1
When to use

Two-step pattern: if you want to separately check Status before taking the response blob. After a 1 result, Phase, Status, JobMeta, Info are queryable, and Take/TakeBlob takes the response.

callbackworker.Take

callbackworker.Take(jobId) -> blob

Returns the response blob of an already completed (Phase=Completed) job, and destroys the job.

Parameters
Parameter Type Description
jobId int The jobId.
Return value

The response blob. If the job has not completed, a runtime error. If the Status is non-OK, returns the Status as an error code.

Example
i64 $jobId;
$jobId = callbackworker.Start("Echo", $req, 5000);
callbackworker.WaitComplete($jobId, 5000);
blob $resp[8];
$resp = callbackworker.Take($jobId);
printf("%d\n", $resp.Length);
Output after running
3
When to use

The second phase of the two-step pattern: the job has completed, take the result. Take is a synonym for TakeBlob — same function, two names with identical semantic contract.

callbackworker.TakeBlob

callbackworker.TakeBlob(jobId) -> blob

Returns the response blob of an already completed job, and destroys the job. Synonym for Take.

Parameters
Parameter Type Description
jobId int The jobId.
Return value

The response blob.

Example
i64 $jobId;
$jobId = callbackworker.Start("Echo", $req, 5000);
callbackworker.WaitComplete($jobId, 5000);
blob $resp[8];
$resp = callbackworker.TakeBlob($jobId);
printf("%d %d %d\n", $resp[0], $resp[1], $resp[2]);
Output after running
65 66 67
When to use

Both names (Take and TakeBlob) are available so the caller can pick one stylistically; behavior is identical. The “Blob” in the name is intentional: it emphasizes that a blob result is being taken.

callbackworker.Cancel

callbackworker.Cancel(jobId) -> int

Attempts to remove a queued (pending) job.

Parameters
Parameter Type Description
jobId int The jobId.
Return value

1 if the job was removed from the queue; 0 if it is already running or has completed.

Example
i64 $jobId;
$jobId = callbackworker.Start("Echo", $req, 5000);
printf("%d\n", callbackworker.Cancel($jobId));
Output after running
0
When to use

Only jobs not yet started (queued) can be canceled. A 0 return is normal if the job is already running — then the callback must stop itself (via timeoutMs).

State queries

The job's current state: phase (queued/running/completed) and status (success/error) with both numeric code and text; plus the optional error message.

callbackworker.Phase

callbackworker.Phase(jobId) -> int

Returns the job's phase from the asyncmeta.Phase* constants.

Parameters
Parameter Type Description
jobId int The jobId.
Return value

asyncmeta.PhaseQueued (=0), PhaseRunning (=1), or PhaseCompleted (=2).

Example
i64 $jobId;
$jobId = callbackworker.Start("Echo", $req, 5000);
callbackworker.WaitComplete($jobId, 5000);
printf("%d\n", callbackworker.Phase($jobId));
Output after running
2
When to use

For programmatic phase checks: compare with the asyncmeta constants. The 2 value is the precondition for Take/Wait.

callbackworker.PhaseText

callbackworker.PhaseText(jobId) -> string

Returns the phase name as text.

Parameters
Parameter Type Description
jobId int The jobId.
Return value

“queued”, “running”, or “completed”.

Example
i64 $jobId;
$jobId = callbackworker.Start("Echo", $req, 5000);
callbackworker.WaitComplete($jobId, 5000);
printf("%s\n", callbackworker.PhaseText($jobId));
Output after running
completed
When to use

For logging or UI display. The textual counterpart of Phase's numeric value — same info in readable form.

callbackworker.Status

callbackworker.Status(jobId) -> int

Returns the job's status: 0 = success, non-zero = error (DOMIN_STATUS_*).

Parameters
Parameter Type Description
jobId int The jobId.
Return value

0 if the job ran successfully; non-zero is the error code.

Example
i64 $jobId;
$jobId = callbackworker.Start("Echo", $req, 5000);
callbackworker.WaitComplete($jobId, 5000);
printf("%d\n", callbackworker.Status($jobId));
Output after running
0
When to use

After WaitComplete, check this first: if 0, go ahead with Take; if non-0, ErrorText describes the error more precisely.

callbackworker.StatusText

callbackworker.StatusText(jobId) -> string

Returns the textual counterpart of the status.

Parameters
Parameter Type Description
jobId int The jobId.
Return value

“success” on a successful job, other text depending on the error type.

Example
i64 $jobId;
$jobId = callbackworker.Start("Echo", $req, 5000);
callbackworker.WaitComplete($jobId, 5000);
printf("%s\n", callbackworker.StatusText($jobId));
Output after running
success
When to use

For logging or user feedback. The textual counterpart of Status.

callbackworker.State

callbackworker.State(jobId) -> int

Returns a unified state code for the job (a shorthand of phase or completion-with-error).

Parameters
Parameter Type Description
jobId int The jobId.
Return value

A state code describing the job's current situation (a combination of Phase + Status).

Example
i64 $jobId;
$jobId = callbackworker.Start("Echo", $req, 5000);
callbackworker.WaitComplete($jobId, 5000);
printf("%d\n", callbackworker.State($jobId));
Output after running
2
When to use

Makes the job state visible in one query; a simplified summary of Phase + Status. The exact code meaning is tied to the Phase and Status defaults.

callbackworker.ErrorText

callbackworker.ErrorText(jobId) -> string

Returns the job's error message (empty on a successful job).

Parameters
Parameter Type Description
jobId int The jobId.
Return value

The error message text; empty string on a successful job.

Example
i64 $jobId;
$jobId = callbackworker.Start("Echo", $req, 5000);
callbackworker.WaitComplete($jobId, 5000);
printf("%d\n", str.Len(callbackworker.ErrorText($jobId)));
Output after running
0
When to use

If Status is non-0, ErrorText gives the error cause in human-readable form. For logging and UI, it gives a human-level description.

Job metadata

Detailed job queries: is it known, what is the timeout, does it have a blob result and how big — plus a combined Info string.

callbackworker.JobKnown

callbackworker.JobKnown(jobId) -> int

Tells whether the jobId belongs to a known (still living or queryable) job.

Parameters
Parameter Type Description
jobId int The jobId.
Return value

1 if known; 0 if not (e.g. already destroyed by Wait/Take).

Example
i64 $jobId;
$jobId = callbackworker.Start("Echo", $req, 5000);
printf("%d\n", callbackworker.JobKnown($jobId));
Output after running
1
When to use

For defensive checks: before calling a state function, this returning 0 signals the job no longer exists. JobMeta(JobMetaKnown) does the same in the asyncmeta-style query.

callbackworker.JobTimeout

callbackworker.JobTimeout(jobId) -> int

Returns the job's configured callback timeout in milliseconds.

Parameters
Parameter Type Description
jobId int The jobId.
Return value

The timeoutMs value (the value passed at Start).

Example
i64 $jobId;
$jobId = callbackworker.Start("Echo", $req, 5000);
printf("%d\n", callbackworker.JobTimeout($jobId));
Output after running
5000
When to use

For configuration checking or logging. Returns -1 if the job is set to infinite wait.

callbackworker.JobHasBlobResult

callbackworker.JobHasBlobResult(jobId) -> int

Tells whether the job has a blob result (completed and successful).

Parameters
Parameter Type Description
jobId int The jobId.
Return value

1 if yes; 0 if no (not completed yet, or unsuccessful).

Example
i64 $jobId;
$jobId = callbackworker.Start("Echo", $req, 5000);
callbackworker.WaitComplete($jobId, 5000);
printf("%d\n", callbackworker.JobHasBlobResult($jobId));
Output after running
1
When to use

Defensive check before calling Take/TakeBlob: if 0, Take raises a runtime error.

callbackworker.JobBlobResultSize

callbackworker.JobBlobResultSize(jobId) -> int

Returns the response blob's size in bytes (only for a completed, successful job).

Parameters
Parameter Type Description
jobId int The jobId.
Return value

The blob size in bytes. If the job did not complete successfully, a runtime error.

Example
i64 $jobId;
$jobId = callbackworker.Start("Echo", $req, 5000);
callbackworker.WaitComplete($jobId, 5000);
printf("%d\n", callbackworker.JobBlobResultSize($jobId));
Output after running
3
When to use

For memory pre-allocation: if you know how big the response will be, you can allocate a sufficiently large blob before Take. Use it together with JobHasBlobResult.

callbackworker.JobMeta

callbackworker.JobMeta(jobId, metaKey) -> int

Returns a specific meta field of the job by asyncmeta.JobMeta* keys.

Parameters
Parameter Type Description
jobId int The jobId.
metaKey int An asyncmeta.JobMeta* value (Phase=1, Status=2, Route=3, Timeout=4, Known=5, HasBlobResult=6, BlobResultSize=7).
Return value

The value matching the field. JobMetaKnown returns 0 on an unknown jobId (NOT a runtime error); other keys raise a runtime error.

Example
i64 $jobId;
$jobId = callbackworker.Start("Echo", $req, 5000);
printf("%d\n", callbackworker.JobMeta($jobId,
asyncmeta.JobMetaTimeout()));
printf("%d\n", callbackworker.JobMeta($jobId,
asyncmeta.JobMetaKnown()));
Output after running
5000
1
When to use

One uniform query on the job's state — with the exact keys from the asyncmeta vocabulary. If your code is portable across several backends, this form is the portable query.

callbackworker.Info

callbackworker.Info(jobId) -> string

Returns the job state's key=value diagnostic text in a single call.

Parameters
Parameter Type Description
jobId int The jobId.
Return value

A space-separated key=value list (keys are stable).

Example
i64 $jobId;
$jobId = callbackworker.Start("Echo", $req, 5000);
callbackworker.WaitComplete($jobId, 5000);
printf("%d\n", (str.Len(callbackworker.Info($jobId)) > 0));
Output after running
1
When to use

For detailed diagnostics in a single call — for logging or a developer interface. The keys are stable; easy to parse with str.* operations.

Practical notes

What the callbackworker plugin is good for

  • Offloading long-running work without blocking the main script thread (CPU-intensive callback, slow data processing).

  • Batch processing: several jobs started sequentially, the worker runs them in FIFO order.

  • Async result channel: the callback may modify the request blob in place, and the modification is visible in the response blob.

  • asyncmeta-compatible: Phase/Status/JobMeta use the shared vocabulary, so the code is portable to other backends.

Wait vs WaitComplete: which to use when?

Wait is one-step: it blocks and returns the response. Simple, but the job is DESTROYED afterward — you couldn't query the Status or other metadata beforehand. WaitComplete is two-step: it blocks and returns only 1/0. Afterward, Phase, Status, JobMeta are queryable, and Take/TakeBlob takes the response. If you want to check Status no matter what (and e.g. run different logic on error), WaitComplete is the choice. If you simply want to get the response and you know the job will succeed, Wait is simpler.

Cancel and running jobs

Cancel can only remove queued (not yet started) jobs — NOT running ones. If the callback must stop itself (e.g. an unbounded-time watching operation), the timeoutMs parameter gives the max run time: if it expires, the job closes with DOMIN_STATUS_TIMEOUT. Cancel returns 0 if the job is already running — this is not an error, just a state signal.

Memory management

Start internally COPIES the request blob — the script may freely use it afterward. The blob returned by Wait/Take/TakeBlob is owned by the script. The Wait + DestroyJob is automatic, so there's no leak. Close shuts down all pending jobs with DOMIN_STATUS_SHUTDOWN; those jobs are no longer accessible via Take.

Error handling

An invalid jobId, a wrong argument count or type, an out-of-range timeoutMs, and touching an already-closed plugin are reported by the runtime as a runtime error. A wait timeout (Wait) is DOMIN_STATUS_TIMEOUT; a Close-style shutdown is DOMIN_STATUS_SHUTDOWN. Take/TakeBlob only accept a completed (Phase=Completed) job — if not completed yet, a runtime error.

The callbackhttp HTTP listener plugin

Loopback or public HTTP server, request-driven callbacks, and route-level state control — complete function reference