# 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 |