node.py 3.0 KB
Newer Older
K
kuizhiqing 已提交
1
# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
2
#
K
kuizhiqing 已提交
3 4 5
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
6
#
K
kuizhiqing 已提交
7
#     http://www.apache.org/licenses/LICENSE-2.0
8
#
K
kuizhiqing 已提交
9 10 11 12 13 14 15 16
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from .device import Device

17 18
import os
import random
K
kuizhiqing 已提交
19 20 21 22 23
import socket
import struct
from contextlib import closing


24
class Node:
K
kuizhiqing 已提交
25 26 27 28 29
    def __init__(self):
        # self.device = Device.detect_device()
        self.device = Device.parse_device()
        self.ip = self.get_host_ip()
        self.free_ports = []
K
kuizhiqing 已提交
30
        self._allocated_ports = []
K
kuizhiqing 已提交
31

32 33 34 35 36 37
        port_range = os.getenv('PORT_RANGE', '35100:64000')
        port_range = port_range.split(':')
        self._port_start = int(port_range[0])
        self._port_end = int(port_range[1])
        self._port_cur = random.randint(self._port_start, self._port_end)

K
kuizhiqing 已提交
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
    def get_host_ip(self):
        try:
            self.hostname = socket.gethostname()
            self.ip = socket.gethostbyname(socket.getfqdn(self.hostname))
            return self.ip
        except:
            return '127.0.0.1'

    def get_free_ports(self, n=1):
        free_ports = [self.get_free_port() for i in range(n)]
        self.free_ports += free_ports
        return free_ports

    def get_ports_occupied(self):
        return self.free_ports

54 55
    def _get_free_port(self, port=0):
        with closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as s:
56 57 58
            s.setsockopt(
                socket.SOL_SOCKET, socket.SO_LINGER, struct.pack('ii', 1, 0)
            )
59 60 61 62 63 64 65 66 67 68 69
            try:
                s.bind(('', port))
                return s.getsockname()[1]
            except:
                return -1

    def _update_port_cur(self):
        self._port_cur += 1
        if self._port_cur > self._port_end:
            self._port_cur = self._port_start

K
kuizhiqing 已提交
70
    def get_free_port(self):
71 72 73 74 75 76 77 78 79 80
        for _ in range(100):
            ret = self._get_free_port(self._port_cur)
            if ret > 0:
                self._update_port_cur()
                return ret
            else:
                self._update_port_cur()

        return self._port_cur

K
kuizhiqing 已提交
81 82 83
    @classmethod
    def is_server_ready(self, ip, port):
        with closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as sock:
84 85
            # sock.settimeout(0.01)
            # sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
K
kuizhiqing 已提交
86 87 88 89 90 91 92
            if hasattr(socket, 'SO_REUSEPORT'):
                sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
            result = sock.connect_ex((ip, int(port)))
            if result == 0:
                return True
            else:
                return False