Ejemplo n.º 1
0
def lfd_ping(lfd_id, lfd_addr):
    sudp_ping = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    sudp_ping.settimeout(1)
    while True:
        msg = messager.encodeMsg(20, 0, "")
        sudp_ping.sendto(msg.encode('utf-8'), lfd_addr)
        try:
            sudp_ping.recvfrom(buffSize)

            logging.info("lfd %d login", lfd_id)
            break
        except socket.timeout:
            continue
    while True:
        while True:
            time.sleep(interval)
            sudp_ping.sendto(msg.encode('utf-8'), lfd_addr)
            tried = 0
            while tried < retry:
                try:
                    sudp_ping.recvfrom(buffSize)
                    logging.info("lfd %d beating freq: %d retry: %d", lfd_id,
                                 interval, retry)
                    break
                except socket.timeout:
                    logging.info("No response, try %d times", tried)
                    tried += 1
                # Should never goes here
                except socket.error:
                    logging.error("Critical error")
            if tried == 3:
                logging.error("NO Heartbeating")
                print("lfd %d down", lfd_id)
                break
Ejemplo n.º 2
0
def ping(sock):
    global ACTIVE
    global INIT_LOGIN
    addr = ((host, port))

    while True:
        time.sleep(interval)

        ping_str = messager.encodeHeartbeat(sid)
        msg = messager.encodeMsg(messager.MSG_PING,
                                 len(ping_str) + 1, ping_str)
        sock.sendto(bytes(msg, 'utf-8'), addr)
        tried = 0
        while tried < retry:
            try:
                data, addr = sock.recvfrom(buffSize)
                logging.info("beating freq: %d retry: %d", interval, retry)
                if (not ACTIVE):
                    c = messager.encodeInit(messager.MSG_ROLE_SERVER, sid)
                    if INIT_LOGIN:
                        msg = messager.encodeMsg(messager.MSG_INIT,
                                                 len(c) + 1, c)
                    else:
                        msg = messager.encodeMsg(messager.MSG_RECOVERY,
                                                 len(c) + 1, c)
                    sudp_handle.sendto(bytes(msg, "utf-8"),
                                       ((ip_gfd, port_gfd)))
                    logging.info("server %d active", sid)
                    ACTIVE = True
                break
            except socket.timeout:
                logging.info("No response, try %d times", tried)
                tried += 1

            # Should never goes here
            except socket.error:
                logging.error("Critical error")

        if tried == 3:
            logging.error("NO Heartbeating")
            if ACTIVE:
                c = messager.encodeInit(messager.MSG_ROLE_LFD, sid)
                msg = messager.encodeMsg(messager.MSG_FAULT, len(c) + 1, c)
                sudp.sendto(bytes(msg, "utf-8"), ((ip_gfd, port_gfd)))
                ACTIVE = False
                INIT_LOGIN = False
            break
