Sqlalchemy + mysql stubs

I am inserting strings with random data into the mysql database. After you insert a few lines, greens hang on the connection. Statistical print green continues to work

This happens with any number of workers (including one), both with mysql-connect drivers and mysqldb. sqlite works fine.

This has no effect (since I understand that it has already been fixed in the new gevent)

def patch():
    from gevent import monkey
    monkey.patch_all()

    # fix https://bugs.launchpad.net/myconnpy/+bug/712037
    from mysql.connector.connection import MySQLConnection
    MySQLConnection.get_characterset_info = MySQLConnection.get_charset
patch()

from sqlalchemy import MetaData, Table, Column, Integer, String, create_engine
from gevent import spawn, sleep
from random import randrange
from time import time

class Stats(object):
    def __init__(self):
        self.inserts, self.faults = 0, 0

    def run(self):
        while True:
            sleep(1)
            print "%d %d %d" % (time(), self.inserts, self.faults)
            self.inserts, self.faults = 0, 0

class Victim(object):
    metadata = MetaData()
    Entry = Table(
        'entry', metadata,
        Column('id', Integer, primary_key=True),
        Column('junk', String(128), unique=True)
    )

    def __init__(self, cs, stats):
        self.e = create_engine(cs)
        self.metadata.drop_all(self.e)
        self.metadata.create_all(self.e)
        self.stats = stats

    def add(self, junk, i):
        print i, 'connecting'
        c = self.e.connect()
        print i, 'connected'
        t = c.begin()
        try:
            q = self.Entry.insert().values(junk=junk)
            c.execute(q)
            t.commit()
            self.stats.inserts += 1
        except Exception as e:
            print i, 'EXCEPTION: ', e
            t.rollback()
            self.stats.faults += 1
        print i, 'done'

def flood(victim, i):
    a, z, l = ord('a'), ord('z')+1, 100
    while True:
        victim.add(''.join(chr(randrange(a, z)) for _ in xrange(l)), i)
        sleep(0)

def main(n_threads, cs):
    stats = Stats()
    victim = Victim(cs, stats)
    threads = [ spawn(flood, victim, i) for i in xrange(n_threads) ]
    threads.append(spawn(stats.run))
    [t.join() for t in threads]

#main(2, 'mysql://root:root@localhost/junk')
main(1, 'mysql+mysqlconnector://root:root@localhost/junk')

What's happening?


Checked, error persists without gevent, maybe something with server configuration

+3
source share
1 answer

I just forgot to release the connections used, so connections that were never checked back to the pool. ...

def add(self, junk, i):
    print i, 'connecting'
    c = self.e.connect()
    ...
    try:
        ...
    except Exception as e:
        ...
    finally:
        c.close() # <-- this returns conenction into pool
    print i, 'done'
+1
source

All Articles