json_socket_translator: convert to gatekeeper protocol
This commit is contained in:
parent
1fd920f1c8
commit
a40cdbce2c
30
README.md
30
README.md
|
@ -88,8 +88,7 @@ $http [
|
||||||
### JSON Socket Translator
|
### JSON Socket Translator
|
||||||
|
|
||||||
Communicate with sockets that send and receive lines of JSON using `<send …>` and `<recv …>` messages.
|
Communicate with sockets that send and receive lines of JSON using `<send …>` and `<recv …>` messages.
|
||||||
|
Responds to the gatekeeper step `<json-socket-translator { socket: <unix "…"> / <tcp "…" … }> $resolver>`.
|
||||||
Do not send messages into the dataspace configure with `<json-socket-translator …>` until `<connected @socketPath string>` is asserted.
|
|
||||||
|
|
||||||
```
|
```
|
||||||
# MPV configuration example
|
# MPV configuration example
|
||||||
|
@ -107,25 +106,11 @@ Do not send messages into the dataspace configure with `<json-socket-translator
|
||||||
protocol: none
|
protocol: none
|
||||||
}>
|
}>
|
||||||
|
|
||||||
let ?mpvSpace = dataspace
|
let ?resolver = dataspace
|
||||||
|
$resolver ? <accepted ?mpvSpace> $mpvSpace [
|
||||||
? <service-state <daemon mpv-server> ready> [
|
|
||||||
<require-service <daemon syndesizer>>
|
|
||||||
? <service-object <daemon syndesizer> ?cap> [
|
|
||||||
$cap <json-socket-translator {
|
|
||||||
dataspace: $mpvSpace
|
|
||||||
socket: <unix "/run/user/1000/mpv.sock">
|
|
||||||
}>
|
|
||||||
]
|
|
||||||
]
|
|
||||||
|
|
||||||
$mpvSpace [
|
|
||||||
|
|
||||||
# announce the dataspace when the translator is connected
|
# announce the dataspace when the translator is connected
|
||||||
? <connected $socketPath> [
|
|
||||||
$config <mpv $mpvSpace>
|
$config <mpv $mpvSpace>
|
||||||
$config <bind <ref { oid: "mpv" key: #x"" }> $mpvSpace #f>
|
$config <bind <ref { oid: "mpv" key: #x"" }> $mpvSpace #f>
|
||||||
]
|
|
||||||
|
|
||||||
# translate <play-file …> to an MPV command
|
# translate <play-file …> to an MPV command
|
||||||
?? <play-file ?file> [
|
?? <play-file ?file> [
|
||||||
|
@ -137,6 +122,15 @@ $mpvSpace [
|
||||||
! <send { "command": ["playlist-clear"] }>
|
! <send { "command": ["playlist-clear"] }>
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
|
||||||
|
? <service-state <daemon mpv-server> ready> [
|
||||||
|
<require-service <daemon syndesizer>>
|
||||||
|
? <service-object <daemon syndesizer> ?cap> [
|
||||||
|
$cap <resolve <json-socket-translator {
|
||||||
|
socket: <unix "/run/user/1000/mpv.sock">
|
||||||
|
}> $resolver>
|
||||||
|
]
|
||||||
|
]
|
||||||
```
|
```
|
||||||
|
|
||||||
### JSON Stdio Translator
|
### JSON Stdio Translator
|
||||||
|
|
|
@ -19,8 +19,6 @@ JsonTranslatorArguments = <json-stdio-translator {
|
||||||
dataspace: #:any
|
dataspace: #:any
|
||||||
}>.
|
}>.
|
||||||
|
|
||||||
JsonTranslatorConnected = <connected @address SocketAddress>.
|
|
||||||
|
|
||||||
TcpAddress = <tcp @host string @port int>.
|
TcpAddress = <tcp @host string @port int>.
|
||||||
UnixAddress = <unix @path string>.
|
UnixAddress = <unix @path string>.
|
||||||
|
|
||||||
|
@ -34,8 +32,7 @@ HttpDriverArguments = <http-driver {
|
||||||
dataspace: #:any
|
dataspace: #:any
|
||||||
}>.
|
}>.
|
||||||
|
|
||||||
JsonSocketTranslatorArguments = <json-socket-translator {
|
JsonSocketTranslatorStep = <json-socket-translator {
|
||||||
dataspace: #:any
|
|
||||||
socket: SocketAddress
|
socket: SocketAddress
|
||||||
}>.
|
}>.
|
||||||
|
|
||||||
|
|
|
@ -40,16 +40,6 @@ type
|
||||||
Base64DecoderArguments* {.preservesRecord: "base64-decoder".} = object
|
Base64DecoderArguments* {.preservesRecord: "base64-decoder".} = object
|
||||||
`field0`*: Base64DecoderArgumentsField0
|
`field0`*: Base64DecoderArgumentsField0
|
||||||
|
|
||||||
JsonTranslatorConnected* {.preservesRecord: "connected".} = object
|
|
||||||
`address`*: SocketAddress
|
|
||||||
|
|
||||||
JsonSocketTranslatorArgumentsField0* {.preservesDictionary.} = object
|
|
||||||
`dataspace`* {.preservesEmbedded.}: EmbeddedRef
|
|
||||||
`socket`*: SocketAddress
|
|
||||||
|
|
||||||
JsonSocketTranslatorArguments* {.preservesRecord: "json-socket-translator".} = object
|
|
||||||
`field0`*: JsonSocketTranslatorArgumentsField0
|
|
||||||
|
|
||||||
XsltArgumentsField0* {.preservesDictionary.} = object
|
XsltArgumentsField0* {.preservesDictionary.} = object
|
||||||
`dataspace`* {.preservesEmbedded.}: EmbeddedRef
|
`dataspace`* {.preservesEmbedded.}: EmbeddedRef
|
||||||
|
|
||||||
|
@ -62,6 +52,12 @@ type
|
||||||
HttpDriverArguments* {.preservesRecord: "http-driver".} = object
|
HttpDriverArguments* {.preservesRecord: "http-driver".} = object
|
||||||
`field0`*: HttpDriverArgumentsField0
|
`field0`*: HttpDriverArgumentsField0
|
||||||
|
|
||||||
|
JsonSocketTranslatorStepField0* {.preservesDictionary.} = object
|
||||||
|
`socket`*: SocketAddress
|
||||||
|
|
||||||
|
JsonSocketTranslatorStep* {.preservesRecord: "json-socket-translator".} = object
|
||||||
|
`field0`*: JsonSocketTranslatorStepField0
|
||||||
|
|
||||||
WebhooksArgumentsField0* {.preservesDictionary.} = object
|
WebhooksArgumentsField0* {.preservesDictionary.} = object
|
||||||
`endpoints`*: Table[seq[string], EmbeddedRef]
|
`endpoints`*: Table[seq[string], EmbeddedRef]
|
||||||
`listen`*: Tcp
|
`listen`*: Tcp
|
||||||
|
@ -131,10 +127,9 @@ type
|
||||||
proc `$`*(x: WebsocketArguments | HttpClientArguments | JsonTranslatorArguments |
|
proc `$`*(x: WebsocketArguments | HttpClientArguments | JsonTranslatorArguments |
|
||||||
SocketAddress |
|
SocketAddress |
|
||||||
Base64DecoderArguments |
|
Base64DecoderArguments |
|
||||||
JsonTranslatorConnected |
|
|
||||||
JsonSocketTranslatorArguments |
|
|
||||||
XsltArguments |
|
XsltArguments |
|
||||||
HttpDriverArguments |
|
HttpDriverArguments |
|
||||||
|
JsonSocketTranslatorStep |
|
||||||
WebhooksArguments |
|
WebhooksArguments |
|
||||||
FileSystemUsageArguments |
|
FileSystemUsageArguments |
|
||||||
SqliteArguments |
|
SqliteArguments |
|
||||||
|
@ -153,10 +148,9 @@ proc encode*(x: WebsocketArguments | HttpClientArguments |
|
||||||
JsonTranslatorArguments |
|
JsonTranslatorArguments |
|
||||||
SocketAddress |
|
SocketAddress |
|
||||||
Base64DecoderArguments |
|
Base64DecoderArguments |
|
||||||
JsonTranslatorConnected |
|
|
||||||
JsonSocketTranslatorArguments |
|
|
||||||
XsltArguments |
|
XsltArguments |
|
||||||
HttpDriverArguments |
|
HttpDriverArguments |
|
||||||
|
JsonSocketTranslatorStep |
|
||||||
WebhooksArguments |
|
WebhooksArguments |
|
||||||
FileSystemUsageArguments |
|
FileSystemUsageArguments |
|
||||||
SqliteArguments |
|
SqliteArguments |
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
# SPDX-FileCopyrightText: ☭ Emery Hemingway
|
# SPDX-FileCopyrightText: ☭ Emery Hemingway
|
||||||
# SPDX-License-Identifier: Unlicense
|
# SPDX-License-Identifier: Unlicense
|
||||||
|
|
||||||
import std/[json, options]
|
import
|
||||||
import pkg/sys/[ioqueue, sockets]
|
std/[json, options],
|
||||||
import preserves, preserves/jsonhooks, syndicate
|
pkg/sys/[ioqueue, sockets],
|
||||||
|
pkg/preserves, pkg/preserves/jsonhooks,
|
||||||
import ../schema/[config, json_messages]
|
pkg/syndicate, pkg/syndicate/protocols/[gatekeeper, sturdy],
|
||||||
|
../schema/[config, json_messages]
|
||||||
|
|
||||||
template translateSocketBody {.dirty.} =
|
template translateSocketBody {.dirty.} =
|
||||||
# Template workaround for CPS and parameterized types.
|
# Template workaround for CPS and parameterized types.
|
||||||
|
@ -24,7 +25,8 @@ template translateSocketBody {.dirty.} =
|
||||||
whelp write(socket[], $data & "\n")
|
whelp write(socket[], $data & "\n")
|
||||||
else:
|
else:
|
||||||
stderr.writeLine "dropped send of ", data
|
stderr.writeLine "dropped send of ", data
|
||||||
discard publish(turn, ds, initRecord("connected", sa.toPreserves))
|
discard publish(turn, observer, ResolvedAccepted(responderSession: ds))
|
||||||
|
# Resolve the <json-socket-translator { }> step.
|
||||||
onStop(facet, kill)
|
onStop(facet, kill)
|
||||||
run(facet, setup)
|
run(facet, setup)
|
||||||
while alive:
|
while alive:
|
||||||
|
@ -45,33 +47,36 @@ template translateSocketBody {.dirty.} =
|
||||||
stderr.writeLine "close socket ", sa
|
stderr.writeLine "close socket ", sa
|
||||||
close(socket[])
|
close(socket[])
|
||||||
|
|
||||||
proc translateSocket(facet: Facet; ds: Cap; sa: TcpAddress) {.asyncio.} =
|
proc translateSocket(facet: Facet; sa: TcpAddress; ds, observer: Cap) {.asyncio.} =
|
||||||
var
|
var
|
||||||
socket = new AsyncConn[Protocol.Tcp]
|
socket = new AsyncConn[Protocol.Tcp]
|
||||||
conn = connectTcpAsync(sa.host, Port sa.port)
|
conn = connectTcpAsync(sa.host, Port sa.port)
|
||||||
socket[] = conn
|
socket[] = conn
|
||||||
translateSocketBody()
|
translateSocketBody()
|
||||||
|
|
||||||
proc translateSocket(facet: Facet; ds: Cap; sa: UnixAddress) {.asyncio.} =
|
proc translateSocket(facet: Facet; sa: UnixAddress; ds, observer: Cap) {.asyncio.} =
|
||||||
var
|
var
|
||||||
socket = new AsyncConn[Protocol.Unix]
|
socket = new AsyncConn[Protocol.Unix]
|
||||||
conn = connectUnixAsync(sa.path)
|
conn = connectUnixAsync(sa.path)
|
||||||
socket[] = conn
|
socket[] = conn
|
||||||
translateSocketBody()
|
translateSocketBody()
|
||||||
|
|
||||||
proc spawnJsonSocketTranslator*(turn: Turn; root: Cap): Actor {.discardable.} =
|
proc spawnJsonSocketTranslator*(turn: Turn; relay: Cap): Actor {.discardable.} =
|
||||||
|
let pat = Resolve?:{ 0: JsonSocketTranslatorStep.grabTypeFlat, 1: grab() }
|
||||||
spawnActor(turn, "json-socket-translator") do (turn: Turn):
|
spawnActor(turn, "json-socket-translator") do (turn: Turn):
|
||||||
during(turn, root, ?:JsonSocketTranslatorArguments) do (ds: Cap, sa: TcpAddress):
|
during(turn, relay, pat) do (sa: TcpAddress, observer: Cap):
|
||||||
linkActor(turn, "json-socket-translator") do (turn: Turn):
|
linkActor(turn, "json-socket-translator") do (turn: Turn):
|
||||||
|
let ds = turn.newDataspace()
|
||||||
discard trampoline:
|
discard trampoline:
|
||||||
whelp translateSocket(turn.facet, ds, sa)
|
whelp translateSocket(turn.facet, sa, ds, observer)
|
||||||
during(turn, root, ?:JsonSocketTranslatorArguments) do (ds: Cap, sa: UnixAddress):
|
during(turn, relay, pat) do (sa: UnixAddress, observer: Cap):
|
||||||
linkActor(turn, "json-socket-translator") do (turn: Turn):
|
linkActor(turn, "json-socket-translator") do (turn: Turn):
|
||||||
|
let ds = turn.newDataspace()
|
||||||
discard trampoline:
|
discard trampoline:
|
||||||
whelp translateSocket(turn.facet, ds, sa)
|
whelp translateSocket(turn.facet, sa, ds, observer)
|
||||||
|
|
||||||
when isMainModule:
|
when isMainModule:
|
||||||
import syndicate/relays
|
import syndicate/relays
|
||||||
runActor("main") do (turn: Turn):
|
runActor("main") do (turn: Turn):
|
||||||
resolveEnvironment(turn) do (turn: Turn; ds: Cap):
|
resolveEnvironment(turn) do (turn: Turn; relay: Cap):
|
||||||
spawnJsonSocketTranslator(turn, ds)
|
spawnJsonSocketTranslator(turn, relay)
|
||||||
|
|
Loading…
Reference in New Issue