Capy-Bearer Documentation

service_send

lib call

Capy

function service_send(unit : string, signal : string, props : as any = {}, delay_ms : u64 = 0) bool

Description

service_send() posts a message to a service and returns at once. It never waits for the service. When the service is listening, the send is one datagram and touches nothing else. When it is not running, the send records that it should run, spools the message under the state lock, and the message is delivered after SERVICE:START returns. Callers therefore never check whether a service is up.

Acceptance does not prove that a handler exists or that it completed. Props cross a serialization boundary and do not share memory with the caller. Signal names are case-sensitive. Pass ASSIGN, not SERVICE:ASSIGN.

Messages from one sender enter the queue in send order. A delayed message can be overtaken by a later message that is already due. The bound is the kernel's datagram queue, about 500 frames per service: a full queue makes the send return false instead of waiting. Messages the service holds for a delay, and messages spooled while it was not running, are not counted against that queue.

delay_ms is the one-shot timer. A service that sends to itself with a delay gets a retry or a backoff without any other timer facility; service_every() covers fixed intervals. A message with the name STOP calls service_stop() directly. It ignores props and delay_ms, and does not start a stopped service.

Parameters

unit : the unit path of the service

signal : the handler name; the service runs SERVICE:<signal> with the props

props : the message, received as the handler's props

delay_ms : how long to hold the message before delivery; zero delivers at once

Return Values

true when the message was accepted for delivery; false for a full mailbox, an oversized message, or a missing unit

Errors

Mailbox setup, spool, lock, and state-file failures trap instead of returning false.

A message larger than a datagram is refused and the call returns false. A signal the unit does not define is dropped by the service and logged.

Example

Capy

var agents := {}

function spawn_agent() bool
{
	var agent := port_spawn(["pi", "--mode", "rpc"], cwd: "workspace", env: { "HOME": "/srv/agents" })
	if agent == 0
	{
		return false
	}
	agents[string(agent)] = agent
	-> true
}

function SERVICE:START(props : any)
{
	if !spawn_agent()
	{
		service_send(string(request.unit), "RESPAWN", {}, 2000)
	}
}

function SERVICE:RESPAWN(props : any)
{
	if !spawn_agent()
	{
		service_send(string(request.unit), "RESPAWN", {}, 2000)
	}
}

function SERVICE:EXIT(props : any)
{
	delete(agents, string(props.port))
	service_send(string(request.unit), "RESPAWN", {}, 2000)
}

function SERVICE:STOP(props : any)
{
	for agent := agents
	{
		port_close(u64(agent))
	}
}