What a namespace is
A namespace is a routing value that the engine stores with a function id and a worker name. It is not part of either value. For examplestate::get can exist as the same function id in default,
orders, and analytics namespaces.
The engine uses these registry keys:
(namespace, function_id)for functions.(namespace, worker_name)for workers.
The two namespaces an observer names
An observer names two functions, and each one resolves in a namespace:- The source’s
namespaceis where the observed function is found. Absent, it isdefaultforengine::*andconfiguration::*functions, and the observing worker’s namespace for every other function. - The target’s
namespaceis where the target runs when the source runs. Absent, it is the observing worker’s namespace.
default namespace. A worker in any namespace
observes engine::* and configuration::* sources without naming one. For observability::* and
stream::* sources, a worker in another namespace names namespace: "default".
Every other observed function resolves only in the observer’s namespace (the one it names, or the
observing worker’s): a worker in orders that observes http::on-request reaches the http worker
in orders, and names namespace: "default" to reach the one in default.
What namespaces enable
Namespaces let you ship one reusable worker package and deploy it for more than one tenant on the same engine. Each tenant can run a worker namedstate and expose state::get. The worker package
does not need tenant-specific names.
Why the namespace is not a prefix
iii does not changestate::get to orders/state::get. A function id is part of the worker
contract. It appears in schemas, skills, console output, commands, and documentation. A deployment
value must not change that contract.
The worker author defines the function id. The operator selects the namespace when they deploy the
worker. These two values stay separate.
Why routing is strict
A call withnamespace: "orders" resolves in orders only. A call with no namespace resolves in
the namespace of the calling worker.
The engine does not search other namespaces after a miss. A fallback could send a call to another
tenant. Instead, the engine returns function_not_found and lists the namespaces where the function
id exists.
The discovery functions are less strict when no namespace is present. For engine::functions::info
and engine::workers::info, a default entry has priority. If there is no default entry, a name
that exists in only one namespace resolves there. A name that exists in multiple namespaces returns
an ambiguity. An explicit namespace always uses strict resolution.
Why the engine rejects a collision
Only one live worker can own a worker name in a namespace. Only one live worker can own a function id in a namespace. The engine rejects a second owner instead of replacing the current owner. A worker-name conflict is fatal. The engine closes the new connection because the worker cannot use its declared identity. A function-id conflict rejects only that function. The worker stays connected and serves its other functions. Worker registration and function registration are separate operations. A connected worker does not confirm that all its functions are registered. The SDK reports a function conflict as a warning. A restart does not conflict with its own connection after teardown starts. The new connection can reclaim the same worker name.How a connection gets its namespace
A worker declares its namespace in theengine::workers::register call. The engine starts a
namespace timer when the WebSocket connection opens. The default timeout is 5000 ms.
A client can send registration messages before engine::workers::register. The engine holds
RegisterFunction, UnregisterFunction, RegisterService, Observe, and Unobserve messages
until it knows the namespace. It does not register them in default and move them later.
If engine::workers::register arrives first, the engine sets the declared namespace. An absent
value selects default. The engine then processes the held messages in arrival order.
If the timer expires first, the engine sets the connection namespace to default and processes the
held messages. A later worker registration cannot change that namespace.
To change the timeout, use registration_namespace_grace_ms or III_NAMESPACE_GRACE_MS. See
Registration namespace timeout.