def get(self, payload, address): message = '' if payload[0] == 'request': value = self.data.get(payload[4], '') if not value: value = self.relay( payload[1], payload[4]) or '' # returns empty string if result is None result = [ 'response', 'get', self.queue.status(), 'key', payload[4], 'value', value ] message = encode_bencode(result) self.deliver(message, address, identifier=payload[2]) dispatch_status('get', 'response', 'to', address[1]) elif payload[0] == 'relay': value = self.data.get(payload[4], '') result = [ 'relay', 'get', self.record, 'key', payload[4], 'value', value ] message = encode_bencode(result) self.transmit(message, address) dispatch_status('get', 'relay', 'to', address[1]) return message
def get(self, payload, address): message = '' if payload[0] == 'request': value = self.data.get(payload[4], '') if not value: value = self.relay(payload[1], payload[4]) result = [ 'response', 'get', payload[2], 'key', payload[4], 'value', value, 'status', self.egress.status() ] message = encode_bencode(result) self.deliver(message, address, identifier=payload[2]) dispatch_status('get', 'response', 'to', address[1]) elif payload[0] == 'relay-request': value = self.data.get(payload[4], '') result = [ 'relay-response', 'get', self.identifier, 'key', payload[4], 'value', value ] message = encode_bencode(result) self.transmit(message, address) dispatch_status('get', 'relay-response', 'to', address[1])
def replay(self, payload, address): ''' Re-sends message in buffer to balancer. ''' message = self.queue.get(payload[2])[0] self.sock.sendto(message, address) dispatch_status(payload[1], 're-response', 'to', address[1])
def set(self, payload, address): message = '' if payload[0] == 'request': value = self.relay(payload[1], payload[4], payload[6]) or '' if not value: self.data[payload[4]] = payload[6] result = [ 'response', 'set', self.queue.status(), 'key', payload[4], 'value', payload[6] ] message = encode_bencode(result) self.deliver(message, address, identifier=payload[2]) dispatch_status('set', 'response', 'to', address[1]) elif payload[0] == 'relay': value = '' if payload[4] in self.data: self.data[payload[4]] = payload[6] value = payload[6] result = [ 'relay', 'set', self.record, 'key', payload[4], 'value', value ] message = encode_bencode(result) self.transmit(message, address) dispatch_status('set', 'relay', 'to', address[1]) return message
def execute(self, command): if command[0] == 'status': if os.getenv('BALANCER_DEBUG'): sys.stderr.write(str(dt.now()) + ' INFO status broadcast\n') self.broadcast() elif command[0] == 'reset': if os.getenv('BALANCER_DEBUG'): sys.stderr.write(str(dt.now()) + ' WARN database reset\n') self.reset() elif command[0] in ['get', 'set']: key = command[1] value = '' if command[0] == 'get' else command[2] payload = ['request', command[0], self.counter, 'key', key, 'value', value] message = encode_bencode(payload) target = self.choose() if os.getenv('BALANCER_DEBUG'): dispatch_status(payload[1], payload[0], 'to', target) attempt = 0 while attempt < 3: if os.getenv('BALANCER_DEBUG'): sys.stderr.write(str(dt.now()) + ' INFO attempt ' + str(attempt + 1) + ' of 3\n') increment = True if attempt == 0 else False # only increment if 1st attempt address = (NODE_IP, target) self.send(message, address, increment=increment) try: self.sock.settimeout(1) response, address = self.sock.recvfrom(1024) if os.getenv('BALANCER_DEBUG'): dispatch_status(command[0], 'response', 'from', target) result = decode_bencode(response) output = result[6] + '\n' if command[0] == 'get' else 'success!\n' self.status[target] = result[2] if os.getenv('EXAMPLE'): activity = [self.status[target] for target in self.targets] sys.stderr.write(str(activity)[1:-1] + '\n') break sys.stderr.write(output) break except socket.timeout: if os.getenv('BALANCER_DEBUG'): sys.stderr.write(str(dt.now()) + ' WARN timeout\n') attempt += 1 if attempt == 3 and not os.getenv('EXAMPLE'): sys.stderr.write('failed!\n')
def status(self, address): if not self.data: sys.stderr.write(str(dt.now()) + ' WARN database empty\n') return None sys.stderr.write(str(dt.now()) + ' INFO contents start\n') for key, value in self.data.iteritems(): sys.stderr.write(key + ': ' + value + '\n') sys.stderr.write(str(dt.now()) + ' INFO contents end\n') self.heartbeat(address) dispatch_status('status', 'response', 'to', address[1])
def process(self, payload, address): if payload[0] == 'request': self.target = address elif payload[0] == 'relay-response': dispatch_status(payload[1], 'relay-response', 'from', address[1]) if payload[6]: self.outcome.put(payload[4], payload[6]) return None self.ingress.put((payload, address))
def status(self, address): if not self.data: sys.stderr.write(str(dt.now()) + ' WARN database empty\n') return None sys.stderr.write(str(dt.now()) + ' INFO database contents start\n') for key, value in self.data.iteritems(): sys.stderr.write(key + ': ' + value + '\n') sys.stderr.write(str(dt.now()) + ' INFO database contents end\n') result = ['response', 'status', self.queue.status()] message = encode_bencode(result) self.sock.sendto(message, address) dispatch_status('status', 'response', 'to', address[1])
def get(self, command, send=True): target = self.choose() if os.getenv('BALANCER_DEBUG'): dispatch_status('get', 'request', 'to', target) payload = ['request', 'get', self.identifier, 'key', command[1]] message = encode_bencode(payload) address = (NODE_IP, target) if send: result = self.send(message, address, identifier=payload[2]) if not os.getenv('EXAMPLE'): sys.stderr.write(result + '\n') return message
def relay(self, task, key, value=''): payload = [ 'relay-request', task, str(self.identifier), 'key', key, 'value', value ] message = encode_bencode(payload) for peer in self.peers: address = (NODE_IP, peer) self.transmit(message, address) dispatch_status(task, 'relay-request', 'to', peer) time.sleep(0.01) if key in self.outcome.data: return self.outcome.get(key) return ''
def relay(self, task, key, value=''): ''' Sends message to all nodes to find specific key ''' payload = ['relay', task, str(self.record), 'key', key, 'value', value] message = encode_bencode(payload) for peer in self.peers: self.transmit(message, (NODE_IP, peer)) dispatch_status(payload[1], payload[0], 'to', peer) try: self.sock.settimeout(self.timeout) response, address = self.sock.recvfrom(1024) dispatch_status(payload[1], payload[0], 'from', peer) result = decode_bencode(response) if result[6]: return result[6] except socket.timeout: sys.stderr.write(str(dt.now()) + ' WARN timeout\n')
def execute(self, request, address): payload = decode_bencode(request) if self.queue.get(payload[2]): # check if message in buffer dispatch_status(payload[1], 're-request', 'from', address[1]) self.replay(payload, address) return None if payload[1] == 'status': dispatch_status('status', 'request', 'from', address[1]) self.status(address) elif payload[1] == 'reset': dispatch_status('reset', 'request', 'from', address[1]) self.reset() elif payload[1] == 'get': dispatch_status('get', payload[0], 'from', address[1]) self.get(payload, address) elif payload[1] == 'set': dispatch_status('set', payload[0], 'from', address[1]) self.set(payload, address)
def replay(self, payload, address): message = self.egress.get(payload[2])[0] self.deliver(message, address) dispatch_status(payload[1], 're-response', 'to', address[1])
def execute(self): while True: if not self.ingress.empty(): payload, address = self.ingress.get() if payload[0][:5] != 'relay' and self.egress.get(payload[2]): dispatch_status(payload[1], 're-request', 'from', address[1]) self.replay(payload, address) continue if payload[1] == 'status': dispatch_status('status', 'request', 'from', address[1]) self.status(address) elif payload[1] == 'reset': dispatch_status('reset', 'request', 'from', address[1]) self.reset() elif payload[1] == 'exit': dispatch_status('exit', 'request', 'from', address[1]) self.exit() elif payload[1] == 'get': dispatch_status('get', payload[0], 'from', address[1]) self.get(payload, address) elif payload[1] == 'set': dispatch_status('set', payload[0], 'from', address[1]) self.set(payload, address)