Minor changes to service management

This commit is contained in:
Nocturn9x 2023-03-29 11:41:15 +02:00
parent 7b7b675fef
commit 142f8ad460
Signed by: nocturn9x
GPG Key ID: 8270F9F467971E59
1 changed files with 17 additions and 19 deletions

View File

@ -105,23 +105,21 @@ proc resolve(logger: Logger, node: Service): seq[Service] =
## list of services, treating it as a DAG ## list of services, treating it as a DAG
## (Directed Acyclic Graph) and builds a topologically ## (Directed Acyclic Graph) and builds a topologically
## sorted list such that a service appears in it only ## sorted list such that a service appears in it only
## after all of its dependencies and only ## after all of its dependencies and only before all of
## before all of its dependents. ## its dependents. This function is called iteratively by
## This function is called iteratively by resolveDependencies ## resolveDependencies handle the case where the dependency
## to handle detached subgraphs, which can occurr if one or ## graph is not fully connected. Nodes that have no dependencies
## more dependencies have common dependencies/dependents between ## and are not providers may be located anywhere in the list, as
## each other, but not with the rest of the graph. Nodes ## that does not invalidate the invariants described above. The
## that have no dependencies nor provide any ## algorithm comes from https://www.electricmonk.nl/log/2008/08/07/dependency-resolving-algorithm/
## service may be located anywhere in the list, ## and has been extended to support the dependent-provider
## as that does not invalidate the invariants ## paradigm. Note that it is not an error for a service in
## described above. The algorithm comes from ## a given runlevel to depend on services in other runlevels:
## https://www.electricmonk.nl/log/2008/08/07/dependency-resolving-algorithm/ ## when that occurs a warning is raised and the service in the
## and has been extended to support the dependent-provider paradigm. ## lower runlevel is promoted to the higher one (runlevels start
## Note that it is not an error for a service in a given runlevel to depend ## from 0), which means adding a module into a given runlevel
## on services in other runlevels: when that occurs a warning is raised and ## implicitly adds all of its dependencies to said runlevel as well,
## the service in the lower runlevel is promoted to the higher one (runlevels start from 0), ## regardless of what was specified in their unit file
## which means adding a module in a given runlevel implicitly adds all of its dependencies
## to said runlevel as well, regardless of what was specified in their unit file
if node.isResolved: if node.isResolved:
logger.debug(&"Dependency '{node.name}' has already been satisfied, skipping it") logger.debug(&"Dependency '{node.name}' has already been satisfied, skipping it")
return @[] return @[]
@ -132,7 +130,7 @@ proc resolve(logger: Logger, node: Service): seq[Service] =
if service.provider == node: if service.provider == node:
continue # Services implicitly provide themselves continue # Services implicitly provide themselves
if node.runlevel < service.provider.runlevel: if node.runlevel < service.provider.runlevel:
logger.warning(&"Service '{node.name}' in runlevel {node.runlevel} depends on '{service.provider.name}' in runlevel {service.provider.runlevel}, loading dependency regardless") logger.warning(&"Service '{node.name}' in runlevel {node.runlevel} depends on '{service.provider.name}' in runlevel {service.provider.runlevel}, loading both")
if not service.provider.isResolved: if not service.provider.isResolved:
if service.provider.isMarked: if service.provider.isMarked:
logger.warning(&"Cyclic dependency from '{node.name}' to '{service.provider.name}' detected while building dependency graph: skipping both") logger.warning(&"Cyclic dependency from '{node.name}' to '{service.provider.name}' detected while building dependency graph: skipping both")
@ -200,7 +198,6 @@ proc removeManagedProcess*(pid: int) =
proc addManagedProcess*(pid: int, service: Service) = proc addManagedProcess*(pid: int, service: Service) =
## Adds a managed process to the ## Adds a managed process to the
## table ## table
discard posix.setsid() # For cgroups support
processIDs[pid] = service processIDs[pid] = service
@ -319,6 +316,7 @@ proc startService(logger: Logger, service: Service) =
var arguments = split.words var arguments = split.words
let progName = arguments[0] let progName = arguments[0]
arguments = arguments[1..^1] arguments = arguments[1..^1]
discard posix.setsid() # For cgroups support
process = startProcess(progName, workingDir=service.workDir, args=arguments, options=if service.useParentStreams: {poParentStreams, poStdErrToStdOut} else: {poUsePath, poDaemon, poStdErrToStdOut}) process = startProcess(progName, workingDir=service.workDir, args=arguments, options=if service.useParentStreams: {poParentStreams, poStdErrToStdOut} else: {poUsePath, poDaemon, poStdErrToStdOut})
if service.supervised or service.kind != Oneshot: if service.supervised or service.kind != Oneshot:
var pid = posix.fork() var pid = posix.fork()