def handleUDP(data):
    global ACTIVE
    global BLOCK_FLAG
    global log
    global state
    global quiet_lock
    global num_client
    global num_blocked

    sock = data
    tdata = threading.local()

    while True:
        try:
            tdata.data, tdata.addr = sock.recvfrom(buffSize)
        except socket.timeout:
            exit(0)

        tdata.t, tdata.s, tdata.c = messager.decodeMsg(
            tdata.data.decode('utf-8'))
        if tdata.t == messager.MSG_CHECKPOINT:
            with __lock:
                if tdata.s == 1:
                    tdata.data = messager.encodeMsg(messager.MSG_CHECKPOINT, 2,
                                                    state)
                    sock.sendto(bytes(tdata.data, 'utf-8'),
                                (tdata.c[0], tdata.c[1]))
                elif tdata.s == 2:
                    print("after checkpoint state is : ", tdata.c)
                else:
                    tdata.cid, tdata.sid, tdata.seq, tdata.ts, tdata.state = messager.decodeUpdateState(
                        tdata.c)
                    print("checkpoint state is : ", tdata.state)
                    state = tdata.state
                    for i in range(len(log)):
                        if log[i][0] == tdata.cid and log[i][2] == tdata.seq:
                            break
                    log = log[i:]
                    print("obtain useful log:")
                    for i in log:
                        print(i)
                    for i in log:
                        state = i[4]
                        logging.info(
                            "client: %i ,server: %i, seq: %i, time: %s,state: %s",
                            i[0], i[1], i[2], i[3], i[4])
                    log = []
                    quiet_lock = False
        if tdata.t == messager.MSG_LFD_SERVER_INIT:
            print('recv lfd init')
            sudp.sendto(tdata.data, tdata.addr)
        # Heartbeating
        if tdata.t == messager.MSG_PING:
            if sid == messager.decodeHeartbeat(tdata.c):
                tdata.data = messager.encodeMsg(messager.MSG_BEATING, tdata.s,
                                                tdata.c)
                sock.sendto(bytes(tdata.data, 'utf-8'), tdata.addr)
            # Should Never happen, but just in case
            else:
                tdata.data = messager.encodeMsg(messager.MSG_ERROR, tdata.s,
                                                tdata.c)
                sock.sendto(bytes(tdata.data, 'utf-8'), tdata.addr)

        elif tdata.t == messager.MSG_ACTIVE:
            with __lock:
                ACTIVE = True
            logging.info("Become active")

        elif tdata.t == messager.MSG_QUIET:
            with __lock:
                quiet_lock = True

            logging.info("Become quiet")

        elif tdata.t == messager.MSG_CHECK_REMIND:
            with __lock:
                tosid = int(tdata.c)

                print("sid:", tosid)
                if tosid == 1:
                    sendToCheck = 10087
                if tosid == 2:
                    sendToCheck = 10088
                if tosid == 3:
                    sendToCheck = 10089
                BLOCK_FLAG = True
                check_state = state
                print("checkpointing")
                print("send checkpoint. state:", check_state)

            #logging.info("%d %d", num_blocked, num_client)
            while num_blocked < num_client:
                continue
            #logging.info("%d %d", num_blocked, num_client)

            with __lock:
                tdata.c = messager.encodeUpdateState(log[0][0], log[0][1],
                                                     log[0][2], log[0][3],
                                                     check_state)
                msg = messager.encodeMsg(messager.MSG_CHECKPOINT, 0, tdata.c)
                sock.sendto(msg.encode('utf-8'), ("localhost", sendToCheck))
                BLOCK_FLAG = False
                log = []
                num_client = 0
def handleTCP(data):
    global state
    global log
    global num_client
    global num_blocked
    sock = data[0]
    tdata = threading.local()
    tdata.cid = 0

    recovered = False

    with __lock:
        num_client += 1

    while True:
        tdata.data = sock.recv(buffSize)

        if not tdata.data:
            # logging.info("CID: %i exit (0 is UNKNOWN)", tdata.cid)
            with __lock:
                num_client -= 1
            sock.close()
            return

        tdata.t, tdata.s, tdata.c = messager.decodeMsg(
            tdata.data.decode('utf-8'))
        # Update state, may be better to have a dedicate function
        if tdata.t == messager.MSG_UPDATESTATE:

            # cid, seq, state
            tdata.cid, tdata.sid, tdata.seq, tdata.ts, tdata.state = messager.decodeUpdateState(
                tdata.c)
            item = [tdata.cid, tdata.sid, tdata.seq, tdata.ts, tdata.state]

            with __lock:
                if ACTIVE == False:
                    logging.error("NOT ACTIVE")
                    log.append([
                        tdata.cid, tdata.sid, tdata.seq, tdata.ts, tdata.state
                    ])
                    print("log:")
                    for i in log:
                        print(i)
                    tdata.c = "SERVER NOT ACTIVE"
                    tdata.data = messager.encodeMsg(messager.MSG_ERROR,
                                                    len(tdata.c), tdata.c)
                    sock.send(bytes(tdata.data, 'utf-8'))

                    #with __lock:
                    #num_client -= 1
                    #sock.close()
                    continue

            with __lock:
                # Send
                if quiet_lock:
                    logging.info("NOT ACTIVE")
                    log.append([
                        tdata.cid, tdata.sid, tdata.seq, tdata.ts, tdata.state
                    ])
                    print("log:")
                    for i in log:
                        print(i)
                    tdata.data = messager.encodeMsg(messager.MSG_UPDATESTATE,
                                                    0, tdata.c)
                    sock.send(bytes(tdata.data, 'utf-8'))
                    continue

            __lock.acquire()  # Racing Condition
            state = tdata.state
            logging.info("client: %i ,server: %i, seq: %i, time: %s,state: %s",
                         tdata.cid, tdata.sid, tdata.seq, tdata.ts, state)

            if BLOCK_FLAG:
                num_blocked += 1
                log.append(
                    [tdata.cid, tdata.sid, tdata.seq, tdata.ts, tdata.state])
                recovered = True
            __lock.release()

            while BLOCK_FLAG:  # Busy wait for very short period
                continue

            with __lock:
                tdata.data = messager.encodeMsg(messager.MSG_UPDATESTATE, 0,
                                                tdata.c)
                sock.send(tdata.data.encode('utf-8'))
                if recovered:
                    time.sleep(0.2)
                    recovered = False
