Hi, @rossetyler. Sorry for the delay, the engineering team mentioned the following about your sample:
- In the driver you aren’t using any sockets at all, so there are no calls to
receive
but you use bothcosock.socket.sleep
andcosock.socket.select
-
In this file it is not clear if one of those functions is getting called in the
added
lifecycle and that is blockinginit
. - You should check if the creation of the devices was successful using
assert(driver.try_create_device(...))
orlocal success, err = driver.try_create_device(...)
. This way, you can see if there were immediate errors.- Especially because, in your sample, you’re calling
try_create_device
in a hot loop100
times and this might be reaching the rate limit of devices created in a given timespan.
- Especially because, in your sample, you’re calling
In this case, this number of devices was an example, or do you actually have drivers that create 100
devices? If so, could you share the details of that use case?
- Any time something could block the current thread, you can avoid that entirely by calling
cosock.spawn
. So, something likecosock.spawn(function() local value, err = socket:receive() end)
would allow the use of the device thread for any other device events. For example:
This sample shows how the device thread can be blocked
-- This driver will lock up any device thread by
-- yielding the thread into a deadlock because
-- init cannot be processed until added is complete
-- but added is relying on init to complete
local tx, rx = cosock.channel.new()
local function added(driver, device)
-- wait for init
local init, err = rx:receive()
end
local function init(driver, device)
-- send init
tx:send(device.id)
end
local driver = Driver("...", {
lifecycle_handlers = {
added = added,
init = init,
}
})
Considering the previous implementation, this is how we can avoid the blockage using cosock.spawn
local tx, rx = cosock.channel.new()
local function added(driver, device)
cosock.spawn(function()
local init, err = rx:receive()
end)
-- wait for init
end
local function init(driver, device)
-- send init
tx:send(device.id)
end
local driver = Driver("...", {
lifecycle_handlers = {
added = added,
init = init,
}
})