diff -r dc2dbe872fc8 -r 5664afa530e5 tests/multiprocessing.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/multiprocessing.py Thu Dec 15 18:21:41 2011 +0100 @@ -0,0 +1,78 @@ +#!/usr/bin/env python3 +'''Multiprocessing test. + +PgManager is partially safe against process forking. + +You can create connection credentials (create_conn) in main process, then fork +and continue working with pgmanager in children processes. You can call create_conn again +in children, but new connection credentials will be accessible only from process +where it was created -- no sharing between processes. + +get_conn and cursor will still work after fork. Connections from parent process will +be forgotten, that cannot be used un child process. + +Connections cannot be shared between processes, DO NOT: + * get_conn, then fork, then put_conn + * get_conn, then fork, then use the connection, then .close() + +Good usage: + * create_conn, fork, get_conn, cursor, etc. + +Basically, you can transfer only information from create_conn(), nothing else. + +''' + + +import multiprocessing + +from config import Config +from pgtoolkit import pgmanager + + +def sub1(id): + with pgm.cursor() as curs: + print('[%d] pgconn: %d' % (multiprocessing.current_process().pid, curs.connection.get_backend_pid())) + print('[%d] update' % multiprocessing.current_process().pid) + curs.execute('''UPDATE test SET name = 'multi-1' WHERE id=%s''', [id]) + print('[%d] commit' % multiprocessing.current_process().pid) + curs.connection.commit() + +def sub2(id): + pgm = pgmanager.get_instance() + with pgm.cursor() as curs: + print('[%d] pgconn: %d' % (multiprocessing.current_process().pid, curs.connection.get_backend_pid())) + print('[%d] update' % multiprocessing.current_process().pid) + curs.execute('''UPDATE test SET name = 'multi-2' WHERE id=%s''', [id]) + print('[%d] commit' % multiprocessing.current_process().pid) + curs.connection.commit() + + +cfg = Config('tests.conf') +pgm = pgmanager.get_instance() +pgm.create_conn(**cfg) + +with pgm.cursor() as curs: + print('[%d] pgconn: %d' % (multiprocessing.current_process().pid, curs.connection.get_backend_pid())) + print('[%d] insert' % multiprocessing.current_process().pid) + curs.execute('''INSERT INTO test (name) VALUES ('multi') RETURNING id''') + id = curs.fetchone()[0] + curs.connection.commit() + + print('[%d] update' % multiprocessing.current_process().pid) + curs.execute('''UPDATE test SET name = 'multi-main' WHERE id=%s''', [id]) + # not committed + +p1 = multiprocessing.Process(target=sub1, args=[id]) +p1.start() +p2 = multiprocessing.Process(target=sub2, args=[id]) +p2.start() + +with pgm.cursor() as curs: + print('[%d] commit' % multiprocessing.current_process().pid) + curs.connection.commit() + +print('join') +p1.join() +p2.join() + +print('done')