If you have not already done so, please look at the “Hello World” tutorials to get a basic understanding of what a Node is and how you can work with it.
In this tutorial, we will examine the different pieces that constitute a PolySync Application, what each means and how you use them.
What You Will Need
- The example source code.
- A computer capable of running PolySync (see the PolySync Installation Guide)
- The system should be compliant with the System Requirements
- It should be running Ubuntu Linux version 14.04.3
- It should have compliant hardware with at least 4GB of ram
- It should have all of the run-time dependencies available; these are included in the installation process
- The system should have PolySync installed
- The system should have a license
- Development tools capable of compiling the tutorial (e.g. sudo apt-get install build-essential)
Compiling the Source Code
The default installation directory for PolySync is /usr/local/polysync. Relative paths used should be considered to originate from the default directory.
The tutorial source code is located in the examples/cpp/PolySyncExampleApp directory.
Use the following command sequence to compile the code:
$ cd /usr/local/polysync/examples/cpp/PolySyncExampleApp $ mkdir build $ cd build $ cmake .. $ make
What is Happening in this code
This tutorial extends the Hello World examples to demonstrate how a more complete application might look. We will delve into the details of each of the different code sections and explain what is happening in each.
This tutorial goes back to using just a single node, but this node gains in complexity as compared to the previous tutiorials. We will implement all of the overloaded callback functions and will support publishing and subscribing in a single application.
Specifically, this application sets the node into different possible states, to demonstrate how the node state machine functions. It also explains what all of the different events are for and situations where you might encounter them.
PolySync Sample Application
Open a terminal and run:
The first thing you see are messages that state:
polysync-sample-appliocation-cpp received a configuration event.
No configuration parameters to display.
While this is not the only time you can see these messages, during the start up of a node, PolySync sends a configuration event to the node to send configuration parameters. We have code to display the parameters send, but, as this is a simple example, we have no parameters to display.
The set configuration event handler has the following prototype:
virtual void setConfigurationEvent( int argc, char *argv )
The next message we see is:
polysync-sample-appliocation-cpp is initializing.
This state you have seen before. In the first tutorial, the HelloWorld only implements this function; it demonstrates how PolySync starts the state machine for a given node. In this tutorial, we are doing the extra work of both registering to receive the “ps_byte_array_msg” message and initializing the timer tick to zero (in preparation for incrementing it.)
The initialization state event has the following prototype:
virtual void initStateEvent()
The next series of messages we see display the following:
OK. This isn't really being printed from the okStateEvent. The okStateEvent is called rapidly by PolySync, which is why we have a sleep function at the end of the loop. This slows it down enough for us to see what is happening on a second by second basis. If we examine what's happening inside the function, we can see that it is publishing a message containing the information above. It happens that we have also subscribes to messages of that type, which is where this printed information is coming from.
At the end of this function, we increment the timer tick by one and it it exceeds the number of iterations in this state, we use the activate fault function to transition in the WARN state.
The ok state event handler has the following prototype:
virtual void okStateEvent()
The information displayed on the console got there from the message event. As part of the initialization, we subscribed to a specific message type that we are now receiving. The complexities associated with processing of the message event are more related to recognizing the type of message that we have received. The message class, has a specific mechanism in place to allow you, as the developer, to attempt to convert your message pointer into the type of message you wanted (and, yes it uses the C++ dynamic_cast.) This function allows you to subscribe to multiple messages and determine which one you received based on what you can convert it to.
The message event has the following prototype:
virtual void messageEvent()
The next message displays the following:
Once again, the warning state does not actually display the information, but instead is sending a message to the effect that the node has entered a warning state. The message event, receives that message and prints the information.
The warning state event sends a few of these messages and then transitions to the ERROR state.
The warning state event handler has the following prototype:
virtual void warnStateEvent()
Next the applications displays:
polysync-sample-application-cpp is in the error state.
We could certainly send messages from the error state also, but the intent is really to indicate that the node is in an error condition and should do something to fix it. PolySync already contains a specific message (the diagnostics message) that contains the state of a given node. Subscribing to that message allows you to see the state of all of the nodes in the current system.
The point of the error state is to allow the system to recognize that the node is in a bad state and do something to react or recover from the fault. What that reaction might be is dependent on both the purpose and function of the node and the criticality of the system.
The treatment of the error state is very like the ok state in that it is called as rapidly as possible. The error state event handler contains a sleep function so that it can send a few of the error messages and then transitions to the FATAL state.
The error state event handler has the following prototype:
virtual void errorStateEvent()
Next the applications displays:
polysync-sample-application-cpp received a fatal error and will shut down.
The fatal state is just that. It is a last call before the node is shut down, essentially an error path for the node to clean itself up if possible.
The fatal state event handler has the following prototype:
virtual void fatalStateEvent()
Finally, the applications displays:
polysync-sample-application-cpp is shutting down.
This is an indicator that the shutdown, even through the fatal state, still calls the release state to allow the node to perform any final clean up. This is specifically called out here because it is an indicator that the fatal state on needs to clean up specific problems. The release will clean up as the nominal exit path for the node.
The release state event handler has the following prototype:
virtual void releaseStateEvent()
And the application has shut down.
This should give you a basic idea of what the different events a node can process are, what they are for, and the situations that you can encounter them.
Thanks for using PolySync!