Initial commit

This commit is contained in:
Emery Hemingway 2022-03-14 20:44:22 -05:00
commit 3b3b7b8f8f
3 changed files with 83 additions and 0 deletions

1
README.md Normal file
View File

@ -0,0 +1 @@
An example of communicating with the Yggdrasil control socket over Syndicate.

69
src/yggdrasilctl.nim Normal file
View File

@ -0,0 +1,69 @@
# SPDX-FileCopyrightText: ☭ 2022 Emery Hemingway
# SPDX-License-Identifier: Unlicense
import std/[asyncdispatch, asyncnet, json, streams, tables]
from std/nativesockets import AF_UNIX, SOCK_STREAM, Protocol
import preserves, preserves/jsonhooks
import syndicate, syndicate/capabilities
type
Controller = ref object
ds: Ref
facet: Facet
handles: Table[JsonNode, Handle]
sock: AsyncSocket
Yggdrasilctl {.preservesRecord: "yggdrasilctl".} = object
label: string
payload: JsonNode
proc dispatchReplies(ctl: Controller) =
if not ctl.sock.isClosed:
ctl.sock.recv(4096).addCallback do (fut: Future[string]):
if fut.failed:
close(ctl.sock)
raise fut.error
var str = newStringStream(fut.read)
for js in parseJsonFragments(str):
if js["status"].getStr == "success":
run(ctl.facet) do (turn: var Turn):
var req = js["request"]
for label, val in js["response"].pairs:
var resp = Yggdrasilctl(label: label, payload: val)
ctl.handles[req] =
replace(turn, ctl.ds, ctl.handles.getOrDefault(req), resp)
callSoon: dispatchReplies(ctl)
proc connectController(facet: Facet; ds: Ref; socketPath: string): Future[Controller] {.async.} =
var sock = newAsyncSocket(
domain = AF_UNIX,
sockType = SOCK_STREAM,
protocol = cast[Protocol](0),
buffered = false)
await connectUnix(sock, socketPath)
let ctl = Controller(ds: ds, facet: facet, sock: sock)
dispatchReplies(ctl)
return ctl
proc request(ctl: Controller; req: string; fields: JsonNode): Future[void] =
var js = %* { "keepalive": true, "request": req, "fields": fields }
ctl.sock.send($js)
proc mint(): SturdyRef =
var key: array[16, byte]
mint(key, "syndicate")
bootDataspace("main") do (ds: Ref; turn: var Turn):
let ctl = waitFor connectController(turn.facet, ds, "/run/yggdrasil/yggdrasil.sock")
onMessage(turn, ds, ?Yggdrasilctl) do (label: string, fields: JsonNode):
asyncCheck ctl.request(label, fields)
onPublish(turn, ds, ?Yggdrasilctl) do (label: string, resp: JsonNode):
stderr.writeLine label, ": ", resp.pretty
# yggdrasil response test
message(turn, ds, Yggdrasilctl(label: "getself", payload: newJObject()))
# yggdrasil request test
for _ in 0..7: poll()

13
yggdrasilctl.nimble Normal file
View File

@ -0,0 +1,13 @@
# Package
version = "0.1.0"
author = "Emery Hemingway"
description = "An example of communicating with the Yggdrasil control socket over Syndicate"
license = "Unlicense"
srcDir = "src"
bin = @["yggdrasilctl"]
# Dependencies
requires "nim >= 1.6.4"