Skip to content

Commit

Permalink
Push docs
Browse files Browse the repository at this point in the history
  • Loading branch information
coretl committed Nov 13, 2015
1 parent b7820cc commit 99e82c1
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 12 deletions.
27 changes: 18 additions & 9 deletions docs/comms/pva.rst
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
pvData over pvAccess
====================

The structure of the device as specified in V4 normative types language is this::
The structure of the Device as specified in V4 normative types language is this::

Device :=
structure
string name // Name of the device
string descriptor : opt // Description of the device
string[] tags : opt // Tags for device if any, e.g. "instance:RunnableDevice"
Method[] methods : opt // Methods this device supports if any
StateMachine stateMachine : opt // Statemachine if device has one
NTAttribute[] attributes : opt // Attributes that form arguments for methods/readbacks if any
Method :=
Expand All @@ -19,13 +18,8 @@ The structure of the device as specified in V4 normative types language is this:
// tags = ["argument:required"] if required
string[] valid_states : opt // StateMachine states this method is valid in
string descriptor : opt // Docstring of method
StateMachine :=
structure
string message // Status message for info
string state // State of the machine
string[] states // List of all possible states of this machine
time_t timeStamp // Timestamp of last transition (even if no change in state/message)

// And standard types unchanged from the Normative Types document
NTAttribute :=
structure
Expand All @@ -47,3 +41,18 @@ The structure of the device as specified in V4 normative types language is this:
long secondsPastEpoch
int nanoseconds
int userTag

I would like to have a number of servers, each of which hosts a number of these devices.
The client can then create proxies to these objects which set monitors on the structures
and allow RPC methods to be called.

This allows me to produce a distributed object model, where I can expose some high level
scriptable objects to the end user, that in turn talk to some lower level objects that
talk directly to hardware. The objects can be in the same process, on the same machine,
or on different machines, and it should make no difference.

The high level objects I would expect to be written in Python, while the lower level
objects should be written in C++ (although they are currently in Python talking CA to
V3 IOCs).


51 changes: 48 additions & 3 deletions docs/devices.rst
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
Design process for devices
==========================

Ideas from Rob
--------------

Some interest on using the client from Jython, so need to think about C
extensions. Maybe we should refactor using threads instead of cothreads?

Expand All @@ -12,3 +9,51 @@ http://stackoverflow.com/questions/3033952/python-thread-pool-similar-to-the-mul

Debatable whether we need 1 or 2 threads per device (one for function requests, one for
stateMachine, or 1 to do both).

Now I think it's better to have the following:
* 1 thread for Process as we currently have
* A thread pool for the process for calling functions, similar to currently
* 1 thread per Socket as we currently have
* 1 thread for CA (change)
* Device statemachine handled by Process thread

If we wrap this all up so we have 3 primitives, following the primitive API
* Task (cothread.Spawn, Queue.Thread) with __del__ behaviour
* Queue (cothread.EventQueue, threading.Queue)
* Lock (cothread.Event, threading.Lock)

We will also make a simple threadpool from these primitives

We can then use the threading builtins, or manufacture cothread
ones that look similar. Let's not use multiprocessing as we can start multiple
processes manually and it will allow us to use Jython

We should also refactor so that listeners require an input queue to push onto,
and push (name, changes) instead of calling arbitrary functions

So we should make it so that any Method only calls threadsafe functions, we can
do this by taking the Lock before running a function, and letting report_wait
release it.

We need 2 objects for the Process:
* Process class with q. This receives all events and fans them out to:
* DeviceManager. This manages all running methods and idle tasks for all devices,
unblocking Methods when changes occur, etc.

Listener API:
* self.listen(device, suffix="")
* will make device put (SEvent.Changes, device.name, changes=dict()) onto self.process.q
and setup self.process to post these changes to any blocked Methods

Subscriptions should be owned by the sockets and should be called like this:
* self.listen(device, suffix="") but will put things on self.q not self.process.q

This should mean that we can do Tango and EPICS V4 by listening to Process devices, and
when they appear or disappear then destroying or creating our own devices

Add fancy things in setattr to see if we are setting
Attributes or _private variables

Can add a whole bunch of fancy things to ipython here:
http://www.esrf.eu/computing/cs/tango/tango_doc/kernel_doc/pytango/latest/itango.html#itango-highlights

0 comments on commit 99e82c1

Please sign in to comment.