The problem is not in my actors or in any other code I wrote, but has to do
with whatever the user might want to send through a channel. My example would
be just the same as your example: just two threads and a single channel. No
different from sending messages to actors through mailboxes.
At this time, we have no way of making sure that what gets sent through a
channel is safe to be received by a different thread. The user might send data
structures that are still referenced from elsewhere, but the the Nim type
system currently has no way to help with this.
Of course we can say "well, just don't do that", but that will not lead to safe
code.
Currently, `isolate[T]` is not helping; `isolate()` requires data to be
isolated at construction time, and `unsafeIsolate()` is just that: unsafe: is
not doing anything at all and gives the user the impression that the data is
isolated, when it might not be.
Let's make this concrete with the example below. It crashesh. I know it is
wrong. You know it is wrong. But the language is not protecting us in any way.
There are no `.gcsafe.` casts going on, or anything indicating that this is
wrong. Except of course that the only way to do this is by calling the function
`unsafeIsolate()`, which is unsafe.
import std / [json, isolation]
import threading / channels
type Thing = ref object
name: string
kid: Thing
var chan = newChan[Thing]()
var thr: Thread[void]
proc worker() {.thread.} =
var x: Thing
chan.recv(x)
echo "received ", x.repr
proc main() =
var t1 = Thing(name: "t1")
var t2 = Thing(name: "t2", kid: t1)
createThread thr, worker
chan.send unsafeIsolate(t2)
joinThread thr
echo "main: ", t1.repr
main()
Run