Code

Ticket #5632: dbmultithreaded.diff

File dbmultithreaded.diff, 5.8 KB (added by claudio.marinozzi@…, 7 years ago)

diff created with Django on Trunk at h12pm Italy time

Line 
1Index: django/db/models/serializer.py
2===================================================================
3--- django/db/models/serializer.py      (revisione 0)
4+++ django/db/models/serializer.py      (revisione 0)
5@@ -0,0 +1,38 @@
6+# -*- coding: utf-8 -*-
7+
8+# Author: Claudio Marinozzi (alias PyMan)
9+
10+from threading import RLock
11+
12+class Serializer :
13+   
14+    def __init__(self) :
15+        self.rc = 0
16+        self.lock = RLock()
17+       
18+    def acquire(self):
19+        self.lock.acquire()
20+        self.rc += 1
21+       
22+    def release(self):
23+        self.rc -= 1
24+        self.lock.release()
25+
26+__serializer = Serializer()
27+
28+#TODO: maybe it's useful the use of a new setting parameter that if setted to True then makes the use of the
29+#Serialized object (multithreaded scenario), False otherwise (single threaded scenario)
30+
31+#NOTE: Now the Serializer object it's useless...it could be just used the RLock object itself.
32+
33+def mutex(func):
34+    def decorator(*args, **kwargs):
35+        __serializer.acquire()
36+        try :
37+            res = func(*args, **kwargs)
38+        except :
39+            __serializer.release()
40+            raise
41+        __serializer.release()
42+        return res
43+    return decorator
44\ Nessun a-capo alla fine del file
45Index: django/db/models/base.py
46===================================================================
47--- django/db/models/base.py    (revisione 6431)
48+++ django/db/models/base.py    (copia locale)
49@@ -19,6 +19,8 @@
50 import sys
51 import os
52 
53+from django.db.models.serializer import mutex
54+
55 class ModelBase(type):
56     "Metaclass for all models"
57     def __new__(cls, name, bases, attrs):
58@@ -206,6 +208,7 @@
59 
60     _prepare = classmethod(_prepare)
61 
62+    @mutex
63     def save(self, raw=False):
64         dispatcher.send(signal=signals.pre_save, sender=self.__class__, instance=self)
65 
66@@ -319,6 +322,7 @@
67                 for sub_obj in getattr(self, rel_opts_name).all():
68                     sub_obj._collect_sub_objects(seen_objs)
69 
70+    @mutex
71     def delete(self):
72         assert self._get_pk_val() is not None, "%s object can't be deleted because its %s attribute is set to None." % (self._meta.object_name, self._meta.pk.attname)
73 
74Index: django/db/models/fields/related.py
75===================================================================
76--- django/db/models/fields/related.py  (revisione 6431)
77+++ django/db/models/fields/related.py  (copia locale)
78@@ -11,6 +11,8 @@
79 from django import newforms as forms
80 from django.dispatch import dispatcher
81 
82+from django.db.models.serializer import mutex
83+
84 try:
85     set
86 except NameError:
87@@ -214,12 +216,14 @@
88             def get_query_set(self):
89                 return superclass.get_query_set(self).filter(**(self.core_filters))
90 
91+            @mutex
92             def add(self, *objs):
93                 for obj in objs:
94                     setattr(obj, rel_field.name, instance)
95                     obj.save()
96             add.alters_data = True
97 
98+            @mutex
99             def create(self, **kwargs):
100                 new_obj = self.model(**kwargs)
101                 self.add(new_obj)
102@@ -228,6 +232,7 @@
103 
104             # remove() and clear() are only provided if the ForeignKey can have a value of null.
105             if rel_field.null:
106+                @mutex
107                 def remove(self, *objs):
108                     val = getattr(instance, rel_field.rel.get_related_field().attname)
109                     for obj in objs:
110@@ -239,6 +244,7 @@
111                             raise rel_field.rel.to.DoesNotExist, "%r is not related to %r." % (obj, instance)
112                 remove.alters_data = True
113 
114+                @mutex
115                 def clear(self):
116                     for obj in self.all():
117                         setattr(obj, rel_field.name, None)
118@@ -283,6 +289,7 @@
119         def get_query_set(self):
120             return superclass.get_query_set(self).filter(**(self.core_filters))
121 
122+        @mutex
123         def add(self, *objs):
124             self._add_items(self.source_col_name, self.target_col_name, *objs)
125 
126@@ -291,6 +298,7 @@
127                 self._add_items(self.target_col_name, self.source_col_name, *objs)
128         add.alters_data = True
129 
130+        @mutex
131         def remove(self, *objs):
132             self._remove_items(self.source_col_name, self.target_col_name, *objs)
133 
134@@ -299,6 +307,7 @@
135                 self._remove_items(self.target_col_name, self.source_col_name, *objs)
136         remove.alters_data = True
137 
138+        @mutex
139         def clear(self):
140             self._clear_items(self.source_col_name)
141 
142@@ -307,6 +316,7 @@
143                 self._clear_items(self.target_col_name)
144         clear.alters_data = True
145 
146+        @mutex
147         def create(self, **kwargs):
148             new_obj = self.model(**kwargs)
149             new_obj.save()
150Index: django/db/models/query.py
151===================================================================
152--- django/db/models/query.py   (revisione 6431)
153+++ django/db/models/query.py   (copia locale)
154@@ -10,6 +10,8 @@
155 import operator
156 import re
157 
158+from django.db.models.serializer import mutex
159+
160 try:
161     set
162 except NameError:
163@@ -264,6 +266,7 @@
164         assert len(obj_list) == 1, "get() returned more than one %s -- it returned %s! Lookup parameters were %s" % (self.model._meta.object_name, len(obj_list), kwargs)
165         return obj_list[0]
166 
167+    @mutex
168     def create(self, **kwargs):
169         """
170         Create a new object with the given kwargs, saving it to the database
171@@ -273,6 +276,7 @@
172         obj.save()
173         return obj
174 
175+    @mutex
176     def get_or_create(self, **kwargs):
177         """
178         Looks up an object with the given kwargs, creating one if necessary.
179@@ -318,6 +322,7 @@
180         qs._params.extend(id_list)
181         return dict([(obj._get_pk_val(), obj) for obj in qs.iterator()])
182 
183+    @mutex
184     def delete(self):
185         """
186         Deletes the records in the current QuerySet.
187