def dispatch_insert(source, req_code, req_type, data):
    #data = {'key': key, 'value': value, resp_ip_port:"None" , 'index': 0}
    key = data['key']
    value = data['value']
    index = data['index']
    resp_ip_port = data['resp_ip_port']
    if is_responsible(key):
        resp_ip_port = node.ip_port
        text = node.insert(key, value, index)
        #check if last --> if so respond to source and return
        if index == int(
                node.get_replicas()) - 1 or node.succ_ip_port == resp_ip_port:
            resp_text = text + " at node:" + node.ip_port
            resp = make_resp(source, req_type, {'resp_text': resp_text},
                             req_code)
            post_resp_thread(source, resp)
            #its important to return here
            return
        else:
            #if type == eventual respond to source
            if node.get_rep_type() == "eventual":
                resp_text = text + " at node:" + node.ip_port
                resp = make_resp(source, req_type, {'resp_text': resp_text},
                                 req_code)
                post_resp_thread(source, resp)
            #now forward request to next node
            new_req = make_same_req(
                source, req_type, {
                    'key': key,
                    'value': value,
                    'resp_ip_port': resp_ip_port,
                    'index': index + 1
                }, req_code)
            post_req_thread(node.succ_ip_port, new_req)
    elif index == 0:
        #request hasnt reached responsible yet--> just forward it to next
        new_req = make_same_req(source, req_type, data, req_code)
        post_req_thread(node.succ_ip_port, new_req)
    else:
        text = node.insert(key, value, index)
        # if last_node dont forward , also if linear.. respond to source
        if index == node.get_replicas(
        ) - 1 or node.succ_ip_port == resp_ip_port:
            if node.get_rep_type() == "linearizability":
                resp_text = text + " at node:" + node.ip_port
                resp = make_resp(source, req_type, {'resp_text': resp_text},
                                 req_code)
                post_resp_thread(source, resp)
        else:
            #if not last node --> forward changed req to succ
            new_req = make_same_req(
                source, req_type, {
                    'key': key,
                    'value': value,
                    'resp_ip_port': resp_ip_port,
                    'index': index + 1
                }, req_code)
            post_req_thread(node.succ_ip_port, new_req)

    return
def ntwresp():
    global number_of_nodes
    resp_dict = json.loads(request.data)
    if resp_dict['type'] == 'set_neighboors':
        prev_ip_port = resp_dict['prev']
        succ_ip_port = resp_dict['succ']
        node.set_neighboors(prev_ip_port, succ_ip_port)
    elif resp_dict['type'] == 'join_vars':
        repn = resp_dict['data']['repn']
        rep_type = resp_dict['data']['rep_type']
        node.join_set_vars(repn, rep_type)
    elif resp_dict['type'] == 'K_nodes':
        if (node.get_replicas() == number_of_nodes):
            return {'K_nodes': 'True'}
        else:
            return {'K_nodes': 'False'}
    elif (resp_dict['type'] == 'inc_number'):
        number_of_nodes += 1
    elif (resp_dict['type'] == 'dec_number'):
        number_of_nodes -= 1
    elif (resp_dict['type'] == 'nodes_in_chord'):
        return {'nodes_in_chord': number_of_nodes}
    else:
        seqn = resp_dict['seqn']
        responses_dict[seqn] = resp_dict
    return {}
