@memberjunction/work-queue-samples
Sample handlers for trying the MemberJunction durable work queue end to end without writing code first. The
package ships one handler, HelloWorldHandler, registered under the HandlerKey samples.hello. It is inert
unless a subscription names that key.
Try it in ten minutes
Section titled “Try it in ten minutes”-
Seed the sample topology (one topic, three subscriptions — one per partition mode) into your development database. It lives under
metadata-optional/, so it is never part of a normalmj sync push:Terminal window mj sync push --dir=metadata-optional/work-queue-samplesYou get topic
samples.hello(external publishing allowed) and subscriptionssamples.hello-log(None),samples.hello-exclusive(Exclusive) andsamples.hello-ordered(Ordered), all onHandlerKey = samples.hello. -
Publish a message from your machine (MJ-code path, no API key needed):
Terminal window mj queue publish --topic samples.hello --payload '{"name":"Paul"}'mj queue statsEvery publish fans out to all three subscriptions, so
statsshows Pending = 1 on each. -
Run the work. Either as a one-shot container job from the CLI:
Terminal window mj queue work --subscription samples.hello-log --onceor inside MJAPI, by enabling the host in
mj.config.cjs(workQueue: { enabled: true, systemUserEmail: '<an existing user>' }) and restarting it. The handler logsHello, Paul!with the delivery details. -
Exercise the queue’s behaviours from the same topic — the payload fields drive them:
Payload What you see {"sleepMs": 60000}The delivery stays InFlightfor a minute.mj queue discard --subscription samples.hello-log --delivery <id> --reason "cancel"stops it early: the handler’s Signal aborts withCancelledand the row isDiscarded{"fail": "fatal"}Dead-letters immediately. mj queue dead-letters --subscription samples.hello-log, thenmj queue replay …{"fail": "transient"}Retries with backoff (2 s, 4 s, …) until MaxAttempts(3), then dead-letters{"failUntilAttempt": 2}Fails attempt 1 on purpose and succeeds on attempt 2: a retry that recovers --partition-key k1 --count 3On samples.hello-exclusivethe three run one at a time; onsamples.hello-orderedthey run in publish order, and afail: "fatal"head blocks the key untilmj queue replay(mj queue partitions --subscription samples.hello-ordered --condition Blocked)--dedup-key evt-1twiceThe second publish reports Duplicatenaming the first message -
Publish from outside MJ through the REST endpoint (enable
WorkQueueServerExtensioninmj.config.cjsserverExtensionsand use an API key with theworkqueue:publishscope):Terminal window curl -X POST http://localhost:4000/work-queue/topics/samples.hello/messages \-H "x-api-key: mj_sk_…" -H "Content-Type: application/json" \-d '{"messages":[{"payload":{"name":"REST"}}]}' -
Remove the samples when done: delete the three subscriptions and the topic through Explorer or
mj sync(their deliveries and messages are driver-owned rows; the retention sweeper purges settled ones, and pending ones can be discarded withmj queue discard).
Moving the sample to another transport
Section titled “Moving the sample to another transport”The handler and the CLI commands are transport-neutral. To run the same demo on a cloud transport once one is
installed, point samples.hello’s TransportID at that transport’s row and re-run the steps above; nothing in
this package changes.
Writing your own handler
Section titled “Writing your own handler”Copy HelloWorldHandler: extend BaseWorkHandler<TPayload> from @memberjunction/work-queue-engine, decorate
with @RegisterClass(BaseWorkHandler, '<your.key>'), and make sure the package is in the host’s class manifest
(mj codegen manifest) so the ClassFactory can resolve the key. The engine README’s “Writing a handler” section
and the consumer guide (guides/WORK_QUEUE_CONSUMER_GUIDE.md) cover idempotency, long-running work and the
abort reasons.