def gossip(): # checks if I am currently gossiping with someone else if not shard.gossiping: shard.lastToGossip = False incoming_data = json.loads(request.get_json()) shard.gossiping = True # causal context of the incoming node trying to gossip other_context = incoming_data["causal-context"] # key store of incoming node trying to gossip other_kvstore = incoming_data["kv-store"] # this is true if the other node determined i will be the tiebreaker tiebreaker = True if incoming_data["tiebreaker"] == ADDRESS else False incoming_Vc = VectorClock(view=None, clock=other_context) if other_kvstore == shard.keystore: shard.gossiping = False return jsonify({"message": "We're equal."}), 201 elif incoming_Vc.allFieldsZero(): shard.gossiping = False return jsonify({"message": "You dont have any data"}), 201 elif incoming_Vc.selfHappensBefore(shard.VC.__repr__()): # I am at least concurrent or after shard.gossiping = False return jsonify({"message": "I Don't need yours."}), 201 elif incoming_Vc.__repr__() != shard.VC.__repr__(): shard.keystore = other_kvstore shard.VC.merge(other_context, ADDRESS) shard.gossiping = False return jsonify({"message": "I took your data"}), 200 return jsonify({"message": "gossiping"}), 201
def gossip(): # checks if I am currently gossiping with someone else if not shard.gossiping: incoming_data = json.loads(request.get_json()) shard.gossiping = True # causal context of the incoming node trying to gossip other_context = incoming_data["context"] # key store of incoming node trying to gossip other_kvstore = incoming_data["kv-store"] if other_kvstore == shard.keystore: return jsonify({"message": "We're equal."}), 200 # this is true if the other node determined i will be the tiebreaker tiebreaker = True if incoming_data["tiebreaker"] == ADDRESS else False incoming_Vc = VectorClock(view=None, clock=other_context) if shard.VC.selfHappensBefore(other_context): # I am before # i accept your data shard.keystore = other_kvstore shard.VC.merge(other_context, ADDRESS) shard.gossiping = False print("I HAPPENED BEFORE, I TAKE YOU" + str(shard.keystore), file=sys.stderr) return jsonify({"message": "I took your data"}), 200 elif incoming_Vc.selfHappensBefore(shard.VC.__repr__()): # I am after the incoming one, so return my data shard.gossiping = False return jsonify({ "message": "I am after you, take my data", "context": shard.VC.__repr__(), "kv-store": shard.keystore, }), 501 elif tiebreaker: shard.gossiping = False return jsonify({ "message": "I am the tiebreaker, take my data", "context": shard.VC.__repr__(), "kv-store": shard.keystore, }), 501 elif not tiebreaker: if bool(other_kvstore) and not incoming_Vc.allFieldsZero(): shard.keystore = other_kvstore shard.VC.merge(other_context, ADDRESS) shard.gossiping = False print("I DID NOT HAPPEN BEFORE BUT AM NOT THE TIEBREAKER" + str(shard.keystore), file=sys.stderr) return jsonify({"message": "I took your data"}), 200 shard.gossiping = False return jsonify({"message": "I am gossiping with someone else"}), 400
def gossip(self): if (self.gossiping == False): current_key_store = self.keystore self.gossiping = True replica_ip_addresses = self.shard_replicas(self.shard_ID) replica = replica_ip_addresses[(random.randint( 0, len(replica_ip_addresses) - 1))] while (self.ADDRESS == replica): replica = replica_ip_addresses[(random.randint( 0, len(replica_ip_addresses) - 1))] myNumber = int((self.ADDRESS.split(".")[3]).split(":")[0]) otherNumber = int((replica.split(".")[3]).split(":")[0]) tiebreaker = replica if (otherNumber > myNumber) else self.ADDRESS data = { "context": self.VC.__repr__(), "kv-store": current_key_store, "tiebreaker": tiebreaker } print("sending to node: " + replica + " " + str(data), file=sys.stderr) try: response = self.router.PUT(replica, '/kv-store/internal/gossip/', json.dumps(data)) except: code = -1 code = response.status_code if (code == 200): # 200: They took my data self.gossiping = False elif (code == 501): content = response.json() # 501: # the other node was either the tiebreaker or happened after self # so this node takes its data # context of node other_context = content["context"] # key store of incoming node trying to gossip other_kvstore = content["kv-store"] incoming_Vc = VectorClock(view=None, clock=other_context) if bool(other_kvstore) and not incoming_Vc.allFieldsZero(): if current_key_store == self.keystore: print("I TOOK DATA: " + str(self.keystore), file=sys.stderr) self.VC.merge(other_context, self.ADDRESS) self.keystore = other_kvstore else: print("I RECIEVED AN UPDATE WHILE GOSSIPING, ABORT", file=sys.stderr) self.gossip = False #self happened before other, take its kvstore and merge with my clock # concurrent but other is tiebreaker else: # 400: Other is already gossiping with someone else # ELSE: unresponsive node (maybe itll be code 404?) self.gossiping = False else: # Curretly gossiping, # Will call after gossip backoff again self.gossiping = False return 200