I have the following code in an actor singleton, in an async method:
actor FurnaceManager {
var modbus: …
func start() async throws {
self.app.eventLoopGroup.next().scheduleRepeatedTask(initialDelay: .zero, delay: .seconds(5))
{ inTask in
do
{
// Connect MODBUS…
self.app.logger.info("Attempting to connect to MODBUS")
try self.modbus.connect()
self.app.logger.info("Connected to MODBUS")
inTask.cancel() // Don’t try to connect again
}
catch let e
{
self.app.logger.critical("Unabled to connect to MODBUS, \(e), trying again after delay…")
}
}
}
I get a warning "Actor-isolated property 'modbus' can not be referenced from a Sendable closure" on the try self.modbus.connect() call. modbus is a class instance.
What's the best way to address this? Should I make another method on FurnaceManager to wrap the connect() call, and call that with await?
Yes, there’s no reason I need the event loop. Your proposed solution works very well, thank you. IIUC, the only need for the connectTask property is to avoid creating two tasks if start() is called multiple times, is that right?
When I first wrote that bit of code, structured concurrency didn't exist, and so I chose the event loop timer as a way to periodically do a thing. Alternatives would've been Timer or Dispatch, I guess. Not sure why I chose, that; maybe just exploring Vapor/NIO.