def run(self): self.zyre = Zyre(None) if self.logger.level > 0: self.zyre.set_verbose() # Zsys.set_logsystem(1) else: # Zsys.set_logsystem(0) pass self.uuid = self.zyre.uuid() self.zyre.set_interface(Config.NIC_NAME.encode('utf-8')) if Config.SECURITY: certFile = os.path.join(self.riapsHome, "keys", const.zmqCertificate) cert = czmq.Zcert.load(ctypes.c_char_p(certFile.encode('utf-8'))) self.zyre.set_zcert(cert) self.zyre.set_evasive_timeout(const.peerEvasiveTimeout) self.zyre.set_expired_timeout(const.peerExpiredTimeout) self.zyre.set_header(b'riaps@' + self.hostAddress.encode('utf-8'), b'hello') self.command = self.context.socket(zmq.PAIR) self.command.connect(const.fmMonitorEndpoint) self.zyre.start() self.zyre.join(b'riaps') self.zyreSocket = self.zyre.socket() self.poller = czmq.Zpoller(zyre.c_void_p(self.command.underlying), self.zyreSocket, 0) while True: reader = self.poller.wait(-1) # Wait forever if self.poller.terminated(): self.logger.warning("FMMon.run - poller terminated") break if type( reader ) == zyre.c_void_p and reader.value == self.command.underlying: msg = self.command.recv_pyobj() self.logger.info('FMMon.run - command: %s' % str(msg)) cmd = msg[0] if cmd == 'stop': break elif cmd == 'setupApp': appName = msg[1] group = self.groupName(appName) self.zyre.join(group) if appName not in self.groups: self.groups[appName] = set() self.actors[appName] = set() elif cmd == 'cleanupApp': appName = msg[1] group = self.groupName(appName) self.zyre.leave(group) if appName in self.groups: del self.groups[appName] elif cmd == 'addActor': appName, actorName = msg[1:] assert appName in self.groups self.actors[appName].add(actorName) group = self.groupName(appName) arg = "+ %s.%s" % (appName, actorName) self.logger.info("FMMon.addActor.shout: %s" % arg) self.zyre.shouts(group, arg.encode('utf-8')) for peer in self.groups[appName]: self.logger.info( "FMMon.addactor tell %s.%s has peer at %s" % (appName, actorName, str(peer))) info = ('peer+', appName, actorName, peer) self.command.send_pyobj(info) elif cmd == 'delActor': appName, actorName = msg[1:] assert appName in self.groups and actorName in self.actors[ appName] self.actors[appName].remove(actorName) group = self.groupName(appName) arg = "- %s.%s" % (appName, actorName) self.logger.info("FMMon.delActor.shout: %s" % arg) self.zyre.shouts(group, arg.encode('utf-8')) elif cmd == 'dieActor': appName, actorName = msg[1:] assert appName in self.groups and actorName in self.actors[ appName] self.actors[appName].remove(actorName) group = self.groupName(appName) arg = "? %s.%s" % (appName, actorName) self.logger.info("FMMon.dieActor.shout: %s" % arg) self.zyre.shouts(group, arg.encode('utf-8')) else: pass # Should be error elif reader == self.zyreSocket: event = ZyreEvent(self.zyre) eType = event.type() _pName = event.peer_name() pUUID = event.peer_uuid() pAddr = event.peer_addr() group = event.group() _headers = event.headers() msg = event.get_msg() # if eType != b'EVASIVE': # print("# %s %s %s %s %s %s %s" # % (str(eType),str(_pName),str(pUUID),str(pAddr), # str(group),str(_headers),str(msg))) if eType == b'ENTER': self.logger.info("FMMon.ENTER %s from %s" % (str(pUUID), str(pAddr))) self.peers[pUUID] = pAddr elif eType == b'JOIN': groupName = group.decode() self.logger.info("FMMon.JOIN %s from %s" % (str(groupName), str(pUUID))) if groupName == 'riaps': continue # Joined riaps group - should be validated else: _, appName = groupName.split('.') if appName not in self.groups: self.groups[appName] = {pUUID} if appName not in self.actors: self.actors[appName] = set() else: self.groups[appName].add(pUUID) if appName in self.actors: peer = pUUID for actorName in self.actors[appName]: arg = "+ %s.%s" % (appName, actorName) self.logger.info( "FMMon.JOIN.whisper: %s to %s " % (arg, str(peer))) self.zyre.whispers(peer, arg.encode('utf-8')) self.logger.info( "FMMon.JOIN tell %s.%s has peer at %s" % (appName, actorName, str(peer))) info = ('peer+', appName, actorName, peer) self.command.send_pyobj(info) elif eType == b'LEAVE': groupName = group.decode() self.logger.info("FMMon.LEAVE %s from %s" % (str(pUUID), str(group))) if groupName == 'riaps': continue # Left riaps group - should be validated else: _, appName = groupName.split('.') if appName in self.groups: self.groups[appName].remove(pUUID) if appName in self.actors: for actorName in self.actors[appName]: peer = pUUID self.logger.info( "FMMon.LEAVE tell %s.%s lost peer at %s" % (appName, actorName, str(peer))) info = ('peer-', appName, actorName, peer) self.command.send_pyobj(info) elif eType == b'EXIT': self.logger.info("FMMon.EXIT %s " % (str(pUUID))) for appName, group in self.groups.items(): if pUUID in group: if appName in self.actors: for actorName in self.actors[appName]: peer = pUUID self.logger.info( "FMMon.EXIT tell %s.%s lost peer at %s" % (appName, actorName, str(peer))) info = ('peer-', appName, actorName, peer) self.command.send_pyobj(info) del self.peers[pUUID] elif eType == b'SHOUT' or eType == b'WHISPER': arg = msg.popstr().decode() self.logger.info("FMMon.SHOUT %s = %s " % (str(pUUID), arg)) peer = pUUID cmd, pair = arg.split(' ') appName, actorName = pair.split('.') head, cast = '?', '?' if cmd == '+': head, cast = 'peer+', ' has peer ' elif cmd == '-': head, cast = 'peer-', ' lost peer ' elif cmd == '?': head, cast = 'peer-', ' lost peer ' if appName not in self.groups: self.groups[appName] = {pUUID} if appName in self.actors: for actorName in self.actors[appName]: self.logger.info("FMMon.%s: tell %s.%s %s %s" % (eType.decode(), appName, actorName, cast, str(peer))) info = (head, appName, actorName, peer) self.command.send_pyobj(info) else: pass self.command.close() for appName in self.actors: if appName in self.groups: group = self.groupName(appName) arg = "- %s.%s" % (appName, actorName) self.logger.info("FMMon.terminate.shout: %s" % arg) self.zyre.shouts(group, arg.encode('utf-8')) self.zyre.leave(b'riaps') self.zyre.stop()
def actor_fn(self, pipe, arg): internal_pipe = Zsock(pipe, False) # We don't own the pipe, so False. arg = string_at(arg) global port zyre_node = Zyre(None) zyre_node.set_header (b"TS-PORT", str(port).encode()); zyre_node.start() zyre_node.join(b"broadcast") zyre_node.join(b"sync") zyre_pipe = zyre_node.socket() poller = Zpoller(zyre_pipe, internal_pipe) internal_pipe.signal(0) print('ZYRE Node started') terminated = False while not terminated: # time.sleep(1) # sock = poller.wait(1000) # if not sock: # continue # # # ZYRE receive # # if sock == zyre_pipe: e = ZyreEvent(zyre_node) # ANY if e.type() != b"EVASIVE": e.print() pass # ENTER: add to phonebook for external contact (i.e. TimeSync) if e.type() == b"ENTER": self.timebook.newpeer(e.peer_uuid(), e.peer_addr(), e.header(b"TS-PORT")) # EXIT elif e.type() == b"EXIT": print( "ZYRE Node: peer is gone..") # JOIN elif e.type() == b"JOIN": # SYNC clocks if e.group() == b"sync": pass self.timebook.sync(e.peer_uuid()) # LEAVE elif e.type() == b"LEAVE": print("ZYRE Node: peer left a group..") # SHOUT -> process event elif e.type() == b"SHOUT" or e.type() == b"WHISPER": # Parsing message data = json.loads(e.msg().popstr().decode()) data['from'] = e.peer_uuid() # add group if e.type() == b"SHOUT": data['group'] = e.group().decode() else: data['group'] = 'whisper' self.eventProc(data) # # # # # # INTERNAL commands # # # elif sock == internal_pipe: # msg = Zmsg.recv(internal_pipe) # if not msg: break # # command = msg.popstr() # if command == b"$TERM": # print('ZYRE Node TERM') # break # # elif command == b"JOIN": # group = msg.popstr() # zyre_node.join(group) # # elif command == b"LEAVE": # group = msg.popstr() # zyre_node.leave(group) # # elif command == b"SHOUT": # group = msg.popstr() # data = msg.popstr() # zyre_node.shouts(group, data) # # # if own group -> send to self too ! # groups = zlist_strlist( zyre_node.own_groups() ) # if group.decode() in groups: # data = json.loads(data.decode()) # data['from'] = 'self' # data['group'] = group.decode() # self.eventProc(data) # zyre_node.stop() # HANGS ! internal_pipe.__del__() zyre_node.__del__() print('ZYRE Node stopped') # WEIRD: print helps the closing going smoothly.. self.done = True
def run(self): self.zyre = Zyre(None) if self.logger.level == logging.DEBUG: self.zyre.set_verbose() else: pass self.uuid = self.zyre.uuid() self.zyre.set_interface(Config.NIC_NAME.encode('utf-8')) if Config.SECURITY: certFile = os.path.join(self.riapsHome, "keys", const.zmqCertificate) cert = czmq.Zcert.load(ctypes.c_char_p(certFile.encode('utf-8'))) self.zyre.set_zcert(cert) self.zyre.set_evasive_timeout(const.peerEvasiveTimeout) self.zyre.set_expired_timeout(const.peerExpiredTimeout) self.zyre.set_header(self.peerHeaderKey(self.hostAddress), self.PEERMARK) self.command = self.context.socket(zmq.PAIR) self.command.connect(const.discoDhtPeerMonEndpoint) self.zyre.start() self.zyre.join(self.PEERGROUP) self.zyreSocket = self.zyre.socket() self.poller = czmq.Zpoller(zyre.c_void_p(self.command.underlying), self.zyreSocket, 0) while True: reader = self.poller.wait(-1) # Wait forever if self.poller.terminated(): self.logger.info("DhtPeerMon.run - poller terminated") break if type( reader ) == zyre.c_void_p and reader.value == self.command.underlying: msg = self.command.recv_pyobj() self.logger.info('DhtPeerMon.run - command: %s' % str(msg)) cmd = msg[0] if cmd == 'stop': break else: pass # Should be error elif reader == self.zyreSocket: event = ZyreEvent(self.zyre) eType = event.type() _pName = event.peer_name() pUUID = event.peer_uuid() pAddr = event.peer_addr() group = event.group() _headers = event.headers() msg = event.get_msg() # if eType != b'EVASIVE': # print("# %s %s %s %s %s %s %s" # % (str(eType),str(_pName),str(pUUID),str(pAddr), # str(group),str(_headers),str(msg))) if eType == b'ENTER': self.logger.info("DhtPeerMon.ENTER %s from %s" % (str(pUUID), str(pAddr))) try: pAddrStr = pAddr.decode('UTF-8') (peerIp, _peerPort) = parse.parse("tcp://{}:{}", pAddrStr) peerHeaderKey = self.peerHeaderKey(peerIp) _value = _headers.lookup(peerHeaderKey) if (_value): try: value = ctypes.cast(_value, ctypes.c_char_p).value assert value == self.PEERMARK self.peers[pUUID] = peerIp self.logger.info("DhtPeerMon.ENTER valid peer") except: self.logger.info( "DhtPeerMon.ENTER header value mismatch") else: self.logger.info( "DhtPeerMon.ENTER header key mismatch") except: self.logger.info( "DhtPeerMon.ENTER peer addr parsing error") elif pUUID not in self.peers: # Skip the rest if this is not a peer continue elif eType == b'JOIN': groupName = group.decode() peer = pUUID self.logger.info("DhtPeerMon.JOIN %s from %s" % (str(groupName), str(pUUID))) if groupName != self.PEERGROUP: self.logger.info("DhtPeerMon.JOIN another group") pass else: self.peerGroup.add(peer) self.zyre.whispers( peer, ("%s://%d" % (self.PEERGROUP, self.dhtPort)).encode('utf-8')) elif eType == b'SHOUT' or eType == b'WHISPER': arg = msg.popstr().decode() self.logger.info("DhtPeerMon.SHOUT %s = %s " % (str(pUUID), arg)) try: pAddrStr = pAddr.decode('UTF-8') (peerIp, _peerPort) = parse.parse("tcp://{}:{}", pAddrStr) assert peerIp == self.peers[pUUID] peerDhtPort = parse.parse("%s://{}" % self.PEERGROUP, arg) if peerDhtPort: self.logger.info("DhtPeerMon.bootstrap %s:%s" % (peerIp, peerDhtPort)) self.dht.bootstrap(str(peerIp), str(peerDhtPort)) except: self.logger.error("DhtPeerMon.bootstrap failed") elif eType == b'LEAVE': groupName = group.decode() self.logger.info("DhtPeerMon.LEAVE %s from %s" % (str(pUUID), str(group))) if groupName != self.PEERGROUP: self.logger.info("DhtPeerMon.LEAVE another group") pass else: self.peerGroup.discard(pUUID) elif eType == b'EXIT': self.logger.info("DhtPeerMon.EXIT %s " % (str(pUUID))) if pUUID in self.peers: del self.peers[pUUID] self.peerGroup.discard(pUUID) else: pass self.command.close() self.zyre.leave(self.PEERGROUP) self.zyre.stop()