Ejemplo n.º 5
0
def handleUDP(sock):

    while True:
        data, addr = sock.recvfrom(buffSize)
        sock.sendto(data, (ip_repmgn, port_repmgn))

        t, s, c = messager.decodeMsg(data.decode('utf-8'))

        if (t == messager.MSG_INIT):
            role, ID = messager.decodeInit(c)
            factive = False

            idaddr = {"id": ID, "addr": addr}

            if online(idaddr):
                logging.error("Already login")
                continue

            if (role == messager.MSG_ROLE_SERVER):
                if _primary:
                    if ID == 1:
                        msg = messager.encodeMsg(messager.MSG_CHECKPOINT, 1,
                                                 ("localhost", 10087))
                    elif ID == 2:
                        msg = messager.encodeMsg(messager.MSG_CHECKPOINT, 1,
                                                 ("localhost", 10088))
                    elif ID == 3:
                        msg = messager.encodeMsg(messager.MSG_CHECKPOINT, 1,
                                                 ("localhost", 10089))
                    if int(_primary[0]['id']) == 1:
                        sock.sendto(bytes(msg, 'utf-8'), ('localhost', 10087))
                    elif int(_primary[0]['id']) == 2:
                        sock.sendto(bytes(msg, 'utf-8'), ('localhost', 10088))
                    elif int(_primary[0]['id']) == 3:
                        sock.sendto(bytes(msg, 'utf-8'), ('localhost', 10089))
                    _backup.append(idaddr)
                else:
                    _primary.append(idaddr)
                factive = True

            elif (role == messager.MSG_ROLE_LFD):
                _lfd.append(idaddr)

            msg = messager.encodeMsg(messager.MSG_SUCCESS, 1, "")
            sock.sendto(bytes(msg, 'utf-8'), addr)
            logging.info('id: %d login', ID)
            print("membership:")
            print("Current primary:")
            for p in _primary:
                print(p)
            print("Current backup:")
            for b in _backup:
                print(b)

            if factive:
                msg = messager.encodeMsg(messager.MSG_ACTIVE, 1, "")
                sock.sendto(bytes(msg, 'utf-8'), addr)
                logging.info('id: %d activing', ID)
                if _primary:
                    firstPrimaryMessage = messager.encodeMsg(
                        messager.MSG_INIT_PRIMARY, 1, "")
                    if int(_primary[0]['id']) == 1:
                        sock.sendto(bytes(firstPrimaryMessage, 'utf-8'),
                                    ('localhost', 10087))
                    if int(_primary[0]['id']) == 2:
                        sock.sendto(bytes(firstPrimaryMessage, 'utf-8'),
                                    ('localhost', 10088))
                    if int(_primary[0]['id']) == 3:
                        sock.sendto(bytes(firstPrimaryMessage, 'utf-8'),
                                    ('localhost', 10089))
        #server down with lfd message
        if (t == messager.MSG_FAULT):
            role, ID = messager.decodeInit(c)

            if (role == messager.MSG_ROLE_LFD):
                for s in _primary:
                    if s["id"] == ID:
                        _primary.remove(s)  # primary done
                        if _backup:  # if there is still backup alive
                            _primary.append(
                                _backup[0]
                            )  #wake up one of the backup and make it primary
                            _backup.pop(0)
                            msg = messager.encodeMsg(messager.MSG_WAKE, 1, '')
                            if int(_primary[0]['id']) == 1:
                                sock.sendto(msg.encode("utf-8"),
                                            ("localhost", 10087))
                            elif int(_primary[0]['id']) == 2:
                                sock.sendto(msg.encode("utf-8"),
                                            ("localhost", 10088))
                            elif int(_primary[0]['id']) == 3:
                                sock.sendto(msg.encode("utf-8"),
                                            ("localhost", 10089))
                            break
                for b in _backup:
                    if b["id"] == ID:
                        _backup.remove(b)
                        break

            ###
            ## c = messager.encodeInit(messager.MSG_ROLE_REPMGN, ID)

            ###
            print("server down. ID:", ID)
            print("membership:")
            print("Current primary:")
            for p in _primary:
                print(p)
            print("Current backup:")
            for b in _backup:
                print(b)