Exemplo n.º 3
0
def join():
    # its important to stall join request so that our server has started properly and then we can get the boot server response
    global seqn
    seqn = seqn + 1
    req_code = str(seqn)
    # 1) kane join to node sto chord kai ftiakse tous pointers tou kai twn geitonwn tou kai dwstou kai ta kleidia tou epomenou same keys  new_keys
    # 2) gia tous epomenous k nodes ektelese new ntw_req --> ( source, type="join_upd_chain" , req_code, data { index:0 , same_keys, new_keys }    )
    # 3) pare ta keys_vals tou prevs stis theseis 0 ews k-1 kai valta stis dikes sou 1 ews k-1
    # 4) respond to user
    data = {'key': node.id}
    req = make_req('join', data, req_code)

    post_req_thread(node.boot_ip_port, req)
    while responses_dict.get(req_code, "None") == "None":
        {}
    # pop response from dict and handle it
    resp = responses_dict.pop(req_code)
    # apo to response pairnw ta same_keys, new_keys, kai ftiaxnw kai tous geitones mou
    same_keys = resp['data']['same_keys']
    new_keys = resp['data']['new_keys']
    node.prev_ip_port = resp['data']['prev']
    node.succ_ip_port = resp['data']['succ']
    # ta new_keys einai ta keys gia ta opoia twra tha eisai responsible
    node.keys_vals[0] = new_keys
    data = {'index': 0, 'same_keys': same_keys, 'new_keys': new_keys}
    req = make_req('join_upd_chain', data, req_code)
    # post request to next node so that all chain of replicas updates
    post_req_thread(node.succ_ip_port, req)
    while responses_dict.get(req_code, "None") == "None":
        {}
    responses_dict.pop(req_code)
    # get_keys request from prev
    req = make_req('get_keys', {}, req_code)
    post_req_thread(node.prev_ip_port, req)
    while responses_dict.get(req_code, "None") == "None":
        {}
    resp = responses_dict.pop(req_code)
    prev_keys = resp['data']['keys']

    post_resp_to(node.boot_ip_port, {'type': 'inc_number'})

    # vale ta keys 0--k-2 tou prev sta dika sou 1--k-1
    # if nodes_in_chord < k then go till nodes_in_chord -1 element
    nodes_in_chord = requests.post("http://" + node.boot_ip_port + "/ntwresp",
                                   json={'type': 'nodes_in_chord'})
    nodes_in_chord = json.loads(nodes_in_chord.text)['nodes_in_chord']
    limit = min(nodes_in_chord, node.get_replicas())
    for i in range(limit - 1):
        node.keys_vals[i + 1] = prev_keys[i]

    msg = ("Node joined succesfully")

    return msg
Exemplo n.º 4
0
def dispatch_depart(source, req_code, req_type, data):
    #update data  --> first node has to add his keys[0] to new_keys  , every node has to put his last keys to last_keys
    #if node isnt last forward next
    #else respond to source
    index = data['index']
    new_keys = data['new_keys']
    last_keys = data['last_keys']
    K_nodes = data['K_nodes']
    if (index == 0):
        new_keys.update(node.keys_vals[index])
    node.keys_vals[index] = new_keys
    if (index + 1 < node.get_replicas() - 1):
        node.pushup(index + 1)
    if (index + 1 <= node.get_replicas() - 1):
        #if there are  K nodes then we should put {} to last keys else do what we do
        if (K_nodes == 'True'):
            node.keys_vals[node.get_replicas() - 1] = {}
        else:
            node.keys_vals[node.get_replicas() - 1] = last_keys
    #check if last_node
    if (index == node.get_replicas() - 1 or node.succ_ip_port == source):
        resp = make_resp(source, req_type, {}, req_code)
        post_resp_thread(source, resp)
    else:
        new_data = {
            'index': index + 1,
            'new_keys': new_keys,
            'last_keys': node.keys_vals[node.get_replicas() - 2],
            'K_nodes': K_nodes
        }
        req = make_same_req(source, req_type, new_data, req_code)
        post_req_thread(node.succ_ip_port, req)
    return
