Пример #1
0
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
Пример #2
0
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
Пример #3
0
    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