def control_message(self): msg = self.pipe.recv_multipart() command = msg.pop(0) if command == "CONNECT": address = msg.pop(0) port = int(msg.pop(0)) if len(self.servers) < SERVER_MAX: self.servers.append( CloneServer(self.ctx, address, port, self.subtree)) self.publisher.connect("%s:%i" % (address, port + 2)) else: logging.error("E: too many servers (max. %i)", SERVER_MAX) elif command == "SET": key, value, sttl = msg ttl = int(sttl) self.kvmap[key] = value # Send key-value pair on to server kvmsg = KVMsg(0, key=key, body=value) kvmsg["ttl"] = ttl kvmsg.send(self.publisher) elif command == "GET": key = msg[0] value = self.kvmap.get(key, '') self.pipe.send(value)
def main(): # context and sockets ctx = zmq.Context() snapshot = ctx.socket(zmq.ROUTER) snapshot.bind("tcp://*:5556") publisher = ctx.socket(zmq.PUB) publisher.bind("tcp://*:5557") collector = ctx.socket(zmq.PULL) collector.bind("tcp://*:5558") sequence = 0 kvmap = {} poller = zmq.Poller() poller.register(collector, zmq.POLLIN) poller.register(snapshot, zmq.POLLIN) while True: try: items = dict(poller.poll(1000)) except: break # Interrupted # Apply state update sent from client if collector in items: kvmsg = KVMsg.recv(collector) sequence += 1 kvmsg.sequence = sequence kvmsg.send(publisher) kvmsg.store(kvmap) print(f"U: publishing update {sequence} {kvmap}") # Execute state snapshot request if snapshot in items: msg = snapshot.recv_multipart() identity = msg[0] request = msg[1] if request == b"ICANHAZ?": pass else: print("E: bad request, aborting\n") break # Send state snapshot to client route = Route(snapshot, identity) # For each entry in kvmap, send kvmsg to client for v in kvmap.values(): send_single(v, route) # Now send END message with sequence number print(f"S: sending snapshot {sequence} {kvmap}") snapshot.send(identity, zmq.SNDMORE) kvmsg = KVMsg(sequence) kvmsg.key = b"KTHXBAI" kvmsg.body = b"" kvmsg.send(snapshot) print("E: Interrupted\nE: %d messages handled" % sequence)
def handle_snapshot(self, msg): """snapshot requests""" if len(msg) != 3 or msg[1] != b"ICANHAZ?": print("E: bad request, aborting") dump(msg) self.loop.stop() return [identity, request, subtree] = msg if subtree: # Send state snapshot to client route = Route(self.snapshot, identity, subtree) # For each entry in kvmap, send kvmsg to client for k, v in self.kvmap.items(): send_single(k, v, route) # Now send END message with sequence number logging.info(f"I: Sending state shapshot={self.sequence:d}") self.snapshot.send(identity, zmq.SNDMORE) kvmsg = KVMsg(self.sequence) kvmsg.key = b"KTHXBAI" kvmsg.body = subtree kvmsg.send(self.snapshot)
def handle_snapshot(self, socket, msg): """snapshot requests""" if msg[1] != "ICANHAZ?" or len(msg) != 3: logging.error("E: bad request, aborting") dump(msg) self.bstar.loop.stop() return identity, request = msg[:2] if len(msg) >= 3: subtree = msg[2] # Send state snapshot to client route = Route(socket, identity, subtree) # For each entry in kvmap, send kvmsg to client for k,v in self.kvmap.items(): send_single(k,v,route) # Now send END message with sequence number logging.info("I: Sending state shapshot=%d" % self.sequence) socket.send(identity, zmq.SNDMORE) kvmsg = KVMsg(self.sequence) kvmsg.key = "KTHXBAI" kvmsg.body = subtree kvmsg.send(socket)
def send_hugz(self): """Send hugz to anyone listening on the publisher socket""" kvmsg = KVMsg(self.sequence) kvmsg.key = "HUGZ" kvmsg.body = "" kvmsg.send(self.publisher)
def main(): # Prepare our context and subscriber ctx = zmq.Context() snapshot = ctx.socket(zmq.DEALER) snapshot.linger = 0 snapshot.connect("tcp://localhost:5556") subscriber = ctx.socket(zmq.SUB) subscriber.linger = 0 subscriber.setsockopt(zmq.SUBSCRIBE, SUBTREE) subscriber.connect("tcp://localhost:5557") publisher = ctx.socket(zmq.PUB) publisher.linger = 0 publisher.connect("tcp://localhost:5558") random.seed(time.time()) kvmap = {} # Get state snapshot sequence = 0 snapshot.send_multipart(["ICANHAZ?", SUBTREE]) while True: try: kvmsg = KVMsg.recv(snapshot) except: raise return # Interrupted if kvmsg.key == "KTHXBAI": sequence = kvmsg.sequence print "I: Received snapshot=%d" % sequence break # Done kvmsg.store(kvmap) poller = zmq.Poller() poller.register(subscriber, zmq.POLLIN) alarm = time.time() + 1. while True: tickless = 1000 * max(0, alarm - time.time()) try: items = dict(poller.poll(tickless)) except: break # Interrupted if subscriber in items: kvmsg = KVMsg.recv(subscriber) # Discard out-of-sequence kvmsgs, incl. heartbeats if kvmsg.sequence > sequence: sequence = kvmsg.sequence kvmsg.store(kvmap) action = "update" if kvmsg.body else "delete" print "I: received %s=%d" % (action, sequence) # If we timed-out, generate a random kvmsg if time.time() >= alarm: kvmsg = KVMsg(0) kvmsg.key = SUBTREE + "%d" % random.randint(1, 10000) kvmsg.body = "%d" % random.randint(1, 1000000) kvmsg['ttl'] = random.randint(0, 30) kvmsg.send(publisher) kvmsg.store(kvmap) alarm = time.time() + 1. print " Interrupted\n%d messages in" % sequence
def main(): # Prepare our context and subscriber ctx = zmq.Context() snapshot = ctx.socket(zmq.DEALER) snapshot.linger = 0 snapshot.connect("tcp://localhost:5556") subscriber = ctx.socket(zmq.SUB) subscriber.linger = 0 subscriber.setsockopt_string(zmq.SUBSCRIBE, "") subscriber.connect("tcp://localhost:5557") publisher = ctx.socket(zmq.PUSH) publisher.linger = 0 publisher.connect("tcp://localhost:5558") random.seed(time.time()) kvmap = {} # Get state snapshot sequence = 0 snapshot.send_string("ICANHAZ?") while True: try: kvmsg = KVMsg.recv(snapshot) except: return # Interrupted if kvmsg.key == b"KTHXBAI": sequence = kvmsg.sequence print(f"S: Received snapshot {sequence} {kvmap}") break # Done kvmsg.store(kvmap) poller = zmq.Poller() poller.register(subscriber, zmq.POLLIN) alarm = time.time() + 1.0 while True: tickless = 1000 * max(0, alarm - time.time()) try: items = dict(poller.poll(tickless)) except: break # Interrupted if subscriber in items: kvmsg = KVMsg.recv(subscriber) # Discard out-of-sequence kvmsgs, incl. heartbeats if kvmsg.sequence > sequence: sequence = kvmsg.sequence kvmsg.store(kvmap) print(f"U: received {sequence} {kvmap}") # If we timed-out, generate a random kvmsg if time.time() >= alarm: kvmsg = KVMsg(0) kvmsg.key = ("%d" % random.randint(1, 10000)).encode() kvmsg.body = ("%d" % random.randint(1, 1000000)).encode() kvmsg.send(publisher) kvmsg.store(kvmap) alarm = time.time() + 1.0 print(f"E: Interrupted\nE: {sequence} messages handled")