def handleUDP(data):
    global ACTIVE
    global primaryFlag
    global state
    global Checkpoint_turn
    global Log
    global state
    sock = data
    tdata = threading.local()

    while True:
        try:
            tdata.data, tdata.addr = sock.recvfrom(buffSize)
        except socket.timeout:
            exit(0)

        tdata.t, tdata.s, tdata.c = messager.decodeMsg(
            tdata.data.decode('utf-8'))

        # intial primary
        if tdata.t == messager.MSG_INIT_PRIMARY:
            primaryFlag = True
            print("I am primary!")
            # checkpointing sent if it is primary
        # wake up to be primary and recover
        if tdata.t == messager.MSG_WAKE:
            # recover
            with __lock:
                print("i am waking up")
                primaryFlag = True
                print(
                    "Recovery start. Prune log and process unreplied requests")
                if Log == []:
                    print("Recovery done. Current state:", state)
        #initial checkpoint
        if tdata.t == messager.MSG_CHECKPOINT and primaryFlag == True:
            with __lock:
                msg = messager.encodeMsg(messager.MSG_CHECKPOINT,
                                         len(state) + 1, state)
                sock.sendto(bytes(msg, 'utf-8'), (tdata.c[0], tdata.c[1]))
        # recv checkpoint it is a backup
        if tdata.t == messager.MSG_CHECKPOINT and primaryFlag == False:
            with __lock:
                state = tdata.c
                Log = []
                print('After checkpointing, current state is: ', state)
        if tdata.t == messager.MSG_LFD_SERVER_INIT:
            print('recv lfd init')
            sudp.sendto(tdata.data, tdata.addr)
        # Heartbeating
        if tdata.t == messager.MSG_PING:
            if sid == messager.decodeHeartbeat(tdata.c):
                tdata.data = messager.encodeMsg(messager.MSG_BEATING, tdata.s,
                                                tdata.c)
                sock.sendto(bytes(tdata.data, 'utf-8'), tdata.addr)
            # Should Never happen, but just in case
            else:
                tdata.data = messager.encodeMsg(messager.MSG_ERROR, tdata.s,
                                                tdata.c)
                sock.sendto(bytes(tdata.data, 'utf-8'), tdata.addr)

        elif tdata.t == messager.MSG_ACTIVE:
            with __lock:
                ACTIVE = True
            logging.info("Become active")
            exit(0)
