redsun.services¶
Servers a session's devices talk to, and the processes behind them.
A session declares services with AsService and makes a Service for
each. A launched service is a child process the session starts and stops; an
attached one already runs elsewhere and only lends its devices their prefix.
A service process takes part in a session through the functions here: its
identity, readiness, logging, and when to stop.
STARTUP_TIMEOUT
module-attribute
¶
Seconds a launched service has to print its readiness line, unless the service gives its own.
STOP_TIMEOUT
module-attribute
¶
Seconds each step of Service.stop waits, unless the service gives its own.
Service
¶
Service(
name: str,
prefix: str = "",
module: str | None = None,
args: Sequence[str] | Mapping[str, ArgValue] = (),
ready: str | None = None,
stop_timeout: float = STOP_TIMEOUT,
transport: str = CHANNEL_ACCESS,
address: str | None = None,
startup_timeout: float = STARTUP_TIMEOUT,
)
A server devices talk to, and its process if the session owns it.
A container makes one per declared service. A service with a module is
launched as python -m <module> <args>; one without is attached to, runs
elsewhere, and start and stop do nothing. Each output line is logged
under redsun.service.<name>: as the record it describes if it is a JSON
log record, at DEBUG otherwise; see service_record.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
Name of the service. |
required |
prefix
|
str
|
Prefix given to each device naming the service. |
''
|
module
|
str | None
|
Module to run. |
None
|
args
|
Sequence[str] | Mapping[str, ArgValue]
|
Arguments following the module: a list, or a mapping of option names
to values, which |
()
|
ready
|
str | None
|
Text of the output line marking the service ready. |
None
|
stop_timeout
|
float
|
Seconds each step of |
STOP_TIMEOUT
|
transport
|
str
|
Protocol the service is reached over: |
CHANNEL_ACCESS
|
address
|
str | None
|
Where an attached service answers, added to this process's address
list when it starts. |
None
|
startup_timeout
|
float
|
Seconds |
STARTUP_TIMEOUT
|
Raises:
| Type | Description |
|---|---|
TypeError
|
If args are given without a module, or as text, or an address with a module. |
ValueError
|
If transport is not a protocol a session accepts. |
sig_exited
class-attribute
instance-attribute
¶
Emitted with the name and exit code when a ready service exits unasked.
It is emitted on the thread reading the service's output, service-<name>.
launched
property
¶
Whether the session launches this service rather than attaching to it.
start
¶
Launch the service and wait until it prints its readiness line.
The process runs without a console window on Windows, and its
transport gives it the environment it is reached on and tells this
process where to look, so devices find it among several local
services. What a transport reserves lasts for every start in this
process. The process learns its name, prefix, ready text and the
level this session records at through the functions of
redsun.services, so a module serving several sessions needs no
arguments for them. The process
writes UTF-8, and each output line is logged as service_record
rebuilds it. An attached service only adds its address to this
process's list, if it names one.
Raises:
| Type | Description |
|---|---|
TimeoutError
|
If the readiness line does not appear within |
RuntimeError
|
If the process exits before it is ready. |
stop
¶
Stop the launched process, escalating until it exits.
First its standard input is closed, the one request that lets a service
clean up on every platform. On POSIX a service still running after
stop_timeout gets SIGINT; one still running after that, or after
the first step on Windows, is killed.
ServiceIdentity
dataclass
¶
identity
¶
Return the name and prefix the session gave this process.
None when no session launched it, so a service run on its own falls back
on defaults of its own.
ready
¶
Print the text the session waits for before it counts this service ready.
The text is the one the service's declaration gives. Without one, nothing is printed: the session does not wait then.
ready_when_reachable
async
¶
Call ready once pv answers over PVAccess.
For a server that prints no line of its own once it serves. pv is
looked for on the loopback, where a launched service listens; it needs
p4p, which a service serving PVAccess already has. A failed attempt
other than a timeout is logged as a warning and retried.
serve_controller
async
¶
serve_controller(
controller: Controller,
transport: Transport,
prefix: str | None = None,
) -> None
Serve controller over transport until the session asks this service to stop.
prefix defaults to the one the session gave this process, and one trailing
colon is taken off it, so a device given STAGE: finds a controller served
as STAGE. The service is ready once its transport is reachable: a
transport with a reachable method is awaited on it, any other is asked for
the PV <prefix>:PVI.
Raises:
| Type | Description |
|---|---|
ValueError
|
If there is no prefix, given or from a session. |
wait_for_stop
async
¶
Return once the session asks this service to stop.
The session asks by closing standard input, which a daemon thread watches, so a service ending for another reason is not held up by it. When no session launched the process, this waits until cancelled and watches nothing: standard input may be closed from the start there.
stop_on_request
¶
Raise SIGINT in this process once the session asks it to stop.
For a server whose run blocks: it shuts down as it would on Ctrl+C.
Does nothing when no session launched the process.
The request can come as soon as the session reads the ready text, so a
service that prints it with ready and handles
the interrupt itself calls ready inside the block that handles it.
configure_logging
¶
Log at the session's level, in lines the session rebuilds into records.
Records of logging and, when it is installed, of loguru go to
standard output as JSON, each keeping its level, time, logger name and
traceback. The level is the one the session records at, INFO when no
session launched the process. The handlers already on the root logger, the
redsun logger and loguru are replaced, so none of their records is
written twice.