MCPcopy
hub / github.com/redis/redis-py / _checkpid

Method _checkpid

redis/connection.py:3076–3121  ·  view source on GitHub ↗
(self)

Source from the content-addressed store, hash-verified

3074 pass
3075
3076 def _checkpid(self) -> None:
3077 # _checkpid() attempts to keep ConnectionPool fork-safe on modern
3078 # systems. this is called by all ConnectionPool methods that
3079 # manipulate the pool's state such as get_connection() and release().
3080 #
3081 # _checkpid() determines whether the process has forked by comparing
3082 # the current process id to the process id saved on the ConnectionPool
3083 # instance. if these values are the same, _checkpid() simply returns.
3084 #
3085 # when the process ids differ, _checkpid() assumes that the process
3086 # has forked and that we're now running in the child process. the child
3087 # process cannot use the parent's file descriptors (e.g., sockets).
3088 # therefore, when _checkpid() sees the process id change, it calls
3089 # reset() in order to reinitialize the child's ConnectionPool. this
3090 # will cause the child to make all new connection objects.
3091 #
3092 # _checkpid() is protected by self._fork_lock to ensure that multiple
3093 # threads in the child process do not call reset() multiple times.
3094 #
3095 # there is an extremely small chance this could fail in the following
3096 # scenario:
3097 # 1. process A calls _checkpid() for the first time and acquires
3098 # self._fork_lock.
3099 # 2. while holding self._fork_lock, process A forks (the fork()
3100 # could happen in a different thread owned by process A)
3101 # 3. process B (the forked child process) inherits the
3102 # ConnectionPool's state from the parent. that state includes
3103 # a locked _fork_lock. process B will not be notified when
3104 # process A releases the _fork_lock and will thus never be
3105 # able to acquire the _fork_lock.
3106 #
3107 # to mitigate this possible deadlock, _checkpid() will only wait 5
3108 # seconds to acquire _fork_lock. if _fork_lock cannot be acquired in
3109 # that time it is assumed that the child is deadlocked and a
3110 # redis.ChildDeadlockedError error is raised.
3111 if self.pid != os.getpid():
3112 acquired = self._fork_lock.acquire(timeout=5)
3113 if not acquired:
3114 raise ChildDeadlockedError
3115 # reset() the instance for the new process if another thread
3116 # hasn't already done so
3117 try:
3118 if self.pid != os.getpid():
3119 self.reset()
3120 finally:
3121 self._fork_lock.release()
3122
3123 @deprecated_args(
3124 args_to_warn=["*"],

Callers 6

get_connectionMethod · 0.95
releaseMethod · 0.95
disconnectMethod · 0.95
get_connectionMethod · 0.80
releaseMethod · 0.80
disconnectMethod · 0.80

Calls 3

resetMethod · 0.95
acquireMethod · 0.45
releaseMethod · 0.45

Tested by

no test coverage detected