I have seen this pattern in a number of SmartThings drivers, and even do it myself in one spot, but I wanted to double-check whether it’s actually safe long-term with cosock.
When using cosock.channel, you can create channels to pass data between threads
local channel = require 'cosock.channel'
local reply_tx, reply_rx = channel.new()
-- ... some other coroutine.......
reply_tx:send(table.pack(my_object))
-- ................................
local packed = reply_rx:receive()
local same_object = table.unpack(packed)
From what I can tell, table.pack creates a shallow wrapper table, and cosock appears to pass the original object reference across the channel. This means the receiving side ends up with what looks like the same object (including metatables in my testing).
I think any future use of my_object on the send side risks concurrency issues after that object reference has been sent in that wrapping table.
However, I’m concerned this might be fragile:
- Once the object has been sent, is it safe to continue using it on the sending side?
- Are there hidden concurrency issues if the object contains sockets, timers, or other non-serializable state?
- Should we be explicitly serializing the object instead of relying on this behavior?
It’s clearly working as-is in a number of drivers, but I question how fragile it may be depending on what’s inside my_object
@nayelyz Can you have one of the devs confirm this?
Thanks