2009-10-13 6 views
0

j'ai une connexions de base de données de manipulation problème dans un démon que je travaille, je première connexion à ma base de données postgres avec:gestion des connexions db sur daemonize threads

try: 
    psycopg2.apilevel = '2.0' 
    psycopg2.threadsafety = 3 
    cnx = psycopg2.connect("host='192.168.10.36' dbname='db' user='vas' password='vas'") 
    except Exception, e: 
    print "Unable to connect to DB. Error [%s]" % (e,) 
    exit() 

après que je sélectionne toutes les lignes de la DB qui sont avec état = 0:

try: 
    cursor = cnx.cursor(cursor_factory = psycopg2.extras.DictCursor) 
    cursor.execute("SELECT * FROM table WHERE status = 0") 
    rows = cursor.fetchall() 
    cursor.close() 
except Exception, e: 
    print "Error on sql query [%s]" % (e,) 

ensuite s'il y a des rangées sélectionnées des fourches de programme en:

while 1: 
    try: 
    psycopg2.apilevel = '2.0' 
    psycopg2.threadsafety = 3 
    cnx = psycopg2.connect("host='192.168.10.36' dbname='sms' user='vas' password='vas'") 
    except Exception, e: 
    print "Unable to connect to DB. Error [%s]" % (e,) 
    exit() 

    if rows: 
    daemonize() 
    for i in rows: 
     try: 
     global q, l 
     q = Queue.Queue(max_threads) 
     for i in rows: 
      cursor = cnx.cursor(cursor_factory = psycopg2.extras.DictCursor) 
      t = threading.Thread(target=sender, args=(i, cursor)) 
      t.setDaemon(True) 
      t.start() 

      for i in rows: 
      q.put(i) 
      q.join() 
     except Exception, e: 
     print "Se ha producido el siguente error [%s]" % (e,) 
     exit() 
    else: 
    print "No rows where selected\n" 
    time.sleep(5) 

Ma fonction daemonize ressemble à ceci:

def daemonize(): 
    try: 
    pid = os.fork() 
    if pid > 0: 
     sys.exit(0) 
    except OSError, e: 
    print >>sys.stderr, "fork #1 failed: %d (%s)" % (e.errno, e.strerror) 
    sys.exit(1) 

    os.chdir("/") 
    os.umask(0) 

    try: 
    pid = os.fork() 
    if pid > 0: 
     sys.exit(0) 
    except OSError, e: 
    print >>sys.stderr, "fork #2 failed: %d (%s)" % (e.errno, e.strerror) 
    sys.exit(1) 

threads cible à la fonction de l'expéditeur:

def sender(row, db): 
    while 1: 
    item = q.get() 
    if send_to(row['to'], row['text']): 
    db.execute("UPDATE table SET status = 1 WHERE id = %d" % sms['id']) 
    else: 
    print "UPDATE table SET status = 2 WHERE id = %d" % sms['id'] 
    db.execute("UPDATE table SET status = 2 WHERE id = %d" % sms['id']) 
    db.close() 
    q.task_done() 

fonction send_to ouvre juste une URL et retourne vrai ou faux sur le succès

Depuis hier, je continue à obtenir ces erreur et ne peux pas trouver mon chemin à travers:

UPDATE outbox SET status = 2 WHERE id = 36 
Exception in thread Thread-1: 
Traceback (most recent call last): 
    File "/usr/lib/python2.6/threading.py", line 525, in __bootstrap_inner 
    self.run() 
    File "/usr/lib/python2.6/threading.py", line 477, in run 
    self.__target(*self.__args, **self.__kwargs) 
    File "sender.py", line 30, in sender 
    db.execute("UPDATE table SET status = 2 WHERE id = %d" % sms['id']) 
    File "/usr/lib/python2.6/dist-packages/psycopg2/extras.py", line 88, in execute 
    return _cursor.execute(self, query, vars, async) 
OperationalError: server closed the connection unexpectedly 
    This probably means the server terminated abnormally 
    before or while processing the request. 
+0

Trop de code. Pouvez-vous réduire ce code à la plus petite chose qui montre votre message d'erreur? Est-ce qu'une version non démon de ce travail? Vos informations d'identification de base de données sont-elles valides? Est-ce que quelqu'un a déplacé le serveur de base de données et ne vous l'a pas dit? Si cela fonctionnait et ne fonctionne pas maintenant, qu'avez-vous changé? –

Répondre

1

Les handles de base de données ne survivent pas à fork(). Vous devrez ouvrir un nouveau handle de base de données dans chaque sous-processus, c'est-à-dire après avoir appelé daemonize() appelez psycopg2.connect.

Je n'ai pas utilisé postgres mais je sais que cela est certainement vrai pour MySQL.

Questions connexes