Loads every key of the "configurations" and then the "services"
namespace of `store`, building the project's capsule configurations and
services -- see sig_config_load_configuration()/sig_config_load_service()
for the exact per-document schema (a trailing newline is fine). With the
file backend these are <base>/configurations/<name>.cfg and
<base>/services/<name>.cfg (see sig_persistence_file.h).
`store` and `modules` are borrowed and must outlive the returned
sig_project: the project saves and removes keys in `store` as it is
edited. `modules` is created and owned by the caller, with every
compiled-in sig_capsule registered before calling this.
A namespace that does not exist (or that the store reports as
SIG_ERR_NOT_FOUND) holds zero entries, not an error; a key that
vanishes between listing and loading is skipped. Any other failure to
list or load is SIG_ERR_PLATFORM (SIG_ERR_ALLOC for want of memory); a
document that does not validate is SIG_ERR_PARSE (SIG_ERR_NOT_FOUND for
an unregistered type, or an unknown configuration or receiver). Nothing
is started by this call -- see sig_project_start_auto(). On any failure,
everything built so far is torn down internally and *out is left
untouched; no partially built project is ever returned.
sig_project_destroy
void sig_project_destroy(sig_project * project)
Parameter
Type
project
sig_project *
Stops every service still running, then destroys every service's
instances, then every service, then every capsule configuration. Does not
touch `modules` -- that stays the caller's.
Calls sig_service_start on every service whose definition had
"auto_start": true. Best-effort across services, mirroring the
convention sig_capsule_instance_notify() already established for
multi-target operations: a failure starting one service does not
stop the others from being attempted; returns SIG_OK only if every
flagged service started successfully, otherwise the status of the
last one that failed.
Calls sig_service_stop on every service in the project, regardless
of how (or whether) it was started -- sig_service_stop is always a
safe no-op on a service that was never started. Same best-effort
convention as sig_project_start_auto.
Read-only introspection, safe from any thread once the project is
loaded (the service table is only mutated during sig_project_load()
and sig_project_destroy()). The sig_service handed to the callback
stays valid until sig_project_destroy(). Order is unspecified. A
non-SIG_OK return from fn stops the walk and becomes its result.
---- Editing -------------------------------------------------------
The project keeps the JSON definition of every configuration and
service. These functions change definitions and persist them to the
project's store under the key <name> in the "configurations" or
"services" namespace, saved as the document followed by one newline
(the file backend writes each key atomically). A document is
validated exactly as sig_project_load() would; on any failure nothing
is saved and nothing changes.
A running service is never disturbed: its instances keep borrowing the
configurations they were built from (a replaced configuration is retired, not
freed, until sig_project_destroy). See sig_project_service_dirty().
Names must match [A-Za-z0-9_-]{1,64}: SIG_ERR_INVALID_ARG otherwise.
An invalid document -- bad JSON, wrong shape, unregistered type,
unknown configuration or receiver -- is SIG_ERR_PARSE. A failed store
operation is SIG_ERR_PLATFORM (SIG_ERR_ALLOC for want of memory);
removing a key the store no longer has is not a failure.
Not thread-safe on their own: callers serialize them with each other
and with service start/stop (sig_runtime_edit() does this).
Why the most recent put/patch was rejected, for a caller to show: a property
message from the capsule's table ("end: required", "step: must be >= 1"), or
"" when the failure has no more specific reason than the status. Cleared at the
start of every put/patch; valid until the next edit. Like the edit functions it
is serialized by sig_runtime_edit(). Never NULL.
Creates (*created = true) or replaces (*created = false) a configuration. The document is
also validated against its capsule's property table (see sig_property).
JSON Merge Patch (sig_value_merge_patch semantics; null is rejected
with SIG_ERR_PARSE) applied to the stored definition. SIG_ERR_NOT_FOUND
if the configuration does not exist.
Renames a configuration, and the references to it in every service
definition that uses it (the services are saved again, as compact
JSON). A running service is left running; like any other edit to what it
uses, the rename makes it dirty until it is restarted. Stopped services
are rebuilt under the new name straight away. SIG_ERR_NOT_FOUND if `from`
does not exist, SIG_ERR_EXISTS if `to` does (or equals `from`),
SIG_ERR_INVALID_ARG for an invalid name. The configuration is validated
like a put. The rename is a put of the new name, a put of each service,
then a delete of the old name, so the project and the store agree after
every step. On a failure those steps are undone, newest first, and the
project is as it was. If the store keeps failing, the undo can stop
part way: then both names exist and each service uses one of them --
a project that runs and loads as it stands.
Creates (*created = true) or replaces (*created = false) a service
definition. Replacing a RUNNING service only changes its definition;
the live service keeps running unchanged and is reported dirty. A
stopped service is rebuilt from the new definition immediately.
Creates (*created = true) or replaces (*created = false) a service
definition. Replacing a RUNNING service only changes its definition;
the live service keeps running unchanged and is reported dirty. A
stopped service is rebuilt from the new definition immediately.
out is true when the service's definition, or the definition of a
configuration it uses, changed after the live service was built -- i.e. a
restart would pick up something new.
If the service is stopped and dirty, rebuilds the live service from
its definition (invalidating any earlier sig_service pointer for it).
A running service is left alone. *out is the current live service.