kinorsi
After some time. Error ocurred: pymysql.err.OperationalError: (2006, "MySQL server has gone away (BrokenPipeError(32, 'Broken pipe'))")。 ping_check seems not working.
#13 · closed · 4 comments
After some time. Error ocurred: pymysql.err.OperationalError: (2006, "MySQL server has gone away (BrokenPipeError(32, 'Broken pipe'))")。 ping_check seems not working.
@kinorsi : what configuration are you using to create the pool? Because by default, the ping_check is disabled.
@kinorsi Hi, can you post your code? @Tiduster Thanks for your comments.
@prprprus, I've got the same problem. ``` import time from pymysqlpool.pool import Pool pool = Pool( host = 'localhost', port = 3306, user = user, passwd = passwd, ping_check = 11 ) # Testing on my local mysql server with wait_timeout=10 # So I set ping_check=11 to ping connection, # which had been closed by the server. # First run conn = pool.get_conn() curs = conn.cursor() curs.execute("select 1") pool.release(conn) # Seems ok time.sleep(12) # Connection is now closed # Second run conn2 = pool.get_conn() curs2 = conn2.cursor() curs2.execute("select 1") pool.release(conn2) ``` ``` ConnectionResetError: [Errno 54] Connection reset by peer During handling of the above exception, another exception occurred: OperationalError Traceback (most recent call last) <ipython-input-3-498de018c73c> in <module> 27 conn2 = pool.get_conn() 28 curs2 = conn2.cursor() ---> 29 curs2.execute("select 1") 30 pool.release(conn2) ``` As far as I see, connection never has attribute `__ping_check_timestamp` here: https://github.com/prprprus/PyMySQLPool/blob/212110afaaa01f1d0d3faa8fe099ad19f48a8fbe/pymysqlpool/pool.py#L179 So the condition `c.__ping_check_timestamp < timeout` is never True. ### But why? The problem is in the attribute naming. When the `c` connection object returned by `__get_safe_conn` function appears in the scope of the script, that uses pymysqlpool, the `__ping_check_timestamp` attribute gets automatically renamed by the python interpreter: ``` print(conn2.__dict__) ``` ``` { a lot of attributes... ... '_Pool__ping_check_timestamp': 1582117850} ``` After being released by `release` function the connection object in `unuse_list` still has `_Pool__ping_check_timestamp` attribute, but not `__ping_check_timestamp`. ### Solution Renaming `__ping_check_timestamp` to `_ping_check_timestamp` or `ping_check_timestamp` will solve the problem.
@lagurev Awesome analysis~!! Thank you for sharing👏👏. I tried and your solution is correct. I also found another solution, maybe iterative updates of v1.03 and v1.04 complicate `get_conn`, `get_conn` only needs to be implemented as follows: ```Python # before v1.03 def get_conn(self): with self.cond: if len(self.unuse_list) <= 0 and \ self.current_size >= self.max_size: self.cond.wait_for(self._wait, self.timeout) if len(self.unuse_list) <= 0: raise TimeoutError if len(self.unuse_list) <= 0 and \ self.current_size < self.max_size: self.create_conn() self.current_size += 1 c = self.unuse_list.pop() self.inuse_list.add(c) c.ping() # just add it return c ``` This can run successfully but I still think your solution is better.