J'insère des lignes avec des données aléatoires dans la base de données mysql. Après l'insertion de quelques lignes, greenlet se bloque lors de la connexion. Les statistiques d'impression de greenlet continuent de tournersqlalchemy + deadlocks mysql
Cela se produit avec n'importe quel nombre de travailleurs (dont un), à la fois avec les pilotes mysql-connector et mysqldb. sqlite fonctionne très bien.
This n'a pas d'effet (comme je comprends qu'il est déjà fixé dans la nouvelle 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:[email protected]/junk')
main(1, 'mysql+mysqlconnector://root:[email protected]/junk')
Qu'est-ce qui se passe?
retesté, sans erreur persiste gevent, probablement quelque chose avec la configuration du serveur
Juste pour confirmer, est-ce que «Un nombre quelconque de travailleurs» comprend exactement 1 travailleur? – Romain
Oui (question fixe) – ymv