def handleTCP(data, udp):
    global state
    global Checkpoint_turn
    global Log
    sock = data[0]
    tdata = threading.local()
    tdata.cid = 0
    checkpoint_count = 0

    while True:
        tdata.data = sock.recv(buffSize)

        if not tdata.data:
            logging.info("CID: %i exit (0 is UNKNOWN)", tdata.cid)
            sock.close()
            return

        tdata.t, tdata.s, tdata.c = messager.decodeMsg(
            tdata.data.decode('utf-8'))

        # Update state, may be better to have a dedicate function
        if tdata.t == messager.MSG_UPDATESTATE:

            # Client side do not have a way to handle this at this point
            if ACTIVE == False:
                logging.error("NOT ACTIVE")
                tdata.c = "SERVER NOT ACTIVE"
                tdata.data = messager.encodeMsg(messager.MSG_ERROR,
                                                len(tdata.c), tdata.c)
                # sock.send(bytes(tdata.data, 'utf-8'))
                sock.close()
                exit(0)

            # cid, seq, state
            tdata.cid, tdata.sid, tdata.seq, tdata.ts, tdata.state = messager.decodeUpdateState(
                tdata.c)

            __lock.acquire()  # Racing Condition

            # state = tdata.state
            # logging.info("client: %i ,server: %i, seq: %i, state: %s", tdata.cid, tdata.sid,tdata.seq, state)
            # sock.send(tdata.c.encode('utf-8'))
            # Checkpoint_turn = True
            ##checkpoint_count += 1

            if primaryFlag == True:
                state = tdata.state
                logging.info(
                    "client: %i ,server: %i, seq: %i, time: %s, state: %s",
                    tdata.cid, tdata.sid, tdata.seq, tdata.ts, state)
                tdata.data = messager.encodeMsg(messager.MSG_UPDATESTATE, 0,
                                                tdata.c)
                sock.send(tdata.data.encode('utf-8'))
                Checkpoint_turn += 1
            else:
                logging.info("backup is sleeping")
                tdata.c = messager.encodeUpdateState(tdata.cid, tdata.sid,
                                                     tdata.seq, tdata.ts,
                                                     "backup is sleeping")
                tdata.data = messager.encodeMsg(messager.MSG_UPDATESTATE, 0,
                                                tdata.c)
                sock.send(tdata.data.encode('utf-8'))
                Log.append([
                    tdata.cid, tdata.sid, tdata.seq, tdata.ts, tdata.state, 0
                ])
                print("log:")
                for i in Log:
                    print(i[:5])

            __lock.release()

        # recovery request
        elif tdata.t == messager.MSG_RECOVERY:
            #print("recovering")
            # cid, seq, state
            tdata.cid, tdata.sid, tdata.seq, tdata.ts, tdata.state = messager.decodeUpdateState(
                tdata.c)

            if primaryFlag == True:
                while True:
                    #process log
                    flag = False
                    for i in range(len(Log)):
                        if Log[i][0] == tdata.cid and Log[i][2] == tdata.seq:
                            #current first
                            if i == 0 or Log[i - 1][5] == 0 or Log[i -
                                                                   1][5] == 2:
                                flag = True
                                break
                            else:
                                break
                    if flag:
                        break
                    time.sleep(0.2)
                with __lock:
                    #process log
                    for i in range(len(Log)):
                        if Log[i][0] == tdata.cid and Log[i][2] == tdata.seq:
                            state = Log[i][4]
                            Log[i][5] = 2
                            logging.info(
                                "client: %i ,server: %i, seq: %i, time: %s, state: %s",
                                Log[i][0], Log[i][1], Log[i][2], Log[i][3],
                                state)
                            tdata.c = messager.encodeUpdateState(
                                Log[i][0], Log[i][1], Log[i][2], Log[i][3],
                                state)
                            tdata.data = messager.encodeMsg(
                                messager.MSG_UPDATESTATE, 0, tdata.c)
                            sock.send(tdata.data.encode('utf-8'))
                            Checkpoint_turn += 1
                            #prune log
                            if i == (len(Log) - 1):
                                Log = []
                                print("Recovery done. Current state:", state)
                            break
                        elif Log[i][5] == 0:
                            state = Log[i][4]
                            Log[i][5] = 2

            else:
                with __lock:
                    tdata.c = messager.encodeUpdateState(
                        tdata.cid, tdata.sid, tdata.seq, tdata.ts,
                        "backup is sleeping")
                    tdata.data = messager.encodeMsg(messager.MSG_UPDATESTATE,
                                                    0, tdata.c)
                    sock.send(tdata.data.encode('utf-8'))
                    #mark as unreplied
                    for i in range(len(Log)):
                        if Log[i][0] == tdata.cid and Log[i][2] == tdata.seq:
                            Log[i][5] = 1

            # send checkpoint out if it is the primary and meets the frequency
        if primaryFlag and (Checkpoint_turn >= checkpoint_frequency):
            with __lock:
                checkpoint = messager.encodeMsg(messager.MSG_CHECKPOINT,
                                                len(state) + 1, state)
                sendCheck(udp, checkpoint)
                Checkpoint_turn = 0
Ejemplo n.º 8
0
def handleUDP(sock):
    while True:
        data, addr = sock.recvfrom(buffSize)

        t, s, c = messager.decodeMsg(data.decode('utf-8'))

        if (t == messager.MSG_INIT):
            role, ID = messager.decodeInit(c)
            factive = False

            idaddr = {"id": ID, "addr": addr}

            if online(idaddr):
                logging.error("Already login")
                continue

            if (role == messager.MSG_ROLE_SERVER):
                if _primary:
                    _backup.append(idaddr)
                else:
                    _primary.append(idaddr)
                factive = True

            elif (role == messager.MSG_ROLE_LFD):
                _lfd.append(idaddr)

            msg = messager.encodeMsg(messager.MSG_SUCCESS, 1, "")

            logging.info('id: %d login', ID)
            print("membership:")
            print("Current primary:")
            for p in _primary:
                print(p)
            print("Current backup:")
            for b in _backup:
                print(b)

            if factive:
                msg = messager.encodeMsg(messager.MSG_ACTIVE, 1, "")

                logging.info('id: %d activing', ID)

        # server down with lfd message
        if (t == messager.MSG_FAULT):
            role, ID = messager.decodeInit(c)

            if (role == messager.MSG_ROLE_LFD):
                for s in _primary:
                    if s["id"] == ID:
                        _primary.remove(s)  # primary done
                        if _backup:  # if there is still backup alive
                            _primary.append(
                                _backup[0]
                            )  # wake up one of the backup and make it primary
                            _backup.pop(0)
                            msg = messager.encodeMsg(messager.MSG_WAKE, 1, '')

                            break
                for b in _backup:
                    if b["id"] == ID:
                        _backup.remove(b)
                        break

            ###
            ## c = messager.encodeInit(messager.MSG_ROLE_REPMGN, ID)

            ###
            print("server down. ID:", ID)
            print("membership:")
            print("Current primary:")
            for p in _primary:
                print(p)
            print("Current backup:")
            for b in _backup:
                print(b)
