---- SNAPpy Polling Framework ----

The polling framework is a SNAPpy script that a user can import from his own script
to provide functions that aid in fast discovery and data retrieval.
Along with the SNAPpy script an accompanying standalone application is available
to demonstrate how to discover the nodes in your network and retrieve some data.

The framework is designed to be unobtrusive to the user's SNAPpy script so that
it can easily be added to existing scripts.  The only adjustments to a user's script
that needs to be made is to call the frameworks "setup" function from the startup
hook and the "timer" function on the 100ms hook.  There are no special hooks required
to call a function in the user's SNAPpy script to retrieve data.  The functions name
is passed and the return value from that function is used.  Here is an example SNAPpy
script using the framework:

from polling_framework import *

@setHook(HOOK_STARTUP)
def on_start():
    setup()
	
@setHook(HOOK_100MS)
def on_100ms(ms):
    timer()

def my_func():
    return random()


The standalone application displays the time it took to discover all of the nodes
and optionally how long to get information from each node.  The standalone application
is built using SNAP Connect 3 and demonstrates how to use SNAP Connect helper library
that talks to the framework.  This library is used to help user's write their own
SNAP Connect application that interface to the SNAPpy polling framework.

Taking a look through the SNAP Connect helper library will help us to better understand
the SNAPpy side of the code.  In your application you will want to instantiate a
"PollingFrameworkHelper" object and then assign it's "snap_instance" property to your
SNAP Connect instance.  You will also need to tell SNAP Connect about some methods that
remote SNAP nodes can call apart of the helper library.  The first public method of the
helper library we want to look at is the "start_ping" method.  This method initiates a
ping to all nodes apart of your SNAPpy network running the polling framework and takes
a single argument that is a function to call when it has completed.  Looking into the
code of that method you will notice that sends a multi-cast ping of 1, which will only
reach your bridge node, calling the polling framework's "ping" function with a sequence
number.  This initiates the ping and nodes will start reporting back allowing you to
discover who is apart of the network.  Once your function has been called it is safe
to look at the "node_addresses" property which is a list of network addresses that
responded. Now that you have a list of all of the nodes who responded it is possible
to call a function on that remote node and retrieve it's answer.
To do this you will need to call the "get_data" method passing it the node's address,
function name to call, and your own function to call when it has completed.  This
initiates retrieving information from the node by calling the "get_data" SNAPpy function
in the network. Once the node responds your function is called and passed the address of
the node who responded and it response.  Similarly, there is a method called
"get_data_all_nodes" that will provided results from all nodes discovered from a ping.