def dispatch_join(source, req_code, req_type, data):
    #if this node is prev ( this.succ== is_responsible ) update its next to source  put its ip to prev datum and forward request to next
    #if this node is_resp === is next   update its prev to source put its ip to succ datum and get same_keys , new_keys and respond to source
    #if nothing of the above just forward to next node

    #### THIS IS ONLY FOR BOOTSTRAP NODE --> IT SENDS THE NODE THAT JOINS REPN AND REP_TYPE INFORMATION####
    resp = make_resp(source, 'join_vars', {
        'repn': node.get_replicas(),
        'rep_type': node.get_rep_type()
    }, req_code)
    post_resp_to(source, resp)
    #######################################################################################################
    if (is_responsible(data['key'])):
        ######only for bootstrap cause he is the first to receive join req
        ######if he is responsible its the only case when we dont pass from the prev
        ######so we must set the data['prev']=node.prev_ip_port
        ###### and also send request to prev to update its succ to the source
        data['prev'] = node.prev_ip_port

        post_resp_to(node.prev_ip_port, {
            'type': 'set_neighboors',
            'prev': "None",
            'succ': source
        })
        ######

        data['succ'] = node.ip_port
        same_new = node.get_same_new_keys(data['key'])
        data['same_keys'] = same_new[0]
        data['new_keys'] = same_new[1]
        if (node.is_alone()):
            # special case --> here we are previous also so we must fix those values too

            node.succ_ip_port = source
            node.prev_ip_port = source
            data['prev'] = node.ip_port
        #respond to source
        node.prev_ip_port = source
        resp = make_resp(source, req_type, data, req_code)
        post_resp_thread(source, resp)

    elif (succ_is_responsible(data['key'])):
        temp = node.succ_ip_port
        node.succ_ip_port = source
        data['prev'] = node.ip_port
        req = make_same_req(source, req_type, data, req_code)
        post_req_thread(temp, req)
    else:
        req = make_same_req(source, req_type, data, req_code)
        post_req_thread(node.succ_ip_port, req)
    return
Exemplo n.º 6
0
def dispatch_join_upd_chain(source, req_code, req_type, data):
    #exei ginei idi to join tou komvou kai exoun enimerwthei oloi oi pointers
    same_keys = data['same_keys']
    new_keys = data['new_keys']
    index = data['index']
    # update data
    node.keys_vals[index] = same_keys
    if (index + 2 < node.get_replicas()):
        node.pushdown(index + 2)
    if (index + 1 < node.get_replicas()):
        node.keys_vals[index + 1] = new_keys
    # if not last node forward next
    if (index != node.get_replicas() - 1 and node.succ_ip_port != source):
        req = make_same_req(source, req_type, {
            'index': index + 1,
            'same_keys': same_keys,
            'new_keys': new_keys
        }, req_code)
        post_req_thread(node.succ_ip_port, req)
    else:
        #make response forward source
        resp = make_resp(source, req_type, {}, req_code)
        post_resp_thread(source, resp)
    return
Exemplo n.º 7
0
def dispatch_query(source, req_code, req_type, data):
    #data = {'key': key, 'value': "None", "resp_ip_port": "None", 'index': 0}
    key = data['key']
    value = data['value']
    resp_ip_port = data['resp_ip_port']
    index = data['index']
    # for eventual consistency, if not found once we dont search for key again until it reaches resp, there is no point
    #make this an array of one element so i can change it later
    failed_to_find = data['failed_to_find']
    k = node.get_replicas()
    if is_responsible(key):
        resp_ip_port = node.ip_port
        value = node.query(key)
        if node.get_rep_type() == "eventual":
            if value != "None":
                resp_text = "has value:" + value + " found at node:" + node.ip_port
                resp = make_resp(source, req_type, {'resp_text': resp_text},
                                 req_code)
                post_resp_thread(source, resp)
                return
        #if node isnt last forward request
        if index != k - 1 and node.succ_ip_port != resp_ip_port:
            req = make_same_req(
                source, req_type, {
                    'key': key,
                    'value': value,
                    'resp_ip_port': resp_ip_port,
                    'index': index + 1,
                    'failed_to_find': failed_to_find
                }, req_code)
            post_req_thread(node.succ_ip_port, req)
        else:
            #is last node respond to source
            if value == "None":
                resp_text = "not found at node " + node.ip_port
            else:
                resp_text = "has value:" + value + " found at node:" + node.ip_port
            resp = make_resp(source, req_type, {'resp_text': resp_text},
                             req_code)
            post_resp_thread(source, resp)
    else:
        #isnt responsible
        if index == 0:
            #hasnt reached resposible yet
            if node.get_rep_type() == "eventual":
                if not failed_to_find[0]:
                    #this query should be executed only once!
                    value = node.query(key)
                    if (value != "None"):
                        resp_text = "has value:" + value + " found at node:" + node.ip_port
                        resp = make_resp(source, req_type,
                                         {'resp_text': resp_text}, req_code)
                        post_resp_thread(source, resp)
                        return
                    else:
                        failed_to_find[0] = True
            req = make_same_req(
                source, req_type, {
                    'key': key,
                    'value': value,
                    'resp_ip_port': resp_ip_port,
                    'index': index,
                    'failed_to_find': failed_to_find
                }, req_code)
            post_req_thread(node.succ_ip_port, req)
        else:
            #it has reached responsible
            new_val = node.query(key)
            if new_val != "None":
                value = new_val
                if node.get_rep_type() == "eventual":
                    resp_text = "has value:" + value + " found at node:" + node.ip_port
                    resp = make_resp(source, req_type,
                                     {'resp_text': resp_text}, req_code)
                    post_resp_thread(source, resp)
                    return
            if index != k - 1 and node.succ_ip_port != resp_ip_port:
                #its not last node-->forward request
                req = make_same_req(
                    source, req_type, {
                        'key': key,
                        'value': value,
                        'resp_ip_port': resp_ip_port,
                        'index': index + 1,
                        'failed_to_find': failed_to_find
                    }, req_code)
                post_req_thread(node.succ_ip_port, req)
            else:
                #its last node respond to source
                if value == "None":
                    resp_text = "not found at node " + node.ip_port
                else:
                    resp_text = "has value:" + value + " found at node:" + node.ip_port
                resp = make_resp(source, req_type, {'resp_text': resp_text},
                                 req_code)
                post_resp_thread(source, resp)
    return
Exemplo n.º 8
0
def depart():
    if request.method == 'POST':

        if not node.get_isInChord():
            return 'This node does not participate in Chord!\n'
        else:
            # Στις επόμενες 4 γραμμές, μαζεύω τα data που θα στείλω στον successor
            global seqn
            seqn = seqn + 1
            req_code = str(seqn)
            new_keys = node.keys_vals[0]
            last_keys = node.keys_vals[node.get_replicas() - 1]
            #send message to boot to find out K_nodes value

            boot_resp = requests.post("http://" + node.boot_ip_port +
                                      "/ntwresp",
                                      json={'type': 'K_nodes'})
            K_nodes = json.loads(boot_resp.text)['K_nodes']
            data = {
                'index': 0,
                'new_keys': new_keys,
                'last_keys': last_keys,
                'K_nodes': K_nodes
            }

            if node.is_alone():
                node.init_state()
                return f"Node {node.ip_port} departed from the Chord!\n"
            else:
                #make depart request and post to next node--> it will update all the rm chain
                req = make_req('depart', data, req_code)
                post_req_thread(node.succ_ip_port, req)
                while responses_dict.get(req_code, "None") == "None":
                    {}
                responses_dict.pop(req_code)
                # then take care of the neighbour pointers
                # data = {'prev': node.prev_ip_port, 'succ': node.succ_ip_port, 'type':'set_neighboors'}
                prev = node.prev_ip_port
                succ = node.succ_ip_port
                if node.is_duo():
                    # an exoume mono 2 nodes tote prepei na steiloume na enimerwsei kai ton next kai ton prev o enas mas geitonas
                    #to parakatw tha perimenei mexri na lavoume apantisi
                    post_resp_to(node.prev_ip_port, {
                        'prev': prev,
                        'succ': succ,
                        'type': 'set_neighboors'
                    })
                else:
                    #an uparxoun toul 3 komvoi stelnoume kai ston prev kai ston next na enimerwsoun mono ton enan geitona tous ekastos
                    post_resp_to(node.prev_ip_port, {
                        'prev': "None",
                        'succ': succ,
                        'type': 'set_neighboors'
                    })
                    post_resp_to(node.succ_ip_port, {
                        'prev': prev,
                        'succ': "None",
                        'type': 'set_neighboors'
                    })
                # Then return the node to dafault state
                node.init_state()
                post_resp_to(node.boot_ip_port, {'type': 'dec_number'})
            return f"Node {node.ip_port} successfully departed from Chord!\n"