Skip to content

Commit

Permalink
Merge pull request #374 from gi0baro/pid-connection
Browse files Browse the repository at this point in the history
Making connection and cursors fork-safe in multiprocess environments
  • Loading branch information
gi0baro committed Jun 9, 2016
2 parents e1136b6 + 377b98e commit ff67ee5
Showing 1 changed file with 21 additions and 14 deletions.
35 changes: 21 additions & 14 deletions pydal/connection.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# -*- coding: utf-8 -*-
import os
from ._compat import itervalues
from ._globals import GLOBAL_LOCKER, THREAD_LOCAL
from ._load import OrderedDict
Expand All @@ -10,30 +11,43 @@ class ConnectionPool(object):
check_active_connection = True

def __init__(self):
self._connection_thname_ = '_pydal_connection_'+str(id(self))+"_"
self._cursors_thname_ = '_pydal_cursors_'+str(id(self))+"_"
_iid_ = str(id(self))
self._connection_thname_ = '_pydal_connection_' + _iid_ + '_'
self._cursors_thname_ = '_pydal_cursors_' + _iid_ + '_'

@property
def _pid_(self):
return str(os.getpid())

@property
def _connection_uname_(self):
return self._connection_thname_ + self._pid_

@property
def _cursors_uname_(self):
return self._cursors_thname_ + self._pid_

@staticmethod
def set_folder(folder):
THREAD_LOCAL._pydal_folder_ = folder

@property
def connection(self):
return getattr(THREAD_LOCAL, self._connection_thname_)
return getattr(THREAD_LOCAL, self._connection_uname_)

@connection.setter
def connection(self, val):
setattr(THREAD_LOCAL, self._connection_thname_, val)
setattr(THREAD_LOCAL, self._connection_uname_, val)
self._clean_cursors()
if val is not None:
self._build_cursor()

def _clean_cursors(self):
setattr(THREAD_LOCAL, self._cursors_thname_, OrderedDict())
setattr(THREAD_LOCAL, self._cursors_uname_, OrderedDict())

@property
def cursors(self):
return getattr(THREAD_LOCAL, self._cursors_thname_)
return getattr(THREAD_LOCAL, self._cursors_uname_)

def _build_cursor(self):
rv = Cursor(self.connection)
Expand Down Expand Up @@ -127,13 +141,9 @@ def reconnect(self):
if the connection is not active (closed by db server) it will loop
if not `self.pool_size` or no active connections in pool makes a new one
"""
if getattr(THREAD_LOCAL, self._connection_thname_, None) is not None:
if getattr(THREAD_LOCAL, self._connection_uname_, None) is not None:
return

# if not hasattr(self, "driver") or self.driver is None:
# LOGGER.debug("Skipping connection since there's no driver")
# return

if not self.pool_size:
self.connection = self.connector()
self.after_connection_hook()
Expand All @@ -149,7 +159,6 @@ def reconnect(self):
GLOBAL_LOCKER.release()
try:
if self.check_active_connection:
#self.execute_test_query()
self.test_connection()
break
except:
Expand All @@ -159,5 +168,3 @@ def reconnect(self):
self.connection = self.connector()
self.after_connection_hook()
break


0 comments on commit ff67ee5

Please sign in to comment.