为什么 pymongo 3.7 SocketChecker 设置选择。POLLIN 在_EVENT_MASK

why pymongo 3.7 SocketChecker set select.POLLIN in _EVENT_MASK

提问人:dingding 提问时间:9/19/2023 更新时间:9/19/2023 访问量:18

问:

在 pymongo 3.7 SocketChecker 中,为什么_EVENT_MASK有一个选择。花粉 |选择。波尔普里?

根据我的理解,池使用SocketChecker.socket_closed检查套接字 obj 状态,如果选择,请重新连接此套接字 obj。POLLERR,select.POLLHUP,选择。波恩瓦尔。

但是套接字 obj 选择了。POLLIN,它会重新连接吗?

皮蒙戈/pool.py

class Pool:
    def __init__(self, address, options, handshake=True):
        ……
        self.socket_checker = SocketChecker()
   def _check(self, sock_info):
        """This side-effecty function checks if this socket has been idle for
        for longer than the max idle time, or if the socket has been closed by
        some external network error, and if so, attempts to create a new
        socket. If this connection attempt fails we raise the
        ConnectionFailure.

        Checking sockets lets us avoid seeing *some*
        :class:`~pymongo.errors.AutoReconnect` exceptions on server
        hiccups, etc. We only check if the socket was closed by an external
        error if it has been > 1 second since the socket was checked into the
        pool, to keep performance reasonable - we can't avoid AutoReconnects
        completely anyway.
        """
        idle_time_seconds = sock_info.idle_time_seconds()
        # If socket is idle, open a new one.
        if (self.opts.max_idle_time_seconds is not None and
                idle_time_seconds > self.opts.max_idle_time_seconds):
            sock_info.close()
            return self.connect()

        if (self._check_interval_seconds is not None and (
                0 == self._check_interval_seconds or
                idle_time_seconds > self._check_interval_seconds)):
            if self.socket_checker.socket_closed(sock_info.sock):
                sock_info.close()
                return self.connect()

        return sock_info

皮蒙戈/network.py

try:
    from select import poll
    _EVENT_MASK = (
        select.POLLIN | select.POLLPRI | select.POLLERR | select.POLLHUP)
except ImportError:
    _HAS_POLL = False

class SocketChecker(object):

    def __init__(self):
        if _HAS_POLL:
            self._lock = threading.Lock()
            self._poller = poll()
        else:
            self._lock = None
            self._poller = None

    def socket_closed(self, sock):
        """Return True if we know socket has been closed, False otherwise.
        """
        while True:
            try:
                if self._poller:
                    with self._lock:
                        self._poller.register(sock, _EVENT_MASK)
                        try:
                            rd = self._poller.poll(0)
                        finally:
                            self._poller.unregister(sock)
                else:
                    rd, _, _ = select.select([sock], [], [], 0)
            except (RuntimeError, KeyError):
                # RuntimeError is raised during a concurrent poll. KeyError
                # is raised by unregister if the socket is not in the poller.
                # These errors should not be possible since we protect the
                # poller with a mutex.
                raise
            except ValueError:
                # ValueError is raised by register/unregister/select if the
                # socket file descriptor is negative or outside the range for
                # select (> 1023).
                return True
            except (_SELECT_ERROR, IOError) as exc:
                if _errno_from_exception(exc) in (errno.EINTR, errno.EAGAIN):
                    continue
                return True
            except Exception:
                # Any other exceptions should be attributed to a closed
                # or invalid socket.
                return True
            return len(rd) > 0

我尝试打印rd结果,我发现一些套接字obj选择了。POLLIN 事件,它返回 True,socket obj 将重新连接。

python linux mongodb pymongo epoll

评论


答: 暂无答案