|
|
Let's the fun begin!
|
|
|
|
|
|
## A 0RPC implementation
|
|
|
|
|
|
Here is an extremely crude version of a distributed Lima implemented with 0RPC that runs two simulators.
|
|
|
|
|
|
#### Server(s)
|
|
|
|
|
|
```python
|
|
|
import zerorpc
|
|
|
|
|
|
from Lima import Core
|
|
|
from Lima import Simulator
|
|
|
|
|
|
Core.Debug.DebParams.setTypeFlags(Core.Debug.DebParams.AllFlags)
|
|
|
|
|
|
cam = Simulator.Camera()
|
|
|
hw = Simulator.Interface(cam)
|
|
|
ct = Core.CtControl(hw)
|
|
|
|
|
|
s = zerorpc.Server(ct)
|
|
|
s.bind("tcp://0.0.0.0:4242")
|
|
|
s.run()
|
|
|
```
|
|
|
|
|
|
#### Client
|
|
|
|
|
|
```python
|
|
|
import gevent
|
|
|
import zerorpc
|
|
|
|
|
|
class Backend(object):
|
|
|
def __init__(self, url):
|
|
|
self.url = url
|
|
|
|
|
|
def connect(self):
|
|
|
self.client = zerorpc.Client()
|
|
|
self.client.connect(self.url)
|
|
|
return self.client
|
|
|
|
|
|
# A distributed CtControl that talks to the actual
|
|
|
# CtControl instance (backends) on the network.
|
|
|
#
|
|
|
# It is supposed to be used in the same way than the regular CtControl.
|
|
|
class CtControlDistrib(object):
|
|
|
def __init__(self, backends):
|
|
|
self.__backends = backends
|
|
|
for b in self.__backends:
|
|
|
c = b.connect()
|
|
|
|
|
|
def __getattr__(self, name):
|
|
|
def res():
|
|
|
async_result = []
|
|
|
for b in self.__backends:
|
|
|
if hasattr(b.client, name):
|
|
|
method = getattr(b.client, name)
|
|
|
async_result.append(method(async=True))
|
|
|
return gevent.joinall(async_result)
|
|
|
return res
|
|
|
|
|
|
backends = [
|
|
|
Backend("tcp://127.0.0.1:4242"),
|
|
|
Backend("tcp://127.0.0.1:4243")
|
|
|
]
|
|
|
|
|
|
ct = CtControlDistrib(backends)
|
|
|
res = ct.prepareAcq()
|
|
|
res = ct.startAcq()
|
|
|
```
|
|
|
|
|
|
This is in no way even a beginning of implementation but a way to understand what needs to be done to implement a distributed LImA. Some ideas:
|
|
|
|
|
|
- The state machine needs to be replicated on each nodes.
|
|
|
- An master instance of CtControl serves as the interface to the external world.
|
|
|
- Only the master actually sends the commands to the camera, the slaves should receive the response though.
|
|
|
- A clean separation of control and data acquisition in the plugins should help.
|
|
|
|
|
|
```mermaid
|
|
|
graph LR;
|
|
|
ctd[CtControlDistrib]---ct1[CtControl 1];
|
|
|
ctd---ct2[CtControl 2];
|
|
|
ctd---ct3[CtControl 3];
|
|
|
ct1---hw[HwInterfaceDistrib];
|
|
|
ct2---hw;
|
|
|
ct3---hw;
|
|
|
hw---cp1[Camera Plugin 1];
|
|
|
hw---cp2[Camera Plugin 2];
|
|
|
hw---cp3[Camera Plugin 3];
|
|
|
cp1---cc[Camera / Control];
|
|
|
cp1---m1[Camera / Module 1];
|
|
|
cp2---m2[Camera / Module 2];
|
|
|
cp3---m3[Camera / Module 3];
|
|
|
``` |
|
|
\ No newline at end of file |