A service on this node
type Note {
Say { text: Str }
Count
Total { count: Int }
}
proc tally(state: Int, msg: Note, envelope: hive.syslink.Envelope): Int {
if msg is Note.Say(text) {
echo text
return state
} else if msg is Note.Count {
hive.syslink.answer(envelope, Note.Total(state))
return state + 1
}
return state
}
proc main(): void {
address := hive.syslink.spawn(tally, 0)
hive.syslink.register(#Cache, address)
async address(Note.Say("hi")) // fire and forget
reply := address(Note.Count()) with timeout 250 // send and wait, bounded
if reply is Result.Ok(msg) {
echo msg
}
}
The same service, truly distributed
type Note {
Say { text: Str }
HowMany
Counted { seen: Int }
}
proc inbox(seen: Int, note: Note, from: hive.syslink.Envelope): Int {
if note is Note.Say(text) {
echo "heard: {text}"
return seen + 1
} else if note is Note.HowMany {
hive.syslink.answer(from, Note.Counted(seen))
return seen
}
return seen
}
// Run this exact program on two machines: a node is identified by where it
// is, so nothing about the two processes differs but the addresses typed
// in below — 192.168.1.10:9100 and 192.168.1.11:9100, one each way round.
proc main(): void {
echo "This node's own ip:port?"
me := hive.term.read()
echo "The other node's ip:port?"
peer := hive.term.read()
if hive.syslink.listen(me) is Result.Error(err) {
panic err
}
box := hive.syslink.spawn(inbox, 0)
hive.syslink.register(#Inbox, box)
mine := hive.syslink.at(#Inbox)
theirs := hive.syslink.on(peer, #Inbox)
async theirs(Note.Say("hello from {me}"))
hive.task.sleep(500)
echo "peers connected: {len(hive.syslink.peers())}"
if theirs(Note.HowMany()) with timeout 4000 is Result.Ok(reply) {
echo "the other node answered: {reply}"
}
}