# Module: `nupp.workers` Isolated worker threads. Each worker owns a fresh LuaJIT state on a native thread. Values cross only as bounded `string.buffer` messages, so neither Lua heap, module state, globals, closures, userdata, nor cdata are shared. Worker entry modules run from the same stamped payload as their spawner: ```nupp local workers = require("nupp.workers") do local worker = workers.spawn("jobs.hash") local answer = worker:call({bytes = contents}) end -- automatic stop ``` The entry obtains its endpoints independently: ```nupp local workers = require("nupp.workers") workers.current():serve(function(job: any): any return {length = #job.bytes} end) ``` A ready receive returns inline. A wait blocks efficiently in an ordinary program and suspends under an installed handler. Closing is cooperative: it wakes a worker blocked in `Self:receive`, but source that ignores the closed inbox can keep `join` and `stop` waiting indefinitely. ## Types ### `Exit` _record_ How a worker ended. ```nupp record workers.Exit succeeded: boolean status: integer error: string? end ``` #### Fields | Name | Type | Description | | --- | --- | --- | | `succeeded` | `boolean` | True when the entry module returned without an uncaught error. | | `status` | `integer` | Zero for a clean return and nonzero for a load or runtime failure. | | `error` | `string?` | The worker's load or runtime error, when it failed. | ### `Self` _record_ The worker-side endpoints. ```nupp record workers.Self inbox: Channel outbox: Channel receive: function(workers.Self): any? send: function(workers.Self, any) serve: function(workers.Self, function(any): any) end ``` #### Methods ##### `receive` Waits for and returns the next payload. Nil means the inbox closed and drained. ```nupp receive: function(workers.Self): any? ``` ###### Arguments | Name | Type | Description | | --- | --- | --- | | `?` | `workers.Self` | | ###### Returns | Type | Description | | --- | --- | | `any?` | | ##### `send` Sends an ordinary message to the spawner. ```nupp send: function(workers.Self, any) ``` ###### Arguments | Name | Type | Description | | --- | --- | --- | | `?` | `workers.Self` | | | `?` | `any` | | ##### `serve` Answers requests until the inbox closes. ```nupp serve: function(workers.Self, function(any): any) ``` ###### Arguments | Name | Type | Description | | --- | --- | --- | | `?` | `workers.Self` | | | `?` | `function(any): any` | | #### Fields | Name | Type | Description | | --- | --- | --- | | `inbox` | `Channel` | | | `outbox` | `Channel` | | ### `Worker` _record_ A fresh Lua state running on a native thread. ```nupp record workers.Worker _handle: any _inbox: Channel _outbox: Channel _closed: boolean _destroyed: boolean _exit: workers.Exit? _nextId: integer _pendingIds: {[integer]: boolean} _replies: {[integer]: Frame} _messages: {any} _firstMessage: integer _lastMessage: integer send: function(workers.Worker, any) tryReceive: function(workers.Worker): any? receive: function(workers.Worker, integer?): any? call: function(workers.Worker, any): any close: function(workers.Worker) join: function(workers.Worker): workers.Exit stop: function(workers.Worker): workers.Exit end ``` #### Methods ##### `send` Queues a copied value without waiting for capacity. ```nupp send: function(workers.Worker, any) ``` ###### Arguments | Name | Type | Description | | --- | --- | --- | | `?` | `workers.Worker` | | | `?` | `any` | | ##### `tryReceive` Takes a ready ordinary message without waiting. ```nupp tryReceive: function(workers.Worker): any? ``` ###### Arguments | Name | Type | Description | | --- | --- | --- | | `?` | `workers.Worker` | | ###### Returns | Type | Description | | --- | --- | | `any?` | | ##### `receive` Waits for an ordinary message, or up to `timeoutMs` when supplied. ```nupp receive: function(workers.Worker, integer?): any? ``` ###### Arguments | Name | Type | Description | | --- | --- | --- | | `?` | `workers.Worker` | | | `?` | `integer?` | | ###### Returns | Type | Description | | --- | --- | | `any?` | | ##### `call` Sends a request and waits for the matching reply. ```nupp call: function(workers.Worker, any): any ``` ###### Arguments | Name | Type | Description | | --- | --- | --- | | `?` | `workers.Worker` | | | `?` | `any` | | ###### Returns | Type | Description | | --- | --- | | `any` | | ##### `close` Closes the worker inbox. Nonblocking and idempotent. ```nupp close: function(workers.Worker) ``` ###### Arguments | Name | Type | Description | | --- | --- | --- | | `?` | `workers.Worker` | | ##### `join` Waits for the worker thread and records how it ended. ```nupp join: function(workers.Worker): workers.Exit ``` ###### Arguments | Name | Type | Description | | --- | --- | --- | | `?` | `workers.Worker` | | ###### Returns | Type | Description | | --- | --- | | `workers.Exit` | | ##### `stop` Closes, joins, and releases the worker. Idempotent. ```nupp stop: function(workers.Worker): workers.Exit ``` ###### Arguments | Name | Type | Description | | --- | --- | --- | | `?` | `workers.Worker` | | ###### Returns | Type | Description | | --- | --- | | `workers.Exit` | | ## Functions ### `workers.current` _function_ Returns the endpoints installed in the current worker state. ```nupp function workers.current(): workers.Self ``` #### Returns | Type | Description | | --- | --- | | `workers.Self` | | #### Raises - outside a worker state ### `workers.spawn` _function_ Starts `entry` in a fresh LuaJIT state. ```nupp function workers.spawn(entry: string): workers.Worker ``` #### Arguments | Name | Type | Description | | --- | --- | --- | | `entry` | `string` | | #### Returns | Type | Description | | --- | --- | | `workers.Worker` | an owned worker that is stopped on every structured exit |