Forgive me if this is obvious, but I'm very new to async/await. If this topic is covered in some resource online, I'd greatly appreciate a pointer to it.
I'm writing a Swift wrapper around libmodbus, which I'm currently calling like this:
public
func
readRegister(address inAddr: Int, fromDevice inDeviceID: Int, completion inCompletion: @escaping (UInt16?, Error?) -> ())
{
self.workQ.async
{
do
{
self.deviceID = inDeviceID
let r = try self.readRegister(address: inAddr)
self.callbackQ.async { inCompletion(r, nil) }
}
catch (let e)
{
self.callbackQ.async { inCompletion(nil, e) }
}
}
}
func
readRegister(address inAddr: Int)
throws
-> UInt16
{
if self.deviceID == -1
{
throw MBError.deviceIDNotSet
}
var v: UInt16 = 0
let rc = modbus_read_registers(self.ctx, Int32(inAddr), 1, &v)
if rc != 1
{
throw MBError(errno: errno)
}
return v
}
The libmodbus structure is only ever accessed on the workQ, and the callbacks always happen on the callbackQ. Other than that, each individual libmodbus call blocks until it completes (or times out).
What's the best way to wrap a library like this in a new async/await-style API?
A simple but slightly suboptimal solution would be to just wrap the whole thing in an actor. Blocking actor threads isn't great, but blocking just one actor thread is generally safe enough (I guess it's a problem if you ever ship on a single core device).