2

The objective of my application is to control and monitor sensor based equipment (temperature, humidity etc). Data from the equipments is transmitted using GSM, Ethernet or Serial port channels. When data is obtained the program needs to store it in the database and then to notify users in their UI. Users are able to send a command from a certain command list to an equipment.

My current design consists of 3 independent programs:

  1. Equipment handling program. It works with the predefined communication channel (GSM, Ethernet, Serial). Actually I have three programs: one for GSM, one for Ethernet, one for Serial. Every program interacts with server program.

  2. The single server program. It gets messages from Equipment handling programs, logs them and transmits data to UI programs. And vice versa: it gets commands from UI and sends them to the concrete Equipment handling program.

  3. UI program. It visualizes current state of equipments, gets commands from a user and sends them to the server. It is possible to have one or more UI programs.

I use the publish/subscribe pattern to exchange data between these programs. I have no problem with data exchanging.

The question is where to store current state of equipments. Do I need to duplicate state in all programs or just to store data at the server? How to deal with data synchronization between the programs?

I believe that such an architecture is well known and there is a reliable pattern to deal with.

5

You can have different storage locations depending on your architecture.

  1. You can store all the data on each of the sensors themselves, and the server requests them (and caches it) regularly. As a result, the definitive data resides on each sensor.

  2. The data is sent to the server which stores it. The sensors only keep data for a short time, either buffered until it can be sent (due to network outage or bandwidth constraints) or the latest state is sent to the server as it becomes ready.

The UI should not have state in it, request what data it needs from the server for display.

Its really easy to put the data on the server and assume its the definitive state, and its as good as you need. If a sensor is offline that information (ie the last time data was received) should be recorded too. Then the sensors can be stateless and you only have to code data handling complexity into the server.

You should never duplicate state though, data is either saved away for use, or in transit to the store. If you choose option 1 for your architecture then the server simply becomes a cache for the data that it reads from the sensors. You can turn the server off and lose all data and it'll be OK as on reboot it'll repopulate its cache. but if the sensors only send irregularly, then there will be gaps until they send, so option 2 might be better as the last state will be read from a persistent database the server stores the data in.

2

You need to consider your wider use cases.

  • What do you want to happen if a sensor or controller goes offline?

    • Do you want to be able to show the most recent values the sensor indicated?
    • Do you want to be able to take commands, that will take effect when it comes back online?
    • Do you want to be able to show (to other UIs) the command / state that will be sent when one comes back online.
  • What do you want to do for an upgrade or restart of the server? Should it rediscover the sensors and their values, or carry forward some notion of that from the previously running server?


In a client-server environment, information is sent to a UI. If that information can change (e.g. by another UI sending commands to the server, or a background/batch job, or in your case by a sensor) then what the UI displays to the user is, in some real sense sense, always stale!

So, we would take that into account in designing the (server) APIs so that they are capable of carrying out meaningful scenarios.

In some domains that means providing APIs that increment or decrement instead of setting absolute values (and in others, vice versa).

Sometimes we will provide for guards in the API, such as "change some item to that value" but only if it is still has this value (a compare & swap), or maybe only if it hasn't been otherwise updated since sometime (or version indicator). We can also provide timestamps or counters along with values, that show how up-to-date the values are.


The question is where to store current state of equipments. Do I need to duplicate state in all programs or just to store data at the server?

Consider your wider use cases. Also, differentiate different kinds of state, e.g. measurements vs. history logs, vs. settings.

How to deal with data synchronization between the programs?

For one, we should provide APIs that accommodate the needs of your synchronization scenarios. An overly simple API may be subject to race conditions, staleness issues, or have atomicity problems.

For another, we should have a definitive idea of who owns what state. Sensors probably own the realtime measurements, and the server maybe owns logs. Controllers & actuators probably own some state for their operation but that might be duplicated on the server, which we might actually consider authoritative (in case a controller needs to be replaced, so it can be reprogrammed by the server).

And further, there are a number of methods that we can use to make UIs refresh when changes are detected (broadly, such as polling or notification). If your UIs are browser-based, you make look into frameworks (e.g. Angular or React).

In short, use a combination of understanding who is authoritative for what data, APIs that are friendly & capable (given that in distributed systems potentially stale information is going to be acted upon), indications acknowledging how up-to-date information is, and timely notification of changes.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.