DiamondLightSource / aioca

Asynchronous Channel Access client for asyncio and Python using libca via ctypes

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Doing an import on the wrong thread doesn't work

thomascobb opened this issue · comments

This doesn't work:

from softioc import asyncio_dispatcher
from aioca import camonitor

dispatcher = asyncio_dispatcher.AsyncioDispatcher()
dispatcher.loop.call_soon_threadsafe(camonitor, "SR-DI-DCCT-01:SIGNAL", print)

But this does

from softioc import asyncio_dispatcher

def f():
    from aioca import camonitor
    camonitor("SR-DI-DCCT-01:SIGNAL", print)

dispatcher = asyncio_dispatcher.AsyncioDispatcher()
dispatcher.loop.call_soon_threadsafe(f)

Doing the ca_context_create(1) on get_channel (i.e. in the correct thread) makes the first bit of code work.

@Araneidae does a ca_context only work on the thread it is created in?

Looks like it, Channel Access Reference:

This function, or ca_attach_context(), should be called once from each thread prior to making any of the other Channel Access calls. If one of the above is not called before making other CA calls then a non-preemptive context is created by default, and future attempts to create a preemptive context for the current threads will fail.

Ok, I guess deferring the context creation until the first time we get a channel is probably a reasonable fix then?

I don't know; can async execution contexts hop threads?

No, this is specifically for the example above, doing the imports at the top of the file, then spawning the camonitor in the asyncio thread. It's more because it's too easy to accidentally import aioca in the wrong thread

Well, clearly the simplest thing is, as you say, defer the context creation. There's still the hazard of somebody running an async excecutor that chooses to hop threads (I presume this is possible) ... but I think we can say it's all their fault if things go wrong!