Start handlers at the Syndicate server

This commit is contained in:
Emery Hemingway 2022-05-19 11:58:47 -05:00
parent 692c455f18
commit 9a301f487a
5 changed files with 85 additions and 17 deletions

23
exec.prs Normal file
View File

@ -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
.

32
src/exec.nim Normal file
View File

@ -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))

View File

@ -1,15 +1,12 @@
# SPDX-FileCopyrightText: ☭ 2022 Emery Hemingway
# SPDX-License-Identifier: Unlicense
import std/[asyncdispatch, deques, re, streams, strutils, osproc]
import preserves
import syndicate
import ./protocol
import std/[asyncdispatch, re]
import preserves, syndicate
import ./protocol, ./exec
bootDataspace("main") do (root: Ref; turn: var Turn):
var
actions: seq[tuple[regex: Regex; cmd: string; args: seq[Assertion]]]
children: Deque[Process]
var actions: seq[tuple[regex: Regex; cmd: string; args: seq[Assertion]]]
connectStdio(root, turn)
@ -26,12 +23,6 @@ bootDataspace("main") do (root: Ref; turn: var Turn):
during(turn, root, ?ListenOn[Ref]) do (a: Assertion):
let ds = unembed a
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:
var matched: bool
for act in actions:
@ -46,9 +37,13 @@ bootDataspace("main") do (root: Ref; turn: var Turn):
args[i] = uri
else:
args[i] = replacef(uri, act.regex, "$" & $arg.int)
var child = startProcess(
command = act.cmd, args = args, options = {})
children.addLast child
message(turn, root, Exec(
argv: CommandLine(
orKind: CommandLineKind.full,
full: FullCommandLine(
program: act.cmd,
args: args)),
restartPolicy: RestartPolicy.never))
if not matched:
stderr.writeLine "no actions matched for ", uri
do:

View File

@ -11,6 +11,8 @@ let ?root_ds = dataspace
}>
? <service-object <daemon uri_runner> ?cap> [
; send configuration to uri_runner
$cap [
<listen-on $root_ds>
@ -29,4 +31,20 @@ let ?root_ds = dataspace
; filesystem paths are always prefixed with file://
<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]
]
]

View File

@ -1,6 +1,6 @@
# Package
version = "0.3.2"
version = "0.4.0"
author = "Emery"
description = "A better xdg-open"
license = "Unlicense"