django32: change the way Thread are made tenant aware (#67760)
gitea-wip/hobo/pipeline/pr-main This commit looks good
Details
gitea-wip/hobo/pipeline/pr-main This commit looks good
Details
Django 3.2. changed the implementation of django.db.ConnectionHandler it now uses asgiref.local.Local as a thread/asyncio-task local dictionnary instead of threading.local. This new implementation use threading.current_thread() to get a reference to the current thread instead of threading._get_ident(), but inside __bootstrap_inner, the _active dictionnary is not initialized and current_thread() returns a dummy value instead of the current thread. To work around this behaviour I made __bootstrap_inner wrap the run method with the code needed to setup the tenant, so that it's run after __boostrap_inner initialization of the current thread in the _active dictionnary.
This commit is contained in:
parent
9bc96520ac
commit
842f699e8a
|
@ -14,6 +14,7 @@
|
|||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import functools
|
||||
import threading
|
||||
|
||||
_Thread_start = threading.Thread.start
|
||||
|
@ -28,21 +29,34 @@ def _new_start(self):
|
|||
return _Thread_start(self)
|
||||
|
||||
|
||||
def wrap_run(self, func):
|
||||
if getattr(func, '_wrapped', False):
|
||||
return func
|
||||
|
||||
@functools.wraps(func)
|
||||
def wrapper():
|
||||
tenant = getattr(self, 'tenant', None)
|
||||
|
||||
if tenant is not None:
|
||||
from django.db import connection
|
||||
|
||||
old_tenant = connection.tenant
|
||||
connection.set_tenant(self.tenant)
|
||||
try:
|
||||
func()
|
||||
finally:
|
||||
connection.set_tenant(old_tenant)
|
||||
connection.close()
|
||||
else:
|
||||
func()
|
||||
|
||||
wrapper._wrapped = True
|
||||
return wrapper
|
||||
|
||||
|
||||
def _new__bootstrap_inner(self):
|
||||
tenant = getattr(self, 'tenant', None)
|
||||
|
||||
if tenant is not None:
|
||||
from django.db import connection
|
||||
|
||||
old_tenant = connection.tenant
|
||||
connection.set_tenant(self.tenant)
|
||||
try:
|
||||
_Thread__bootstrap_inner(self)
|
||||
finally:
|
||||
connection.set_tenant(old_tenant)
|
||||
connection.close()
|
||||
else:
|
||||
_Thread__bootstrap_inner(self)
|
||||
self.run = wrap_run(self, self.run)
|
||||
_Thread__bootstrap_inner(self)
|
||||
|
||||
|
||||
def install_tenant_aware_threads():
|
||||
|
|
Loading…
Reference in New Issue