def handle_snapshot(self, message, initial=True): print('snapshot_id: {}'.format(message.snapshot_id)) if not initial: print('From: {}'.format(message.branch_name)) # Set marker marker = bank_pb2.Marker() marker.branch_name = self.name marker.snapshot_id = message.snapshot_id # Create local snapshot to send later stored_snapshot = bank_pb2.ReturnSnapshot() stored_snapshot.local_snapshot.snapshot_id = message.snapshot_id # Set balance of local snapshot and default value channel_states stored_snapshot.local_snapshot.balance = self.balance stored_snapshot.local_snapshot.channel_state[:] = [ 0 for _ in range(len(self.branches)) ] print('Initial channel_state') print(stored_snapshot.local_snapshot.channel_state) # Store local snapshot which means it has seen snapshot_id self.snapshots[message.snapshot_id] = (stored_snapshot, True) self.channel_states[message.snapshot_id] = [ 0 for _ in range(len(self.branches)) ] if not initial: incoming_channel_index = self.get_branch_index(message.branch_name) # Set incoming channel as empty for snapshot self.channel_states[ message.snapshot_id][incoming_channel_index] = None new_message = bank_pb2.BranchMessage() new_message.marker.MergeFrom(marker) for sock in self.sockets: sock[1].acquire() self.message_socket(sock[0], new_message) sock[1].release()
def __init__(self): self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.s.bind((socket.gethostname(), int(sys.argv[2]))) self.s.listen(100) self.branch_names = [] self.branch_ip = [] self.branch_port = [] self.balance = 0 self.mutex = Lock() self.server_branch_Message = bank_pb2.BranchMessage() self.client_branch_Message = bank_pb2.BranchMessage() self.marker_Message = bank_pb2.Marker() self.local_snapshot_Message = bank_pb2.ReturnSnapshot.LocalSnapshot() self.my_name = '' self.sock_list = [self.s] self.sock_dict = {} self.sock_dict_rev = {} self.state = [] self.rec = [] self.fm = [] self.channel_state = [] self.m_rcvd = [] self.m_rcvd_cnt = [] self.m_sent = [] self.msg_count = 0 self.map = {} self.check_branch_names = [] self.check_branch_ip = [] self.check_branch_port = []
def send_markers(self, snapshot_id): branch_msg = bank_pb2.BranchMessage() markr = bank_pb2.Marker() markr.snapshot_id = snapshot_id markr.branch_name = self.branch_name branch_msg.marker.CopyFrom(markr) for connections in self.connections: connections.sendall(branch_msg.SerializeToString())
def handle_init_snapshot(cls, incoming_message): # Temporarily pause the money transfer MoneyTransferThread.set_enabled(False) # Grab the lock, since the current_snapshots data structure we modify ahead is shared between threads cls.marker_handler_lock.acquire() # Make sure that the new snapshot_id doesn't already exist snapshot_id = incoming_message.init_snapshot.snapshot_id if snapshot_id in cls.current_snapshots: print "ERROR! Got init snapshot again for snapshot id : " + str( snapshot_id) return print "Got init_snapshot msg (snapshot_id: " + str(snapshot_id) + ")" # Record local state current_balance = BankVault.get_balance() state = {"local": current_balance} cls.current_snapshots[snapshot_id] = state # Create marker message marker_msg = bank_pb2.Marker() marker_msg.snapshot_id = snapshot_id pb_msg = bank_pb2.BranchMessage() pb_msg.marker.CopyFrom(marker_msg) # Send marker message to everyone else total_peers = ThreadPool.get_thread_count() for i in range(total_peers): a_friend = ThreadPool.get_thread(i) if not a_friend: continue print "Sending marker message to : " + str(a_friend.remote_branch_name) + " (snapshot_id: "\ + str(snapshot_id) + ")" a_friend.send_msg_to_remote(pb_msg) # Start recording all incoming activity a_friend.add_recorder(snapshot_id) # Release the lock, we're done modifying the shared data structure cls.marker_handler_lock.release() # Resume the money transfer thread MoneyTransferThread.set_enabled(True)
def SendMarkers(self,snapshot_id): global branhList global moneyTransfer global branchName moneyTransfer = False markerMessage = bank_pb2.Marker() markerMessage.snapshot_id = snapshot_id markerMessage.src_branch = branchName branchMessage = bank_pb2.BranchMessage() branchMessage.marker.CopyFrom(markerMessage) for branch in branhList: markerSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) markerSocket.connect((branch.ip, branch.port)) markerSocket.sendall(pickle.dumps(branchMessage)) markerSocket.close() moneyTransfer = True
def sendMarkerToAll(self, snapshot_id): # Send a Marker message to all branches for port in self.branches.keys(): if port == self.port: continue # Create empty BranchMessage bm = bank_pb2.BranchMessage() marker = bank_pb2.Marker() marker.send_branch = self.name marker.snapshot_id = snapshot_id # Attach Marker to BranchMessage bm.marker.CopyFrom(marker) sent = self.sendMessage(bm, port) if sent: print('Sent Marker to port %i from port %i' % (port, self.port))
def receiver(client_socket): global balance global branches_all global branch_soc_list global curr_snap_id global this_branch global marker_count global RECORD while 1: received_message = client_socket.recv(1024) data = bank_pb2.BranchMessage() data.ParseFromString(received_message) if data.WhichOneof('branch_message') == 'init_branch': lock = threading.Lock() lock.acquire() balance = data.init_branch.balance lock.release() branches_add(data.init_branch.all_branches) connect_branches() sleep(5) print("calling sleep thread") try: th = Thread(target=sleep_thread, args=()) th.daemon = True th.start() except KeyboardInterrupt: exit() if data.WhichOneof('branch_message') == 'transfer': if not RECORD[int(data.transfer.src_branch)]: lock = threading.Lock() lock.acquire() balance += data.transfer.money print "Balance in the bank after getting transferred money:", balance lock.release() else: print "Recording", data.transfer.src_branch, "->", this_branch, data.transfer.money lock = threading.Lock() lock.acquire() if curr_snap_id not in global_snapshot: global_snapshot[curr_snap_id] = {} global_snapshot[curr_snap_id][ data.transfer.src_branch] = data.transfer.money lock.release() if data.WhichOneof('branch_message') == 'init_snapshot': print "Received init_snapshot for", this_branch, "with snap_id", data.init_snapshot.snapshot_id lock = threading.Lock() lock.acquire() for obj in RECORD: RECORD[obj] = True curr_snap_id = data.init_snapshot.snapshot_id if curr_snap_id not in global_snapshot: global_snapshot[curr_snap_id] = {} global_snapshot[curr_snap_id]['balance'] = balance lock.release() for banks in branch_soc_list: marker = bank_pb2.Marker() marker.src_branch = str(port) marker.dst_branch = str(banks) marker.snapshot_id = curr_snap_id send_message = bank_pb2.BranchMessage() send_message.marker.CopyFrom(marker) print "Sending marker to", banks, "for snapshot", curr_snap_id branch_soc_list[banks].sendall( send_message.SerializeToString()) if data.WhichOneof('branch_message') == 'marker': if data.marker.snapshot_id != curr_snap_id: print "Received marker from", data.marker.src_branch, "and snap_id is", data.marker.snapshot_id lock = threading.Lock() lock.acquire() for obj in RECORD: RECORD[obj] = True curr_snap_id = data.marker.snapshot_id if curr_snap_id not in global_snapshot: global_snapshot[curr_snap_id] = {} global_snapshot[curr_snap_id]['balance'] = balance lock.release() for banks in branch_soc_list: marker = bank_pb2.Marker() marker.src_branch = str(port) marker.dst_branch = str(banks) marker.snapshot_id = curr_snap_id send_message = bank_pb2.BranchMessage() send_message.marker.CopyFrom(marker) print "Sending marker to", banks, "for snapshot", curr_snap_id branch_soc_list[banks].sendall( send_message.SerializeToString()) if banks == data.marker.src_branch: RECORD[banks] = False elif marker_count < len(branches_all): print "Reply marker from", data.marker.src_branch, "for snapshot", data.marker.snapshot_id marker_count += 1 lock = threading.Lock() lock.acquire() RECORD[int(data.marker.src_branch)] = False if marker_count == len(branches_all): print "Received markers from all. Snapshot created" marker_count = 0 lock.release() if data.WhichOneof('branch_message') == 'retrieve_snapshot': print "Received retrieve_snapshot for", this_branch snapshot = bank_pb2.ReturnSnapshot() snapshot.local_snapshot.snapshot_id = data.retrieve_snapshot.snapshot_id for key, val in global_snapshot.items(): if key == data.retrieve_snapshot.snapshot_id: for key2, val2 in val.items(): if key2 != 'balance': snapshot.local_snapshot.channel_state.append( int(str(key2) + str(val2))) else: snapshot.local_snapshot.balance = val2 send_message = bank_pb2.BranchMessage() send_message.return_snapshot.CopyFrom(snapshot) client_socket.sendall(send_message.SerializeToString())
print "Received Amount %s from %s...Total Balance is %s\n" % ( str(data.transfer.money), str( client_address[0]), str(BRANCH_BALANCE)) if MARKER_MSG > 1 or isCapturing: isUpdate = False elif data.WhichOneof('branch_message') == 'init_snapshot': currentSnapId = data.init_snapshot.snapshot_id SNAPSHOTS[currentSnapId] = {} SNAPSHOTS[currentSnapId][sys.argv[1]] = BRANCH_BALANCE for branch in BRANCH_LIST: SNAPSHOTS[currentSnapId][branch["name"] + "->" + sys.argv[1]] = [] marker_msg = bank_pb2.Marker() marker_msg.snapshot_id = data.init_snapshot.snapshot_id msg = bank_pb2.BranchMessage() msg.marker.CopyFrom(marker_msg) for branch in BRANCH_LIST: s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((branch["ip"], branch["port"])) s.sendall(pickle.dumps(msg)) s.close() isCapturing = True elif data.WhichOneof('branch_message') == 'marker': if MARKER_MSG == 1: MARKER_MSG = MARKER_MSG + 1 if not isCapturing:
def handle_marker(cls, incoming_message, remote_branch_name): # Temporarily pause the money transfer MoneyTransferThread.set_enabled(False) # Grab the lock, since the current_snapshots data structure we modify ahead is shared between threads cls.marker_handler_lock.acquire() snapshot_id = incoming_message.marker.snapshot_id if snapshot_id in cls.current_snapshots: # This is a reply marker message print "Got reply marker msg from: " + str( remote_branch_name) + " (snapshot_id: " + str( snapshot_id) + ")" # Get the state of the channel on which this marker was received total_peers = ThreadPool.get_thread_count() for i in range(total_peers): a_friend = ThreadPool.get_thread(i) if not a_friend: continue if a_friend.remote_branch_name == remote_branch_name: # Channel found, get the money recorded on this channel money_in_flight = a_friend.pop_recorder(snapshot_id) # Record the state of the channel cls.current_snapshots[snapshot_id][str( remote_branch_name)] = money_in_flight break else: # This is the first marker message we're seeing print "Got the first marker msg from " + str(remote_branch_name) + " (snapshot_id: "\ + str(snapshot_id) + ")" # Record local state current_balance = BankVault.get_balance() state = {"local": current_balance} cls.current_snapshots[snapshot_id] = state # Record the state of the incoming channel from the sender to itself as empty cls.current_snapshots[snapshot_id][str(remote_branch_name)] = 0 # Create marker message marker_msg = bank_pb2.Marker() marker_msg.snapshot_id = snapshot_id pb_msg = bank_pb2.BranchMessage() pb_msg.marker.CopyFrom(marker_msg) # Send marker msg to all outgoing channels, except self total_peers = ThreadPool.get_thread_count() for i in range(total_peers): a_friend = ThreadPool.get_thread(i) if not a_friend: continue '''# MY HACK BEGIN --- ONLY FOR TESTING if a_friend.remote_branch_name == remote_branch_name: transfer_msg_h = bank_pb2.Transfer() pb_msg_h = bank_pb2.BranchMessage() transfer_msg_h.money = 10 pb_msg_h.transfer.CopyFrom(transfer_msg_h) a_friend.send_msg_to_remote(pb_msg_h) # MY HACK END ---''' print "Sending marker message to : " + str(a_friend.remote_branch_name) + " (snapshot_id: " \ + str(snapshot_id) + ")" a_friend.send_msg_to_remote(pb_msg) # Start recording all incoming activity if a_friend.remote_branch_name != remote_branch_name: a_friend.add_recorder(snapshot_id) # Release the lock, we're done modifying the shared data structure cls.marker_handler_lock.release() # Resume the money transfer thread MoneyTransferThread.set_enabled(True)
def thread_listener(sock, handler): init_received = False c_ip = '' c_port = 0 # Listen for init message while True: connection, client = sock.accept() try: while True: data = connection.recv(1024) if data: init_received = True msg = bank_pb2.BranchMessage() msg.ParseFromString(data) handler.balance = msg.init_branch.balance for i in msg.init_branch.all_branches: handler.b_counter = handler.b_counter + 1 handler.b_names.append(i.name) handler.b_ips.append(i.ip) handler.b_ports.append(i.port) handler.b_counter = handler.b_counter - 1 c_ip = handler.b_ips[handler.b_counter] c_port = handler.b_ports[handler.b_counter] handler.b_names.pop() handler.b_ips.pop() handler.b_ports.pop() else: break finally: connection.close() if init_received: handler.start_connecting = True break # Listen for other messages while True: connection, client = sock.accept() try: while True: data = connection.recv(1024) if data: msg = bank_pb2.BranchMessage() msg.ParseFromString(data) if msg.HasField('transfer'): money = msg.transfer.money # print handler.name + ' receives ' + str(money) + ' from ' + msg.transfer.branch_name # Update channel during snapshot algorithm # print ' ' + str(handler.b_recording) # print ' ' + msg.transfer.branch_name if msg.transfer.branch_name in handler.b_recording: # print ' ' + handler.name + ' receives and appends ' + str(money) + ' from ' + msg.transfer.branch_name handler.incoming_names.append(msg.transfer.branch_name) handler.incoming_balances.append(money) else: # print ' ' + handler.name + ' receives ' + str(money) + ' from ' + msg.transfer.branch_name balance_lock.acquire() handler.balance = handler.balance + money balance_lock.release() elif msg.HasField('init_snapshot'): # balance_lock.acquire() handler.markers_going = True # print handler.name + ' Init Snapshot received - local: ' + str(handler.balance) handler.state_balance = handler.balance handler.current_snapshot_id = msg.init_snapshot.snapshot_id for i in range(0, handler.b_counter): if handler.b_names[i] != handler.name: handler.b_recording.append(handler.b_names[i]) addr = (handler.b_ips[i], handler.b_ports[i]) try: m = bank_pb2.Marker() m.snapshot_id = handler.current_snapshot_id m.branch_name = handler.name msg = bank_pb2.BranchMessage() msg.marker.CopyFrom(m) # print handler.name + ' sends marker to ' + handler.b_names[i] s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect(addr) s.sendall(msg.SerializeToString()) except Exception as e: print handler.name + ' could not send the marker message' print e s.close() handler.markers_going = False # balance_lock.release() elif msg.HasField('marker'): # print 'marker msg received' # Not first marker message if handler.current_snapshot_id == msg.marker.snapshot_id: # print handler.name + ' Second marker received from ' + msg.marker.branch_name if msg.marker.branch_name in handler.b_recording: handler.b_recording.remove(msg.marker.branch_name) # First marker message else: # balance_lock.acquire() handler.markers_going = True mm = msg.marker.branch_name # print handler.name + ' First marker received from ' + mm + ' - local: ' + str(handler.balance) handler.current_snapshot_id = msg.marker.snapshot_id handler.state_balance = handler.balance # Set marker`s channel to 0 and start recording other channels handler.incoming_names.append(msg.marker.branch_name) handler.incoming_balances.append(0) for i in range(0, handler.b_counter): n = handler.b_names[i] if handler.name != n and mm != n: #print " mm: " + mm #print " record: " + n handler.b_recording.append(n) # Send markers if handler.name != n: addr = (handler.b_ips[i], handler.b_ports[i]) try: m = bank_pb2.Marker() m.snapshot_id = handler.current_snapshot_id m.branch_name = handler.name msg = bank_pb2.BranchMessage() msg.marker.CopyFrom(m) # print handler.name + ' sends marker to ' + handler.b_names[i] s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect(addr) s.sendall(msg.SerializeToString()) except: print handler.name + ' could not send the marker message from first' finally: s.close() handler.markers_going = False # balance_lock.release() elif msg.HasField('retrieve_snapshot'): # print handler.name + ' Retrieve Snapshot received' if msg.retrieve_snapshot.snapshot_id == handler.current_snapshot_id: # Send return snapshot message r = bank_pb2.ReturnSnapshot() r.local_snapshot.snapshot_id = handler.current_snapshot_id r.local_snapshot.balance = handler.state_balance names = [] balances = [] for index, i in enumerate(handler.incoming_names): if i not in names: names.append(i) balances.append(handler.incoming_balances[index]) else: ind = names.index(i) balances[ind] = balances[ind] + handler.incoming_balances[index] # Populate channel states for i in balances: # for i in handler.incoming_balances: r.local_snapshot.channel_state.append(i) msg = bank_pb2.BranchMessage() msg.return_snapshot.CopyFrom(r) s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server_address = (c_ip, c_port) s.connect(server_address) try: # print handler.name + ' Response sent' s.sendall(msg.SerializeToString()) except: print 'Could not send response message' finally: s.close() balance_lock.acquire() for i in balances: # for i in handler.incoming_balances: handler.balance = handler.balance + i balance_lock.release() handler.incoming_names = [] handler.incoming_balances = [] handler.b_recording = [] else: print 'Error in retrieve snapshot - ids do not match' else: print 'Incoming data has wrong protobuf format' break finally: connection.close()