git.fiddlerwoaroof.com
Browse code

made the server more asynchronous

Ed L authored on 17/10/2011 17:54:41
Showing 1 changed files
... ...
@@ -37,6 +37,7 @@ import jsonrpc.common
37 37
 # Twisted imports
38 38
 from twisted.web import server
39 39
 from twisted.internet import threads
40
+from twisted.internet import defer
40 41
 from twisted.web.resource import Resource
41 42
 
42 43
 
... ...
@@ -119,7 +120,7 @@ class JSON_RPC(Resource):
119 120
 				self._ebRender(e, request, content.id if hasattr(content, 'id') else None)
120 121
 
121 122
 			else:
122
-				d = threads.deferToThread(self._action, request, content)
123
+				d = self._action(request, content)
123 124
 				d.addCallback(self._cbRender, request)
124 125
 				d.addErrback(self._ebRender, request, content.id if hasattr(content, 'id') else None)
125 126
 		except BaseException, e:
... ...
@@ -135,27 +136,42 @@ class JSON_RPC(Resource):
135 136
 
136 137
 		if contents == []: raise jsonrpc.common.InvalidRequest
137 138
 
139
+		def callmethod(request, rpcrequest, add, **kwargs):
140
+			add.update(kwargs)
141
+			result = self.eventhandler.callmethod(request, rpcrequest, **add)
142
+			return result
143
+
144
+		deferreds = []
138 145
 		for rpcrequest in contents:
139 146
 			res = None
147
+			add = copy.deepcopy(rpcrequest.extra)
148
+			add.update(kw)
149
+			deferreds.append(threads.deferToThread(callmethod, request, rpcrequest, add))
150
+		deferreds = defer.DeferredList(deferreds, consumeErrors=True)
151
+
152
+		@deferreds.addCallback
153
+		def helper(deferredresults):
154
+			result = []
155
+			for success, methodresult in deferredresults:
156
+				res = None
157
+				if success:
158
+					res = jsonrpc.common.Response(id=rpcrequest.id, result=methodresult)
159
+					res = self.eventhandler.processrequest(res, request.args, **kw)
160
+				else:
161
+					try:
162
+						methodresult.raiseException()
163
+					except Exception, e:
164
+						res = self.render_error(e, rpcrequest.id)
140 165
 
141
-			try:
142
-				add = copy.deepcopy(rpcrequest.extra)
143
-				add.update(kw)
144
-				res = jsonrpc.common.Response(id=rpcrequest.id, result=self.eventhandler.callmethod(request, rpcrequest, **add))
145
-				res = self.eventhandler.processrequest(res, request.args, **kw)
146
-			except Exception, e:
147
-				res = self.render_error(e, rpcrequest.id)
148
-
149
-			if res.id is not None:
150
-				result.append(res)
151
-
152
-
166
+				if res.id is not None:
167
+					result.append(res)
153 168
 
154
-		if result != []:
155
-			if not islist: result = result[0]
156
-		else: result = None
169
+			if result != []:
170
+				if not islist: result = result[0]
171
+			else: result = None
172
+			return result
157 173
 
158
-		return result
174
+		return deferreds
159 175
 
160 176
 
161 177
 	def _setresponseCode(self, result, request):
... ...
@@ -166,32 +182,38 @@ class JSON_RPC(Resource):
166 182
 		request.setResponseCode(code)
167 183
 
168 184
 	def _cbRender(self, result, request):
169
-		self._setresponseCode(result, request)
170
-		self.eventhandler.log(result, request, error=False)
171
-		if result is not None:
172
-			request.setHeader("content-type", 'application/json')
173
-			result = jsonrpc.jsonutil.encode(result).encode('utf-8')
174
-			request.setHeader("content-length", len(result))
175
-			request.write(result)
176
-		request.finish()
185
+		@threads.deferToThread
186
+		def _inner(*args, **_):
187
+			self._setresponseCode(result, request)
188
+			self.eventhandler.log(result, request, error=False)
189
+			if result is not None:
190
+				request.setHeader("content-type", 'application/json')
191
+				result_ = jsonrpc.jsonutil.encode(result).encode('utf-8')
192
+				request.setHeader("content-length", len(result_))
193
+				request.write(result_)
194
+			request.finish()
195
+		return _inner
177 196
 
178 197
 	def _ebRender(self, result, request, id, finish=True):
179
-		err = None
180
-		if not isinstance(result, BaseException):
181
-			try: result.raiseException()
182
-			except BaseException, e:
183
-				err = e
184
-				self.eventhandler.log(err, request, error=True)
185
-		else: err = result
186
-
187
-		err = self.render_error(err, id)
188
-		self._setresponseCode(err, request)
189
-
190
-		request.setHeader("content-type", 'application/json')
191
-		result = jsonrpc.jsonutil.encode(err).encode('utf-8')
192
-		request.setHeader("content-length", len(result))
193
-		request.write(result)
194
-		if finish: request.finish()
198
+		@threads.deferToThread
199
+		def _inner(*args, **_):
200
+			err = None
201
+			if not isinstance(result, BaseException):
202
+				try: result.raiseException()
203
+				except BaseException, e:
204
+					err = e
205
+					self.eventhandler.log(err, request, error=True)
206
+			else: err = result
207
+
208
+			err = self.render_error(err, id)
209
+			self._setresponseCode(err, request)
210
+
211
+			request.setHeader("content-type", 'application/json')
212
+			result_ = jsonrpc.jsonutil.encode(err).encode('utf-8')
213
+			request.setHeader("content-length", len(result_))
214
+			request.write(result_)
215
+			if finish: request.finish()
216
+		return _inner
195 217
 
196 218
 
197 219
 	def render_error(self, e, id):