Ejemplo n.º 9
0
def stateUpdate(stcp):
    global seq
    global recovering
    global resend
    # Currently for easy debug -- Later will be feeded by script
    if recovering:
        state = resend
        print("send recover", state)
    else:
        state = messager.inputState()

    # send msg
    for i in stcp:
        # check connection
        if i[2]:
            timestamp = str(datetime.now())
            update_str = messager.encodeUpdateState(cid, i[0], seq, timestamp,
                                                    state)
            if recovering:
                msg = messager.encodeMsg(messager.MSG_RECOVERY,
                                         len(update_str) + 1, update_str)
            else:
                msg = messager.encodeMsg(messager.MSG_UPDATESTATE,
                                         len(update_str) + 1, update_str)
            i[1].send(bytes(msg, 'utf-8'))
            if not recovering:
                print("msg send to server id:", i[0], state)
        else:
            # reconnect
            try:
                i[1] = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                i[1].connect(server_address[i[0] - 1])
                i[2] = True
                timestamp = str(datetime.now())
                update_str = messager.encodeUpdateState(
                    cid, i[0], seq, timestamp, state)
                if recovering:
                    msg = messager.encodeMsg(messager.MSG_RECOVERY,
                                             len(update_str) + 1, update_str)
                else:
                    msg = messager.encodeMsg(messager.MSG_UPDATESTATE,
                                             len(update_str) + 1, update_str)
                i[1].send(bytes(msg, 'utf-8'))
                if not recovering:
                    print("msg send to server id:", i[0], state)
            except socket.error:
                continue

    # duplicate detector
    recovering = True
    for i in range(len(stcp)):
        if stcp[i][2]:
            try:
                data = stcp[i][1].recv(buffSize)
                # error
                if not data:
                    stcp[i][1].close()
                    stcp[i][2] = False
                    if stcp[i][3] == 'p':
                        recovering = True
                    stcp[i][3] = 'b'
                    continue

                i_type, i_len, i_c = messager.decodeMsg(data.decode('utf-8'))
                if i_type == messager.MSG_UPDATESTATE:
                    i_cid, i_sid, i_seq, i_timestamp, i_state = messager.decodeUpdateState(
                        i_c)
                    # only implementaiton on reply
                    if i_state == "backup is sleeping":
                        continue
                    if i_seq >= seq:
                        print(messager.decodeUpdateState(i_c))
                        stcp[i][3] = 'p'
                        recovering = False
                        seq += 1
                    else:
                        print("duplicate reply detected:")
                        print(messager.decodeUpdateState(i_c))
            # error
            except socket.error:
                stcp[i][1].close()
                stcp[i][2] = False
                if stcp[i][3] == 'p':
                    recovering = True
                stcp[i][3] = 'b'
                continue
    if recovering:
        resend = state
        time.sleep(1)
    return
Ejemplo n.º 10
0
def handle_gfd_ping():
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    sock.bind(('localhost', port_lfd))
    tdata = threading.local()
    while True:
        tdata.data, tdata.addr = sock.recvfrom(buffSize)
        sock.sendto(tdata.data, tdata.addr)


if __name__ == "__main__":
    sudp = init()

    logging.info("timeout: %d, interval: %d", timeout, interval)

    tudp2 = threading.Thread(target=handle_gfd_ping, args=(), daemon=True)
    tudp2.start()

    ## keep sending message to server until get responses, then break
    while True:
        msg = messager.encodeMsg(messager.MSG_LFD_SERVER_INIT, 0, "")
        sudp.sendto(msg.encode('utf-8'), ((host, port)))

        try:
            data, addr = sudp.recvfrom(buffSize)
            break
        except socket.timeout:
            continue

    while True:
        ping(sudp)
Ejemplo n.º 11
0
def stateUpdate(stcp):
    global seq
    # Currently for easy debug -- Later will be feeded by script
    state = messager.inputState()

    # send msg
    for i in stcp:
        # check connection
        if i[2]:
            timestamp = str(datetime.now())
            update_str = messager.encodeUpdateState(cid, i[0], seq, timestamp,
                                                    state)
            msg = messager.encodeMsg(messager.MSG_UPDATESTATE,
                                     len(update_str) + 1, update_str)
            i[1].send(bytes(msg, 'utf-8'))
            print("msg send to server id:", i[0], "msg:", state)
        else:
            # reconnect
            try:
                i[1] = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                i[1].connect(server_address[i[0] - 1])
                i[2] = True
                timestamp = str(datetime.now())
                update_str = messager.encodeUpdateState(
                    cid, i[0], seq, timestamp, state)
                msg = messager.encodeMsg(messager.MSG_UPDATESTATE,
                                         len(update_str) + 1, update_str)
                i[1].send(bytes(msg, 'utf-8'))
                print("msg send to server id:", i[0], "msg:", state)
            except socket.error:
                print("not add ", server_address[i[0] - 1])
                continue

    # duplicate detector
    for i in range(len(stcp)):
        if stcp[i][2]:
            try:
                data = stcp[i][1].recv(buffSize)
                # error
                if not data:
                    stcp[i][1].close()
                    stcp[i][2] = False
                    continue

                i_type, i_len, i_c = messager.decodeMsg(data.decode('utf-8'))
                if i_type == messager.MSG_UPDATESTATE:
                    i_cid, i_sid, i_seq, i_timestamp, i_state = messager.decodeUpdateState(
                        i_c)
                    # only implementaiton on reply
                    if i_state == "backup is sleeping":
                        continue
                    if i_seq >= seq:
                        print("Reply:", messager.decodeUpdateState(i_c))
                        seq += 1
                    else:
                        print("Duplicate reply detected:")
                        print(messager.decodeUpdateState(i_c))

                elif i_type == messager.MSG_ERROR:
                    if i_c == "SERVER NOT ACTIVE":
                        continue

                    elif i_c == "SERVER QUIESCENCE":
                        print("quiet")
                        continue
            # error
            except socket.error:
                stcp[i][1].close()
                stcp[i][2] = False
                continue

    return
Ejemplo n.º 12
0
def handleUdp(sock):
    while True:

        data, addr = sock.recvfrom(buffSize)
        print("msg recv")
        t, s, c = messager.decodeMsg(data.decode('utf-8'))

        if (t == messager.MSG_INIT):
            role, ID = messager.decodeInit(c)
            factive = False

            idaddr = {"id": ID, "addr": addr}

            if online(idaddr):
                logging.error("Already login")
                continue

            if (role == messager.MSG_ROLE_SERVER):
                if (len(_active) > 3):
                    _replica.append(idaddr)
                else:
                    _active.append(idaddr)
                    factive = True

            elif (role == messager.MSG_ROLE_LFD):
                _lfd.append(idaddr)

            msg = messager.encodeMsg(messager.MSG_SUCCESS, 1, "")

            logging.info('id: %d login', ID)
            print("membership:")
            for s in _active:
                print("server id:", s["id"])

            if factive:
                msg = messager.encodeMsg(messager.MSG_ACTIVE, 1, "")
                logging.info('id: %d activing', ID)
                print()
        ## recovery
        if (t == messager.MSG_RECOVERY):

            role, ID = messager.decodeInit(c)
            factive = False

            idaddr = {"id": ID, "addr": addr}

            if online(idaddr):
                logging.error("Already login")
                continue

            if (role == messager.MSG_ROLE_SERVER):
                if (len(_active) > 3):
                    _replica.append(idaddr)
                else:
                    _active.append(idaddr)
                    factive = True

            elif (role == messager.MSG_ROLE_LFD):
                _lfd.append(idaddr)

            msg = messager.encodeMsg(messager.MSG_SUCCESS, 1, "")

            logging.info('id: %d login', ID)
            print("membership:")
            for s in _active:
                print("server id:", s["id"])

            if factive:
                msg = messager.encodeMsg(messager.MSG_ACTIVE, 1, "")
                logging.info('id: %d activing', ID)
                print()
            if _active[0]['id'] == 1:
                checkSendFromPort = 10087
            if _active[0]['id'] == 2:
                checkSendFromPort = 10088
            if _active[0]['id'] == 3:
                checkSendFromPort = 10089
            print("when recovery rempn active list:", _active)
            msg = messager.encodeMsg(messager.MSG_CHECK_REMIND, 1,
                                     _active[-1]['id'])

        # server down with lfd message
        if (t == messager.MSG_FAULT):
            role, ID = messager.decodeInit(c)

            if (role == messager.MSG_ROLE_LFD):
                for s in _active:
                    if s["id"] == ID:
                        _active.remove(s)
                        break
            print("server down. ID:", ID)
            print("membership:")
            for s in _active:
                print("server id:", s["id"])
            print()
