Add <connected "…"> assertion to json_socket_translator
This commit is contained in:
parent
2fe54f44bb
commit
3a3fc0db2d
|
@ -6,7 +6,9 @@ Wrapper that executes a command, parses its JSON output, and asserts a Preserves
|
||||||
|
|
||||||
## json_socket_translator
|
## json_socket_translator
|
||||||
|
|
||||||
Utility to communicate with sockets that send and receive lines of JSON. Compatible with [mpv](https://mpv.io/), see [mpv.config-example.pr](./mpv.config-example.pr).
|
Utility to communicate with sockets that send and receive lines of JSON using `<sen-json …>` and `<recv-json …>` messages. Compatible with [mpv](https://mpv.io/), see [mpv.config-example.pr](./mpv.config-example.pr).
|
||||||
|
|
||||||
|
Do not send messages immediately to the dataspace passed `json_socket_translator`, wait until it asserts `<connected @socketPath string>`.
|
||||||
|
|
||||||
## msg
|
## msg
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,8 @@ JsonTranslatorArguments = {
|
||||||
dataspace: #!any
|
dataspace: #!any
|
||||||
}.
|
}.
|
||||||
|
|
||||||
|
JsonTranslatorConnected = <connected @path string>.
|
||||||
|
|
||||||
JsonSocketTranslatorArguments = {
|
JsonSocketTranslatorArguments = {
|
||||||
dataspace: #!any
|
dataspace: #!any
|
||||||
socket: string
|
socket: string
|
||||||
|
|
|
@ -1,39 +1,52 @@
|
||||||
? <mpv ?mpv> $mpv [
|
let ?socketPath = "/run/user/1000/mpv.sock"
|
||||||
|
let ?mpvSpace = dataspace
|
||||||
|
$mpvSpace [
|
||||||
|
; announce the dataspace when the translator is connected
|
||||||
|
? <connected $socketPath> [
|
||||||
|
$config <mpv $mpvSpace>
|
||||||
|
]
|
||||||
|
|
||||||
|
; translate <play-file …> to an MPV command
|
||||||
?? <play-file ?file> [
|
?? <play-file ?file> [
|
||||||
! <send-json { "command": ["loadfile" $file "append-play"] }>
|
! <send-json { "command": ["loadfile" $file "append-play"] }>
|
||||||
]
|
]
|
||||||
|
|
||||||
?? <recv-json ?js> [ $log ! <log "-" { mpv: $js }> ]
|
; clear the playlist on idle so it doesn't grow indefinitely
|
||||||
|
?? <recv-json {"event": "idle"}> [
|
||||||
|
! <send-json { "command": ["playlist-clear"] }>
|
||||||
|
]
|
||||||
|
|
||||||
|
; log anything that comes back from MPV
|
||||||
|
?? <recv-json ?js> [ $log ! <log "-" { mpv: $js }> ]
|
||||||
]
|
]
|
||||||
|
|
||||||
|
; need the translator and the translator needs the daemon
|
||||||
<require-service <daemon mpv-translator>>
|
<require-service <daemon mpv-translator>>
|
||||||
<depends-on <daemon mpv-translator> <service-state <daemon mpv> ready>>
|
<depends-on <daemon mpv-translator> <service-state <daemon mpv-server> ready>>
|
||||||
|
|
||||||
let ?socketPath = "/run/user/1000/mpv.sock"
|
|
||||||
|
|
||||||
<daemon mpv {
|
|
||||||
argv: [
|
|
||||||
"/run/current-system/sw/bin/mpv"
|
|
||||||
"--really-quiet"
|
|
||||||
"--idle=yes"
|
|
||||||
"--no-audio-display"
|
|
||||||
"--input-ipc-server=/run/user/1000/mpv.sock"
|
|
||||||
]
|
|
||||||
protocol: none
|
|
||||||
}>
|
|
||||||
|
|
||||||
<daemon mpv-translator {
|
|
||||||
argv: "/home/emery/src/bin/json_socket_translator"
|
|
||||||
protocol: application/syndicate
|
|
||||||
}>
|
|
||||||
|
|
||||||
let ?mpvSpace = dataspace
|
|
||||||
? <service-object <daemon mpv-translator> ?cap> [
|
? <service-object <daemon mpv-translator> ?cap> [
|
||||||
$cap {
|
$cap {
|
||||||
dataspace: $mpvSpace
|
dataspace: $mpvSpace
|
||||||
socket: $socketPath
|
socket: $socketPath
|
||||||
}
|
}
|
||||||
<mpv $mpvSpace>
|
]
|
||||||
|
|
||||||
|
; assert and retract the daemon as the daemon is built (this is a testing artifact)
|
||||||
|
? <built "json_socket_translator" ?path ?sum> [
|
||||||
|
<daemon mpv-server {
|
||||||
|
argv: [
|
||||||
|
"/run/current-system/sw/bin/mpv"
|
||||||
|
"--really-quiet"
|
||||||
|
"--idle=yes"
|
||||||
|
"--no-audio-display"
|
||||||
|
"--input-ipc-server=/run/user/1000/mpv.sock"
|
||||||
|
]
|
||||||
|
protocol: none
|
||||||
|
}>
|
||||||
|
|
||||||
|
<daemon mpv-translator {
|
||||||
|
argv: [$path]
|
||||||
|
protocol: application/syndicate
|
||||||
|
env: {BUILD_SUM: $sum}
|
||||||
|
}>
|
||||||
]
|
]
|
||||||
|
|
|
@ -16,19 +16,23 @@ runActor("main") do (root: Ref; turn: var Turn):
|
||||||
protocol = cast[Protocol](0),
|
protocol = cast[Protocol](0),
|
||||||
buffered = false,
|
buffered = false,
|
||||||
)
|
)
|
||||||
waitFor connectUnix(socket, socketPath)
|
addCallback(connectUnix(socket, socketPath), turn) do (turn: var Turn):
|
||||||
|
let a = JsonTranslatorConnected(path: socketPath)
|
||||||
|
discard publish(turn, ds, a)
|
||||||
|
|
||||||
let f = turn.facet
|
let socketFacet = turn.facet
|
||||||
proc processOutput(fut: Future[string]) {.gcsafe.} =
|
proc processOutput(fut: Future[string]) {.gcsafe.} =
|
||||||
run(f) do (turn: var Turn):
|
run(socketFacet) do (turn: var Turn):
|
||||||
var data = fut.read.parseJson.toPreserve
|
var data = fut.read.parseJson.toPreserve
|
||||||
message(turn, ds, initRecord("recv-json", data))
|
message(turn, ds, initRecord("recv-json", data))
|
||||||
|
socket.recvLine.addCallback(processOutput)
|
||||||
socket.recvLine.addCallback(processOutput)
|
socket.recvLine.addCallback(processOutput)
|
||||||
socket.recvLine.addCallback(processOutput)
|
|
||||||
|
|
||||||
onMessage(turn, ds, ?Input) do (data: Assertion):
|
onMessage(turn, ds, ?Input) do (data: Assertion):
|
||||||
var js: JsonNode
|
var js: JsonNode
|
||||||
if fromPreserve(js, data):
|
if fromPreserve(js, data):
|
||||||
asyncCheck(turn, send(socket, $js & "\n"))
|
asyncCheck(turn, send(socket, $js & "\n"))
|
||||||
else:
|
else:
|
||||||
writeLine(stderr, "cannot convert assertion to JSON - ", data)
|
writeLine(stderr, "cannot convert assertion to JSON - ", data)
|
||||||
|
do:
|
||||||
|
close(socket)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
|
|
||||||
import
|
import
|
||||||
std/typetraits, preserves
|
preserves
|
||||||
|
|
||||||
type
|
type
|
||||||
Output* {.preservesRecord: "recv-json".} = object
|
Output* {.preservesRecord: "recv-json".} = object
|
||||||
|
@ -9,6 +9,9 @@ type
|
||||||
JsonTranslatorArguments* {.preservesDictionary.} = object
|
JsonTranslatorArguments* {.preservesDictionary.} = object
|
||||||
`dataspace`* {.preservesEmbedded.}: Preserve[void]
|
`dataspace`* {.preservesEmbedded.}: Preserve[void]
|
||||||
|
|
||||||
|
JsonTranslatorConnected* {.preservesRecord: "connected".} = object
|
||||||
|
`path`*: string
|
||||||
|
|
||||||
JsonSocketTranslatorArguments* {.preservesDictionary.} = object
|
JsonSocketTranslatorArguments* {.preservesDictionary.} = object
|
||||||
`dataspace`* {.preservesEmbedded.}: Preserve[void]
|
`dataspace`* {.preservesEmbedded.}: Preserve[void]
|
||||||
`socket`*: string
|
`socket`*: string
|
||||||
|
@ -16,10 +19,12 @@ type
|
||||||
Input* {.preservesRecord: "send-json".} = object
|
Input* {.preservesRecord: "send-json".} = object
|
||||||
`field0`*: Preserve[void]
|
`field0`*: Preserve[void]
|
||||||
|
|
||||||
proc `$`*(x: Output | JsonTranslatorArguments | JsonSocketTranslatorArguments |
|
proc `$`*(x: Output | JsonTranslatorArguments | JsonTranslatorConnected |
|
||||||
|
JsonSocketTranslatorArguments |
|
||||||
Input): string =
|
Input): string =
|
||||||
`$`(toPreserve(x))
|
`$`(toPreserve(x))
|
||||||
|
|
||||||
proc encode*(x: Output | JsonTranslatorArguments | JsonSocketTranslatorArguments |
|
proc encode*(x: Output | JsonTranslatorArguments | JsonTranslatorConnected |
|
||||||
|
JsonSocketTranslatorArguments |
|
||||||
Input): seq[byte] =
|
Input): seq[byte] =
|
||||||
encode(toPreserve(x))
|
encode(toPreserve(x))
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# Package
|
# Package
|
||||||
|
|
||||||
version = "20230507"
|
version = "20230516"
|
||||||
author = "Emery Hemingway"
|
author = "Emery Hemingway"
|
||||||
description = "Utilites for Syndicated Actors and Synit"
|
description = "Utilites for Syndicated Actors and Synit"
|
||||||
license = "unlicense"
|
license = "unlicense"
|
||||||
|
|
Loading…
Reference in New Issue