Changelog
Released versions of the runstate TypeScript and Python SDKs and what changed in each.
Both SDKs are published as runstate-sdk (npm and PyPI), MIT licensed, and versioned together.
npm install runstate-sdkpip install runstate-sdkThese docs describe version 0.3.0. It works against the current hosted API (https://api.getrunstate.com).
0.3.0 replaces the whole SDK surface in both languages. You wrap a function once where you define it and call it as before; runstate does the coordination inside the call. There is no compatibility layer: the 0.2 names are gone, so upgrading means updating your code with the table below.
- New surface:
once,limit,take,slots,budget,queue(withsend,gatherandserve, and producer-only queues without a handler),setup,sleep,together,run,child,runId,stop,finish,context,eventsandstatus, on a default client (import runstate from 'runstate-sdk',import runstate) or aRunstateinstance. See the TypeScript and Python references. - Runs are implicit. Every process joins the run named by
RUNSTATE_RUN(default), or the one you name withrunstate.run(name). You never pass run ids. - Default API address. The SDKs now connect to
https://api.getrunstate.comunlessRUNSTATE_BASE_URLsays otherwise. - Durations are seconds, or strings such as
'30s'and'10m'. Amounts are numbers or decimal strings. - Resources are declared in code.
max,perandlimitcreate a limit, slots or a budget the first time, and check the sizes after that. - Python: decorators work on plain and
async deffunctions. Every module function has ana-prefixed async form (astop,atake,aserve, …), which replacesAsyncRunstate. - Errors: a smaller set of classes:
ConfigError,AuthError,StoppedError,TimeoutError,OnceFailedError,TaskFailedError,BudgetExceededError,ResultTooLargeError,ConflictError,LeaseLostErrorandUnavailableError. Busy resources and rate limits are retried inside the SDK. See Errors & retries. - Removed: the TypeScript low-level client, the admin accessors for declaring resources (use
setup()or the sizes on each wrapper), manual reservations and deliveries, run handles, task groups, timer and rendezvous handles, and diagnostics. The HTTP API still exposes everything for other languages and custom tooling.
Migrating from 0.2
Section titled “Migrating from 0.2”| 0.2 | 0.3 |
|---|---|
const run = await new Runstate().scopes.create() |
nothing (runs are implicit) or runstate.run('name') |
run.claim(k).run(fn) |
runstate.once(fn)(...args) |
run.quota('q').take() |
runstate.take('q') or runstate.limit('q', fn) |
run.pool('p').run(fn) |
runstate.slots('p', fn) |
run.budget('b').reserve(...) + settle / void |
runstate.budget('b', fn, { reserve, cost }) |
bus.mailboxes.ensure + mailbox.submit + consume |
runstate.queue(name, handler), queue(input), runstate.serve() |
run.groups.create(...) |
queue.gather(inputs, { need, accept }) |
run.timers.create(...).wait() |
runstate.sleep(name, duration) |
run.barriers.create(...), arrive, wait |
runstate.together(name, count) |
bus.events.watch |
runstate.events() |
bus.diagnostics.run(id) |
runstate.status() |
run.cancel() / run.complete() |
runstate.stop() / runstate.finish() |
Python follows the same table with decorators: @runstate.once, @runstate.limit(...), @runstate.slots(...), @runstate.budget(...) and @runstate.queue(...).
- Idle workers:
consume()long-polls (waitMs/wait_ms, default 20 s), so an idle worker makes a few requests a minute instead of polling everypollMs.receive()andadmit()accept a wait too. Empty waits and lease renewals don’t count toward the request rate. - Task groups:
group.close()andexpectedMembers/expected_members. AnN_ACCEPTEDgroup stays open until it is closed, reaches its expected members, or hits its deadline, and is only judged unreachable once closed.seal()is deprecated in favour ofclose(). - Runs:
scopes.create({ name })andchild({ name })store the name and return it in reads. - Admission: TypeScript
TaskRequirementsacceptsbudgetsandadmit()returnsreservations; Python exportsTaskRequirements,UnitsRequirementandBudgetRequirementtype hints. Pool units and the work-limit slot taken byadmit()are released when the task completes, is rejected or is retried (a server change; no SDK call needed). - Permissions: declaring a pool, quota, work limit or budget that already exists with matching sizes works with a key that may not create resources.
FORBIDDENis raised only when the resource does not exist.
- Python:
MailboxRef.receive()works. In 0.1.0 it raisedTypeErroron every call;consume()was not affected. - Both SDKs: waiting claim and pool acquisitions (
acquire({ wait: true }),run()) now also wait throughCONCURRENCY_LIMITED, retrying about once a second. - Both SDKs:
CONCURRENCY_LIMITEDandOPERATIONS_EXHAUSTEDmap toRateLimitError. - TypeScript low-level client: error codes are no longer collapsed to
UNAVAILABLEwhen the code was added to the contract after the client was written (for exampleINSUFFICIENT_BUDGET).
First public release of both SDKs: runs, claims, work queues and durable tasks, task groups, concurrency pools, shared quotas, work limits, budgets, barriers, timers, events and diagnostics; AsyncRunstate and the blocking Runstate client in Python; the low-level createRunstateClient in TypeScript.