Ejemplo n.º 13
0
def handleUDP(sock):

    while True:
        data, addr = sock.recvfrom(buffSize)
        sock.sendto(data, ((ip_repmgn, port_repmgn)))
        t, s, c = messager.decodeMsg(data.decode('utf-8'))

        if (t == messager.MSG_INIT):
            role, ID = messager.decodeInit(c)
            factive = False

            idaddr = {"id": ID, "addr": addr}

            if online(idaddr):
                logging.error("Already login")
                continue

            if (role == messager.MSG_ROLE_SERVER):
                if (len(_active) > 3):
                    _replica.append(idaddr)
                #initial checkpoint
                elif _active != []:
                    if ID == 1:
                        msg = messager.encodeMsg(messager.MSG_CHECKPOINT, 1,
                                                 ("localhost", 10087))
                    elif ID == 2:
                        msg = messager.encodeMsg(messager.MSG_CHECKPOINT, 1,
                                                 ("localhost", 10088))
                    elif ID == 3:
                        msg = messager.encodeMsg(messager.MSG_CHECKPOINT, 1,
                                                 ("localhost", 10089))
                    sock.sendto(bytes(msg, 'utf-8'), _active[0]["addr"])
                    _active.append(idaddr)
                    factive = True
                else:
                    _active.append(idaddr)
                    factive = True

            elif (role == messager.MSG_ROLE_LFD):
                _lfd.append(idaddr)

            msg = messager.encodeMsg(messager.MSG_SUCCESS, 1, "")
            sock.sendto(bytes(msg, 'utf-8'), addr)

            logging.info('id: %d login', ID)
            print("membership:")
            for s in _active:
                print("server id:", s["id"])

            if factive:
                msg = messager.encodeMsg(messager.MSG_ACTIVE, 1, "")
                sock.sendto(bytes(msg, 'utf-8'), addr)
                logging.info('id: %d activing', ID)
                print()
        ## recovery
        if (t == messager.MSG_RECOVERY):

            role, ID = messager.decodeInit(c)
            factive = False

            idaddr = {"id": ID, "addr": addr}
            print("recoveryhhhhhhhhhhhhhh:", idaddr)

            if online(idaddr):
                logging.error("Already login")
                continue

            if (role == messager.MSG_ROLE_SERVER):
                if (len(_active) > 3):
                    _replica.append(idaddr)
                else:
                    _active.append(idaddr)
                    factive = True

            elif (role == messager.MSG_ROLE_LFD):
                _lfd.append(idaddr)

            # msg = messager.encodeMsg(messager.MSG_SUCCESS, 1, "")
            # sock.sendto(bytes(msg, 'utf-8'), addr)

            msg_lock = messager.encodeMsg(messager.MSG_QUIET, 1, "")
            sock.sendto(msg_lock.encode('utf-8'), addr)

            logging.info('id: %d login', ID)
            print("membership:")
            for s in _active:
                print("server id:", s["id"])

            if factive:
                msg = messager.encodeMsg(messager.MSG_ACTIVE, 1, "")
                sock.sendto(bytes(msg, 'utf-8'), addr)
                logging.info('id: %d activing', ID)
                print()
            if _active[0]['id'] == 1:
                checkSendFromPort = 10087
            if _active[0]['id'] == 2:
                checkSendFromPort = 10088
            if _active[0]['id'] == 3:
                checkSendFromPort = 10089
            print("when recovery rempn active list:", _active)
            msg = messager.encodeMsg(messager.MSG_CHECK_REMIND, 1,
                                     _active[-1]['id'])
            sock.sendto(msg.encode('utf-8'), ("localhost", checkSendFromPort))

        #server down with lfd message
        if (t == messager.MSG_FAULT):
            role, ID = messager.decodeInit(c)

            if (role == messager.MSG_ROLE_LFD):
                for s in _active:
                    if s["id"] == ID:
                        _active.remove(s)
                        break
            print("server down. ID:", ID)
            print("membership:")
            for s in _active:
                print("server id:", s["id"])
            print()