Skip to content

Instantly share code, notes, and snippets.

@zzzeek
Last active March 20, 2018 16:27
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zzzeek/b762218a5f855ec7d1c3a998fe996893 to your computer and use it in GitHub Desktop.
Save zzzeek/b762218a5f855ec7d1c3a998fe996893 to your computer and use it in GitHub Desktop.
illustrate pymysql DB connection causing errors which resolve when we make sure they are recycled in greenletexit
import eventlet
eventlet.monkey_patch()
import itertools
import pymysql
import random
from eventlet.green import time
import greenlet
def connect():
return pymysql.connect(user="scott", passwd="tiger", host="127.0.0.1", db="test")
greenlet_id = itertools.count(1)
def do_work(connections, conn_index):
our_id = next(greenlet_id)
conn = connections[conn_index]
while True:
try:
print("greenlet %d working..." % our_id)
cursor = conn.cursor()
for i in range(10):
cursor.execute(
"insert into stuff (data) values (%s)",
(("some_data_%f" % random.random()), )
)
cursor.close()
conn.commit()
cursor = conn.cursor()
cursor.execute("select sleep(%s)", (random.random(), ))
time.sleep(random.random())
if cursor.description is None:
raise Exception("cursor.description not supposed to be none")
cursor.fetchall()
cursor.close()
conn.rollback()
time.sleep(random.random())
except pymysql.Error as err:
print("error occurred, invalidating connection: %s" % err)
conn.rollback()
conn.close()
conn = connections[conn_index] = connect()
except Exception as err:
print("totally unexpected error occurred: %r" % err)
except greenlet.GreenletExit as ex:
print("exit exception: %r" % ex)
if ensure_greenlet_exit_handled:
conn.close()
conn = connections[conn_index] = connect()
break
if __name__ == '__main__':
ensure_greenlet_exit_handled = False
num = 10
conn = connect()
cursor = conn.cursor()
cursor.execute("drop table if exists stuff")
cursor.execute(
"create table stuff(id integer primary key auto_increment, "
"data varchar(200))")
cursor.close()
conn.commit()
connections = [connect() for i in range(num)]
greenlets = [
eventlet.spawn(do_work, connections, idx)
for idx in range(num)]
while True:
for idx in range(num):
time.sleep(random.random())
print("kill...")
eventlet.greenthread.kill(greenlets[idx])
time.sleep(.5)
greenlets[idx] = eventlet.spawn(do_work, connections, idx)
@zzzeek
Copy link
Author

zzzeek commented Mar 20, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment