Start handlers at the Syndicate server
This commit is contained in:
parent
692c455f18
commit
9a301f487a
|
@ -0,0 +1,23 @@
|
||||||
|
; Copied from ../syndicate-rs/syndicate-server/protocols/schemas/externalServices.prs
|
||||||
|
version 1 .
|
||||||
|
|
||||||
|
Exec = <exec @argv CommandLine @restartPolicy RestartPolicy> .
|
||||||
|
|
||||||
|
CommandLine = @shell string / @full FullCommandLine .
|
||||||
|
FullCommandLine = [@program string @args string ...] .
|
||||||
|
|
||||||
|
RestartPolicy =
|
||||||
|
/ ; Whether the process terminates normally or abnormally, restart it
|
||||||
|
; without affecting any peer processes within the service.
|
||||||
|
=always
|
||||||
|
/ ; If the process terminates normally, leave everything alone; if it
|
||||||
|
; terminates abnormally, restart it without affecting peers.
|
||||||
|
@onError =on-error
|
||||||
|
/ ; If the process terminates normally, leave everything alone; if it
|
||||||
|
; terminates abnormally, restart the whole daemon (all processes
|
||||||
|
; within the daemon).
|
||||||
|
=all
|
||||||
|
/ ; Treat both normal and abnormal termination as normal termination; that is, never restart,
|
||||||
|
; and enter state "complete" even if the process fails.
|
||||||
|
=never
|
||||||
|
.
|
|
@ -0,0 +1,32 @@
|
||||||
|
|
||||||
|
import
|
||||||
|
std/typetraits, preserves
|
||||||
|
|
||||||
|
type
|
||||||
|
CommandLineKind* {.pure.} = enum
|
||||||
|
`shell`, `full`
|
||||||
|
CommandLineShell* = string
|
||||||
|
`CommandLine`* {.preservesOr.} = object
|
||||||
|
case orKind*: CommandLineKind
|
||||||
|
of CommandLineKind.`shell`:
|
||||||
|
`shell`*: CommandLineShell
|
||||||
|
|
||||||
|
of CommandLineKind.`full`:
|
||||||
|
`full`*: FullCommandLine
|
||||||
|
|
||||||
|
|
||||||
|
Exec* {.preservesRecord: "exec".} = object
|
||||||
|
`argv`*: CommandLine
|
||||||
|
`restartPolicy`*: RestartPolicy
|
||||||
|
|
||||||
|
`RestartPolicy`* {.preservesOr, pure.} = enum
|
||||||
|
`always`, `onError`, `all`, `never`
|
||||||
|
FullCommandLine* {.preservesTuple.} = object
|
||||||
|
`program`*: string
|
||||||
|
`args`* {.preservesTupleTail.}: seq[string]
|
||||||
|
|
||||||
|
proc `$`*(x: CommandLine | Exec | FullCommandLine): string =
|
||||||
|
`$`(toPreserve(x))
|
||||||
|
|
||||||
|
proc encode*(x: CommandLine | Exec | FullCommandLine): seq[byte] =
|
||||||
|
encode(toPreserve(x))
|
|
@ -1,15 +1,12 @@
|
||||||
# SPDX-FileCopyrightText: ☭ 2022 Emery Hemingway
|
# SPDX-FileCopyrightText: ☭ 2022 Emery Hemingway
|
||||||
# SPDX-License-Identifier: Unlicense
|
# SPDX-License-Identifier: Unlicense
|
||||||
|
|
||||||
import std/[asyncdispatch, deques, re, streams, strutils, osproc]
|
import std/[asyncdispatch, re]
|
||||||
import preserves
|
import preserves, syndicate
|
||||||
import syndicate
|
import ./protocol, ./exec
|
||||||
import ./protocol
|
|
||||||
|
|
||||||
bootDataspace("main") do (root: Ref; turn: var Turn):
|
bootDataspace("main") do (root: Ref; turn: var Turn):
|
||||||
var
|
var actions: seq[tuple[regex: Regex; cmd: string; args: seq[Assertion]]]
|
||||||
actions: seq[tuple[regex: Regex; cmd: string; args: seq[Assertion]]]
|
|
||||||
children: Deque[Process]
|
|
||||||
|
|
||||||
connectStdio(root, turn)
|
connectStdio(root, turn)
|
||||||
|
|
||||||
|
@ -26,12 +23,6 @@ bootDataspace("main") do (root: Ref; turn: var Turn):
|
||||||
during(turn, root, ?ListenOn[Ref]) do (a: Assertion):
|
during(turn, root, ?ListenOn[Ref]) do (a: Assertion):
|
||||||
let ds = unembed a
|
let ds = unembed a
|
||||||
onMessage(turn, ds, ?XdgOpen) do (uris: seq[string]):
|
onMessage(turn, ds, ?XdgOpen) do (uris: seq[string]):
|
||||||
while children.len > 0 and not children.peekFirst.running:
|
|
||||||
var child = children.popFirst()
|
|
||||||
if child.peekExitCode != 0:
|
|
||||||
stderr.writeLine child.errorStream.readAll
|
|
||||||
close child
|
|
||||||
# TODO check children on a timer?
|
|
||||||
for uri in uris:
|
for uri in uris:
|
||||||
var matched: bool
|
var matched: bool
|
||||||
for act in actions:
|
for act in actions:
|
||||||
|
@ -46,9 +37,13 @@ bootDataspace("main") do (root: Ref; turn: var Turn):
|
||||||
args[i] = uri
|
args[i] = uri
|
||||||
else:
|
else:
|
||||||
args[i] = replacef(uri, act.regex, "$" & $arg.int)
|
args[i] = replacef(uri, act.regex, "$" & $arg.int)
|
||||||
var child = startProcess(
|
message(turn, root, Exec(
|
||||||
command = act.cmd, args = args, options = {})
|
argv: CommandLine(
|
||||||
children.addLast child
|
orKind: CommandLineKind.full,
|
||||||
|
full: FullCommandLine(
|
||||||
|
program: act.cmd,
|
||||||
|
args: args)),
|
||||||
|
restartPolicy: RestartPolicy.never))
|
||||||
if not matched:
|
if not matched:
|
||||||
stderr.writeLine "no actions matched for ", uri
|
stderr.writeLine "no actions matched for ", uri
|
||||||
do:
|
do:
|
||||||
|
|
|
@ -11,6 +11,8 @@ let ?root_ds = dataspace
|
||||||
}>
|
}>
|
||||||
|
|
||||||
? <service-object <daemon uri_runner> ?cap> [
|
? <service-object <daemon uri_runner> ?cap> [
|
||||||
|
|
||||||
|
; send configuration to uri_runner
|
||||||
$cap [
|
$cap [
|
||||||
<listen-on $root_ds>
|
<listen-on $root_ds>
|
||||||
|
|
||||||
|
@ -29,4 +31,20 @@ let ?root_ds = dataspace
|
||||||
; filesystem paths are always prefixed with file://
|
; filesystem paths are always prefixed with file://
|
||||||
<action-handler "file://(.*.pdf)" ["/run/current-system/sw/bin/mupdf" 1]>
|
<action-handler "file://(.*.pdf)" ["/run/current-system/sw/bin/mupdf" 1]>
|
||||||
]
|
]
|
||||||
|
|
||||||
|
; uri_runner sends messages to the server to start handler applications
|
||||||
|
$cap ?? <exec ?argv ?restartPolicy> [
|
||||||
|
let ?id = timestamp
|
||||||
|
let ?facet = facet
|
||||||
|
let ?d = <uri_runner-exec $id $argv>
|
||||||
|
$config <run-service <daemon $d>>
|
||||||
|
$config <daemon $d {
|
||||||
|
argv: $argv,
|
||||||
|
readyOnStart: #f,
|
||||||
|
restart: $restartPolicy,
|
||||||
|
}>
|
||||||
|
$config ? <service-state <daemon $d> complete> [$facet ! stop]
|
||||||
|
$config ? <service-state <daemon $d> failed> [$facet ! stop]
|
||||||
|
]
|
||||||
|
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# Package
|
# Package
|
||||||
|
|
||||||
version = "0.3.2"
|
version = "0.4.0"
|
||||||
author = "Emery"
|
author = "Emery"
|
||||||
description = "A better xdg-open"
|
description = "A better xdg-open"
|
||||||
license = "Unlicense"
|
license = "Unlicense"
|
||||||
|
|
Loading…
Reference in New Issue