Get a connection from the pool
(self, command_name=None, *keys, **options)
| 3126 | version="5.3.0", |
| 3127 | ) |
| 3128 | def get_connection(self, command_name=None, *keys, **options) -> "Connection": |
| 3129 | "Get a connection from the pool" |
| 3130 | |
| 3131 | # Start timing for observability |
| 3132 | self._checkpid() |
| 3133 | is_created = False |
| 3134 | |
| 3135 | with self._lock: |
| 3136 | try: |
| 3137 | connection = self._available_connections.pop() |
| 3138 | except IndexError: |
| 3139 | # Start timing for observability |
| 3140 | start_time_created = time.monotonic() |
| 3141 | |
| 3142 | connection = self.make_connection() |
| 3143 | is_created = True |
| 3144 | self._in_use_connections.add(connection) |
| 3145 | |
| 3146 | # Record state transition: IDLE -> USED |
| 3147 | # (make_connection already recorded IDLE +1 for new connections) |
| 3148 | # This ensures counters stay balanced if connect() fails and release() is called |
| 3149 | pool_name = get_pool_name(self) |
| 3150 | record_connection_count( |
| 3151 | pool_name=pool_name, |
| 3152 | connection_state=ConnectionState.IDLE, |
| 3153 | counter=-1, |
| 3154 | ) |
| 3155 | record_connection_count( |
| 3156 | pool_name=pool_name, |
| 3157 | connection_state=ConnectionState.USED, |
| 3158 | counter=1, |
| 3159 | ) |
| 3160 | |
| 3161 | try: |
| 3162 | # ensure this connection is connected to Redis |
| 3163 | connection.connect() |
| 3164 | # connections that the pool provides should be ready to send |
| 3165 | # a command. if not, the connection was either returned to the |
| 3166 | # pool before all data has been read or the socket has been |
| 3167 | # closed. either way, reconnect and verify everything is good. |
| 3168 | try: |
| 3169 | if ( |
| 3170 | connection.can_read() |
| 3171 | and self.cache is None |
| 3172 | and not self.maint_notifications_enabled() |
| 3173 | ): |
| 3174 | raise ConnectionError("Connection has data") |
| 3175 | except (ConnectionError, TimeoutError, OSError): |
| 3176 | connection.disconnect() |
| 3177 | connection.connect() |
| 3178 | if connection.can_read(): |
| 3179 | raise ConnectionError("Connection not ready") |
| 3180 | except BaseException: |
| 3181 | # release the connection back to the pool so that we don't |
| 3182 | # leak it |
| 3183 | self.release(connection) |
| 3184 | raise |
| 3185 |