Python bridge issues

Chris and Dave, two other issues with the python bridge in the latest nightly:

  1. After you call conduit.initialize() some time passes before the
    .codec and .reverse_codec attributes are filled in. If you try to
    access them immediately after initialize() they are sometimes empty
    (but as you’d expect from a race, not always. Argh.) time.sleep(0.5)
    works around this for me. Should initialize() block?

  2. If the server dies unexpectedly, the conduit gets wedged. Even
    restarting the server and client doesn’t work, you have to kill the
    process:
    python2.6 python_bridge_plugin_conduit
    and restart.

Also, one question about variables: there is a logging option
“when_changed”. Is there an “always” option, so that even if you
write the existing value to a variable the new timestamp gets logged?
This would be nice but is not essential for me, I have a workaround.

Thanks. I’ll let you know about other issues I hit as I debug this.

Mark

Re 1: This is a great point. Probably the cleanest thing to do here would be to have any Python call that depends on the codec block until it has been received (+ a timeout exception).

Re 2: In my lab, we found that we were actually much happier interfacing with conduits from python processes we launched ourselves (which is to say, we don’t actually use the client bridge). Most of our stuff is IO-related, so the serverside-bridge is appropriate (I still need to get you this plugin), but if you wanted an under-the-hood clientside GUI-free bridge, that would be straightforward to arrange.

Also, re: conduit wedging, are you still using a nightly from December? I remember squashing a few zombie conduit bugs along the way that may or may not be affecting you.

Thanks! For output, yes I could just launch python myself; I’ll try that when I have a chance.
And I’m now using a nightly from last week.

Hi Dave and Chris,

I tried launching the client bridge script manually:
/usr/bin/python2.6 script_name
and it doesn’t successfully connect to MWClient.
I can get it to work, though: I launch the python bridge plugin, and
load the same python script.
Then, I can kill the python process and launch the script, and it
connects to the conduit just fine. Is there something I’m missing to
make this easier?

Thanks,
Mark

Is there something I’m missing to make this easier?

Yes: the serverside conduit: https://github.com/davidcox/mworks/tree/feature/serverside_conduit_integration/plugins/core/ServersideConduit

If you choose to use it, let me know if anything is unclear. MWLibrary.xml/mw_plugin_definition.yml give an outline of how it is meant to be used.

Dave

Danke. I will probably take a few weeks to test this out but I may get to it sooner. Thanks!!! A quick look at the docs seems like it should be straightforward.
Mark

Hey Dave,

At Mark’s request, I’m trying to get your serverside conduit to work with the latest nightly. I’ve been able to compile it and use it in an experiment (though I had to disable the “Autogenerate Plugin Plumbing” step, since I don’t have your script, and I had to modify MWServer to register its Server instance). For the most part, it seems to work. However, when running the attached experiment and Python script, I’m observing two issues:

  1. Every time I run the script, I get dozens of “Received new codec, updating variable registry” messages in the server console. These appear to be originating in VariableRegistry::updateFromCodecDatum.
  2. Running the script causes MWClient to freeze, after which I must force quit it.

Have you run in to these at all? Are there other changes you’ve made to the core or other components to address them? Or is the design of my script leading to these issues?

Thanks,
Chris

Attachments:

Chris,

I’m out of the country at the moment, so it is a bit difficult for me to check on this, but the standalone server-side conduit wasn’t causing any crashing or freezing the last time I checked. My suspicion is there may have been fixes to python bridging that go along with it, that I haven’t merged upstream yet (indeed, the whole plugin hasn’t been merged upstream yet). The autogenerate script thing (as you discovered) is not essential; it was an experiment. It works well, but I’m happy to remove it when merging into the mainline if we want to keep dependencies down.

I’ll be back in my lab on Tuesday (for one day, then traveling again), so I’ll hopefully have a chance to check it out. I’ll at least be in the country from that point on, so I should still be able to make some progress if you’re still stuck.

The branch I’m working from is the one that the plugin is a subtree of, so you’re welcome to check the whole thing out and try it, to see if there are any difference. That repo is in is a subtree-merged version of everything, as we discussed. I sent you a message a while back about biting the bullet and transitioning / cleaning up (or at least, I thought I did), but things have been so busy that I haven’t really had time to follow up (sounds like you’ve been busy too – congrats, btw!). In any event, it would be nice to re-raise this issue, since it is quite a bit easier to work within a single umbrella repository. Happy to do it differently than I’ve done, but it would be nice to settle the structure going forward.

  • Dave

Thanks, Dave. After further investigation, I’ve discovered that the client is freezing due to a bug in the MATLAB plugin. I’m working on a fix, but in the meantime, removing (or just not installing) the MATLAB plugin eliminates the issue.

Chris

Hi Mark,

The server-side Python conduit is now included in the nightly build. I’ve attached a demo script (and corresponding experiment) that both sends and receives variable values. To try it out, load and run the experiment, then launch the script from the command line:

$ python python_bridge_demo.py

Note that the script is written to work with both the server-side and client-side bridges. I’m not sure when Dave made it possible to set variable values via the client-side bridge, but it’s certainly a nice feature.

If you have any questions or run in to any problems, please let us know.

Chris

Attachments:

Chris,

Thanks very much for this - I will check it out soon.

What are the downsides and advantages of the server and client bridges? Should everyone be using the server-side bridge?

Thanks,
Mark

What are the downsides and advantages of the server and client bridges? Should everyone be using the server-side bridge?

Apart from the obvious distinction (namely, that the server-side conduit connects to scripts running on the same machine as MWServer, while the client-side conduit connects to scripts on the machine running MWClient), there’s really only two differences:

  1. A script connected to the server-side conduit communicates directly with MWServer, whereas a script connected to the client-side conduit communicates via MWClient, which relays events between the script and MWServer.

  2. The client-side conduit launches the script for you and pipes its standard output and standard error streams in to the client window, whereas the server-side conduit requires you to launch the script yourself (and thereby lets you decide how to view or otherwise use its output).

If your Python script controls or communicates with an I/O device, then I think the server-side conduit is most appropriate. Since the device is probably an integral part of your experiment, it makes sense for the bridge to be created whenever the experiment runs, regardless of what happens on the client end. Also, the event-delivery latency will be lower, since events don’t need to be sent over the network or make an intermediate hop through MWClient.

On the other hand, scripts that monitor the experiment or do online data analysis are probably a better fit for the client-side conduit, especially if they don’t send events back to the server. Maintaining a bridge consumes memory, threads, and CPU cycles that the server could be using for other stuff, so if the script’s work doesn’t influence the running of your experiment, then it’s best to push that workload on to the client.

I imagine there’s a middle ground where either bridge might make sense, particularly if you run MWServer and MWClient on the same machine. In that case, the decision probably would depend mainly on your feelings about (2) above.

Anyway, that’s my thinking, which admittedly is not based on much real-world usage. Dave may have other recommendations based on his experience.

Chris