Basic description of Taranta architecture

This relates to a brief definition of Taranta architecture overview

Taranta communication protocol

The communication between Taranta and TangoGQL is done by using WebSocket.

WebSocket is a computer communications protocol, providing full-duplex communication channels over a single TCP connection.

The way Taranta works is that it opens a socket at the beginning of the runCanvas (pressing the Start button on dashboards) or at the selection of a device on the overview, this socket is only closed once the Edit button is pressed on the dashboards, or the user exits overview or Taranta itself from the browser.

Taranta data injection points

There are two injection points of data on Taranta, one for the dashboards, another for the overview.

  • taranta/src/dashboard/components/RunCanvas/emmiter.ts (for dashboards)

  • taranta/src/jive/state/api/tango/index.js (for overview)

On both this files there is a function called socketUrl(tangoDB: string) this is where the url for socket communication is defined

Taranta data injection type

On the communication between Taranta and TangoGQL the type of data is defined by Graphene-Python which is a library for building GraphQL APIs in Python.

This are two simple examples of data between Taranta and TangoGQL

  • Data example passed to TangoGQL to subscribe to one attribute double_scalar on the device sys/tg_test/1

   {"type":"start","payload":{"query":"\nsubscription Attributes($fullNames: [String]!) {\n  attributes(fullNames: $fullNames) {\n    device\n    attribute\n    value\n    writeValue\n    timestamp\n  }\n}","variables":{"fullNames":["sys/tg_test/1/double_scalar"]}}}

* Data example passed to Taranta for the subscription of one attribute *double_scalar* on the device *sys/tg_test/1*
{"type": "data", "payload": {"data": {"attributes": {"device": "sys/tg_test/1", "attribute": "double_scalar", "value": 181.01969624669448, "writeValue": 0.0, "timestamp": 1568211918.50133}}}}

To support multiple Tango databases, the name of the DB is appended to the device name using the :// separator, for example, tangodb1://my/device/name. The extended device name is then saved and used within the application. When required, the name is split to make the appropriate API calls. Logic for combining and splitting the name is mainly found in the dashboard/runtime/utils.ts file, specifically within the splitFullPath function.

WebSocket middleware & store

The websocket middleware is created when the application loads during the creation the store. This middleware is used to fetch data from TangoGQL & store it in the redux store.

IMG1

During the creation of websocket middleware, a socket object is created which is used to open a connection to the TangoGQL. Some listeners attached to socket object are as follows:

  1. open: In this listener we can perform some task or set flags to indicate socket is open successfully.

  2. message: This is called every time we get data or message from TangoGQL via the socket. After receiving mesage we dispatch (raise) action to store this message in the store. The subscribed components will react (re-render) to this data updated in the store.

  3. disconnected: This is called when socket connection is terminated

Additionally the websocket middleware also listens continuously to the redux events (UNSUBSCRIBE, SUBSCRIBE etc).

  1. SUBSCRIBE EVENT: Socket is already open but we are not receiving any data from the TangoGQL. To receive the data we(AttributeDisplay in this case) need to raise subscribe to some device attribute. For eg. Attribute display component can raise SUBSCRIBE event with device as sys/tg_test/1 & attribute as short_scalar in the payload. The websocket middleware will listen to this subscribe event and ask’s TangoGQL for the data (in this case device attribute value) via socket.

  2. UNSUBSCRIBE EVENT: This is helpful to unsubscribe the data coming from the TangoGQL

  3. We can also write some custom listeners as per our need

IMG2

Structure of redux store Store is the object that stores the state of the entire application in object format We store every incoming message or data from TangoGQL inside store. The react components have subscribed to the store object. Any change in the store causes the respective subscribed component to re-render. For eg. If we have two attribute display widgets:

  1. Attribute Display 1: Device: sys/tg_test/1, attribute: short_scalar

  2. Attribute Display 2: Device: sys/tg_test/1, attribute: status

In above case if only short_scalar value changes then only Attribute Display 1 component will re-render. This will save un-necessary re-rendering of Attribute Display 2.

IMG3