Announcement

Collapse
No announcement yet.

SNAPconnect Futures

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • SNAPconnect Futures

    I'm trying to implement SNAPconnect Futures for asynchronous communications. Tornado and async programming in python is a new world for me.

    All the nodes in my network are in a sqlite database. Here is what I'm doing:

    Code:
    activators = getActivators(DATABASE_NAME)
    for name, mac in activators.iteritems():
        log("activator name: " + name + " activator MAC: " + mac)
        response = yield scf.callback_rpc(mac, "ping", callback_name="pingCompleted")
        log(name + " response = " + str(response[0]))
    My question is how to handle the case where the node is NOT found? Here is some logging output:

    Code:
    03-02-2017 09:51:32:184 DEBUG    snap.mesh Sent RREQ for 074cbf
    03-02-2017 09:51:32:214 DEBUG    snap.mesh RREQ was sent by us or we have already seen
    03-02-2017 09:51:32:687 DEBUG    snap.mesh RREQ retry #1 for 074cbf
    03-02-2017 09:51:32:734 DEBUG    snap.mesh RREQ was sent by us or we have already seen
    03-02-2017 09:51:33:693 DEBUG    snap.mesh RREQ retry #2 for 074cbf
    03-02-2017 09:51:33:721 DEBUG    snap.mesh RREQ was sent by us or we have already seen
    03-02-2017 09:51:35:197 DEBUG    snap.mesh RREQ timeout for 074cbf
    03-02-2017 09:51:35:198 ERROR    snapconnect_futures RPC failed to send for 074cbf ping('ping',)
    ...
    03-02-2017 09:51:44:282 ERROR    snapconnect_futures RPC failed to send for 074cbf ping('ping',)
    03-02-2017 09:51:44:282 ERROR    snapconnect_futures Unable to send RPC after multiple attempts. Giving up and returning responses
    03-02-2017 09:51:44:285 ERROR    tornado.application Future exception was never retrieved: Traceback (most recent call last):
    The first thing I tried was a try/except, but that did not seem to catch the error. What are my options?

  • #2
    After further examination, it looks like try/except does indeed catch the exception:

    Code:
    activators = getActivators(DATABASE_NAME)
    activators2 = activators.copy()
    for name, mac in activators2.iteritems():
        log("activator name: " + name + " activator MAC: " + mac)
        try:
            response = yield scf.callback_rpc(mac, "ping", callback_name="pingCompleted")
            log(name + " response = " + str(response[0]))
        except Exception, e:
            log("exception = " + e.message)
            # remove the unfound activator
            del activators[name]

    Comment


    • #3
      Using SNAPconnect Futures, I'm trying to schedule a callback_rpc. I'm really in the dark here since there are no example scripts from which to obtain guidance.

      Here is my code with some of the background stuff missing for the sake of brevity.

      Code:
      scheduler = apy.ioloop_scheduler.IOLoopScheduler.instance()
      comm = snap.Snap(scheduler=scheduler, funcs={})
      tornado.ioloop.PeriodicCallback(comm.poll_internals, 5).start()
      scf = SnapConnectFutures(comm)
      
      def solenoid_off(addr, solID):
          response = yield scf.callback_rpc(addr, "SolenoidOff", solID )
      
      def solenoid_on(addr, solID):
          response = yield scf.callback_rpc(addr, "SolenoidOn", solID)
      
      @coroutine
      def main():
          ...
          yield setup_serial(COM_PORT)
          startDelay = 0 # seconds
          endDelay = 3 # seconds
          scheduler.schedule(startDelay, solenoid_on, "07f628", 1)
          scheduler.schedule(endDelay, solenoid_off, "07f628", 1)
      
      
      if __name__ == '__main__':
          main()
          tornado_loop = tornado.ioloop.IOLoop.instance()
          # my_loop.add_timeout(3, my_loop.stop)
          tornado_loop.start()
      When I run this, the scheduled events never fire. I don't have a clear idea on how to schedule the callback_rpc. Should the solenoid_on/solenoid_off funcs be defined as coroutines?

      Comment


      • #4
        I finally figured this out. First, the solenoid_on/solenoid_off funcs have to be declared as coroutines. To schedule the delays, I used

        Code:
        tornado_loop.add_timeout(time.time() + startDelay, solenoid_on, mac, 1)
        to schedule the callback_rpc.

        Comment


        • #5
          As I continue to implement SNAPconnect Futures, I'm running into a new problem. Here is how I'm creating the SCF instance:

          Code:
          scheduler = apy.ioloop_scheduler.IOLoopScheduler.instance()
          comm = snap.Snap(scheduler=scheduler, funcs={'activate': activate})
          tornado.ioloop.PeriodicCallback(comm.poll_internals, 5).start()
          scf = SnapConnectFutures(comm)
          I want my SC script to respond to a mcastRpc coming from any node.
          Code:
          mcastRpc(1,3,'activate',switchValue)
          I've tried decorating the activate function with @coroutine, but my script is still not seeing any mcastRpc's coming from one if the nodes.

          How do I create the SCF instance such that it will receive this?

          Comment


          • #6
            Crap! This works, I had an error elsewhere in my code.

            For anyone who's interested in SNAPconnect Futures, if you want to get the remote address of the node calling your SCF script you need to use:
            Code:
            remoteAddr = comm.rpcSourceAddr()

            Comment

            Working...
            X