mysqldb et threading

mysqldb et threading - Python - Programmation

Marsh Posté le 26-03-2009 à 00:45:35    

bonjour,
 
pour faire suite à ça http://forum.hardware.fr/hfr/Progr [...] 1783_1.htm ma classe python qui récupère des urls sur internet doit maintenant vérifier si par exemple une url est dans une table et si non l'ajouter.
 
Le soucis c'est qu'une fois sur 2 ça plante au niveau d'une des requetes fait par une des threads. D'après la doc, 2 mêmes threads ne peuvent partager la même connexion d'où mon problème... Y a t-il une solution ? Tout en évitant de créer une nouvelle connexion par threads. Si j'ai 20 threads, 20 connexion à MySQL risquent de charger un peu le serveur.
 
Code de base qui déconne si plusieurs threads:
 

Code :
  1. #!/usr/bin/env python2.6
  2. # -*- coding: utf-8 -*-
  3. import urllib2
  4. import MySQLdb
  5. # Threading version
  6. from threading import Thread
  7. from Queue import Queue
  8. class robot:
  9.     def __init__(self):
  10.         conn = MySQLdb.connect(host="localhost", user="user", passwd="", db="mabase" )
  11.         self.db = db.conn.cursor()
  12.         self.__num_worker = 4
  13.     def queue_fast(self):
  14.         def worker():
  15.             while True:
  16.                 url = q.get()
  17.                 try:
  18.                     True
  19.                     self.execute(url)
  20.                 except:
  21.                     print "erreur avec", url
  22.                 q.task_done()
  23.         q = Queue()
  24.         for i in range(self.__num_worker):
  25.             t = Thread(target=worker)
  26.             t.setDaemon(True)
  27.             t.start()
  28.        
  29.         self.db.execute("""SELECT url FROM site ORDER BY url_id ASC""" )
  30.         data = self.db.fetchone()
  31.         for d in data:
  32.             q.put(data)
  33.             data = self.db.fetchone()
  34.         q.join()    # block until all tasks are done
  35.     def execute(self, url):
  36.         """
  37.         Recupere le contenu html...
  38.         """
  39.         self.db.execute("""SELECT url, date FROM cache WHERE url = %s""", (url))     
  40.        
  41.         data = sql.fetchone()
  42.         page = data[0]
  43.         html = urllib2.urlopen(page).read()
  44.         if html:
  45.             try:
  46.                 self.db.execute("""UPDATE cache SET content = %s WHERE url = %s""", (html, page))
  47.                 return True
  48.             except:
  49.                 return False
  50.         else:
  51.             print "erreur sur la page {0}".format(page)
  52.             return False
  53. if __name__ == '__main__':
  54.     bot = robot()
  55.     bot.queue_fast()


 
donc des fois ça marche, la plupart du temps je m'en sors avec une erreur sql (_mysql_exceptions.OperationalError: 2006, 'MySQL server has gone away') et d'autre fois, le programme se bloque sans me rendre la main (je suppose qu'une des threads doit bloquer le q.join() qui attend).
 
je précise : python 2.6 avec MySQLdb 1.2.2 et MySQL-server 5.0.77 (sous arch)
 
merci

Message cité 1 fois
Message édité par pouchat le 26-03-2009 à 00:49:25
Reply

Marsh Posté le 26-03-2009 à 00:45:35   

Reply

Marsh Posté le 01-04-2009 à 17:04:46    

pouchat a écrit :

Le soucis c'est qu'une fois sur 2 ça plante au niveau d'une des requetes fait par une des threads. D'après la doc, 2 mêmes threads ne peuvent partager la même connexion d'où mon problème... Y a t-il une solution ? Tout en évitant de créer une nouvelle connexion par threads. Si j'ai 20 threads, 20 connexion à MySQL risquent de charger un peu le serveur.


 
Ne peux-tu pas, dans ton thread, créer la connexion, exécuter ta requête, clôre ta requête puis clôre ta connexion une fois devenue inutile ???


---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed