Skip to content

Commit 2f2b562

Browse files
committed
Async process fully compatitible (+1 squashed commits)
Squashed commits: [e473cce] asynchronous process on JsonProcessor class
1 parent 3aa155d commit 2f2b562

3 files changed

Lines changed: 166 additions & 43 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,3 +106,4 @@ Generated_Code #added for RIA/Silverlight projects
106106
_UpgradeReport_Files/
107107
Backup*/
108108
UpgradeLog*.XML
109+
.nuget/NuGet.exe

Json-Rpc/Handler.cs

Lines changed: 82 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@
88
using Newtonsoft.Json;
99
using System.Threading.Tasks;
1010
using System.Collections.Concurrent;
11-
using Newtonsoft.Json.Linq;
11+
using Newtonsoft.Json.Linq;
12+
using System.Threading;
1213

1314
public class Handler
1415
{
@@ -26,7 +27,7 @@ static Handler()
2627
//current = new Handler(Guid.NewGuid().ToString());
2728
_defaultSessionId = Guid.NewGuid().ToString();
2829
_sessionHandlers = new ConcurrentDictionary<string, Handler>();
29-
_sessionHandlers[_defaultSessionId]= new Handler(_defaultSessionId);
30+
_sessionHandlers[_defaultSessionId] = new Handler(_defaultSessionId);
3031
}
3132

3233
private Handler(string sessionId)
@@ -55,7 +56,7 @@ public static Handler GetSessionHandler(string sessionId)
5556
{
5657
return _sessionHandlers.GetOrAdd(sessionId, new Handler(sessionId));
5758
}
58-
59+
5960
/// <summary>
6061
/// gets the default session
6162
/// </summary>
@@ -72,7 +73,7 @@ public static Handler GetSessionHandler()
7273
public static void DestroySession(string sessionId)
7374
{
7475
Handler h;
75-
_sessionHandlers.TryRemove(sessionId,out h);
76+
_sessionHandlers.TryRemove(sessionId, out h);
7677
h.Handlers.Clear();
7778
h.MetaData.Services.Clear();
7879
}
@@ -92,7 +93,7 @@ public void Destroy()
9293
/// <summary>
9394
/// The sessionID of this Handler
9495
/// </summary>
95-
public string SessionId { get; private set; }
96+
public string SessionId { get; private set; }
9697

9798
private static ConcurrentDictionary<int, object> RpcContexts = new ConcurrentDictionary<int, object>();
9899
private static ConcurrentDictionary<int, JsonRpcException> RpcExceptions = new ConcurrentDictionary<int, JsonRpcException>();
@@ -104,7 +105,7 @@ public void Destroy()
104105
/// <returns></returns>
105106
public static object RpcContext()
106107
{
107-
if (Task.CurrentId == null)
108+
if (Task.CurrentId == null)
108109
return null;
109110

110111
if (RpcContexts.ContainsKey(Task.CurrentId.Value) == false)
@@ -140,7 +141,7 @@ private void RemoveRpcException()
140141
private AustinHarris.JsonRpc.PreProcessHandler externalPreProcessingHandler;
141142
private Func<JsonRequest, JsonRpcException, JsonRpcException> externalErrorHandler;
142143
private Func<string, JsonRpcException, JsonRpcException> parseErrorHandler;
143-
private Dictionary<string,Delegate> Handlers { get; set; }
144+
private Dictionary<string, Delegate> Handlers { get; set; }
144145
#endregion
145146

146147
/// <summary>
@@ -180,15 +181,26 @@ public void UnRegister(string key)
180181
/// <param name="Rpc">JsonRpc Request to be processed</param>
181182
/// <param name="RpcContext">Optional context that will be available from within the jsonRpcMethod.</param>
182183
/// <returns></returns>
183-
public JsonResponse Handle(JsonRequest Rpc, Object RpcContext = null)
184+
public JsonResponse Handle(JsonRequest Rpc, Object RpcContext = null, Action<JsonResponse> callback = null)
184185
{
186+
//empty delegate declaration if callback is not provided
187+
if (null == callback)
188+
{
189+
callback = delegate(JsonResponse a) { };
190+
}
191+
185192
AddRpcContext(RpcContext);
186193

187194
var preProcessingException = PreProcess(Rpc, RpcContext);
188195
if (preProcessingException != null)
189196
{
190-
return new JsonResponse() { Error = preProcessingException,
191-
Id = Rpc.Id };
197+
JsonResponse response = new JsonResponse()
198+
{
199+
Error = preProcessingException,
200+
Id = Rpc.Id
201+
};
202+
callback.Invoke(response);
203+
return response;
192204
}
193205

194206
SMDService metadata = null;
@@ -198,25 +210,32 @@ public JsonResponse Handle(JsonRequest Rpc, Object RpcContext = null)
198210

199211
if (haveDelegate == false || haveMetadata == false || metadata == null || handle == null)
200212
{
201-
return new JsonResponse() { Result = null, Error = new JsonRpcException(-32601, "Method not found", "The method does not exist / is not available."), Id = Rpc.Id };
213+
JsonResponse response = new JsonResponse()
214+
{
215+
Result = null,
216+
Error = new JsonRpcException(-32601, "Method not found", "The method does not exist / is not available."),
217+
Id = Rpc.Id
218+
};
219+
callback.Invoke(response);
220+
return response;
202221
}
203222

204223
bool isJObject = Rpc.Params is Newtonsoft.Json.Linq.JObject;
205224
bool isJArray = Rpc.Params is Newtonsoft.Json.Linq.JArray;
206225
object[] parameters = null;
207226
bool expectsRefException = false;
208227
var metaDataParamCount = metadata.parameters.Count(x => x != null);
209-
228+
210229
var getCount = Rpc.Params as ICollection;
211230
var loopCt = 0;
212-
231+
213232
if (getCount != null)
214233
{
215234
loopCt = getCount.Count;
216235
}
217236

218237
var paramCount = loopCt;
219-
if (paramCount == metaDataParamCount - 1 && metadata.parameters[metaDataParamCount-1].ObjectType.Name.Contains(typeof(JsonRpcException).Name))
238+
if (paramCount == metaDataParamCount - 1 && metadata.parameters[metaDataParamCount - 1].ObjectType.Name.Contains(typeof(JsonRpcException).Name))
220239
{
221240
paramCount++;
222241
expectsRefException = true;
@@ -234,7 +253,7 @@ public JsonResponse Handle(JsonRequest Rpc, Object RpcContext = null)
234253
for (int i = 0; i < loopCt; i++)
235254
{
236255
parameters[i] = CleanUpParameter(jarr[i], metadata.parameters[i]);
237-
}
256+
}
238257
}
239258
else if (isJObject)
240259
{
@@ -249,16 +268,18 @@ public JsonResponse Handle(JsonRequest Rpc, Object RpcContext = null)
249268
{
250269
if (asDict.ContainsKey(metadata.parameters[i].Name) == false)
251270
{
252-
return new JsonResponse()
271+
JsonResponse response = new JsonResponse()
253272
{
254273
Error = ProcessException(Rpc,
255274
new JsonRpcException(-32602,
256275
"Invalid params",
257276
string.Format("Named parameter '{0}' was not present.",
258277
metadata.parameters[i].Name)
259-
))
260-
,Id = Rpc.Id
278+
)),
279+
Id = Rpc.Id
261280
};
281+
callback.Invoke(response);
282+
return response;
262283
}
263284
parameters[i] = CleanUpParameter(jo[metadata.parameters[i].Name], metadata.parameters[i]);
264285
}
@@ -282,7 +303,7 @@ public JsonResponse Handle(JsonRequest Rpc, Object RpcContext = null)
282303

283304
if (missingParamsCount > metadata.defaultValues.Length)
284305
{
285-
return new JsonResponse
306+
JsonResponse response = new JsonResponse
286307
{
287308
Error = ProcessException(Rpc,
288309
new JsonRpcException(-32602,
@@ -293,12 +314,14 @@ public JsonResponse Handle(JsonRequest Rpc, Object RpcContext = null)
293314
)),
294315
Id = Rpc.Id
295316
};
317+
callback.Invoke(response);
318+
return response;
296319
}
297320
}
298-
321+
299322
if (parameters.Length != metaDataParamCount)
300323
{
301-
return new JsonResponse()
324+
JsonResponse response = new JsonResponse()
302325
{
303326
Error = ProcessException(Rpc,
304327
new JsonRpcException(-32602,
@@ -309,46 +332,68 @@ public JsonResponse Handle(JsonRequest Rpc, Object RpcContext = null)
309332
)),
310333
Id = Rpc.Id
311334
};
335+
callback.Invoke(response);
336+
return response;
312337
}
313338

314339
try
315340
{
341+
//callback is stored to thread's local storage in order to get it directly from concrete JsonRpcService method implementation
342+
if (null != callback)
343+
{
344+
Thread.SetData(Thread.GetNamedDataSlot("Callback"), callback);
345+
}
316346
var results = handle.DynamicInvoke(parameters);
317347
var last = parameters.LastOrDefault();
318348
JsonRpcException contextException;
319349
if (Task.CurrentId.HasValue && RpcExceptions.TryRemove(Task.CurrentId.Value, out contextException))
320350
{
321-
return new JsonResponse() { Error = ProcessException(Rpc, contextException), Id = Rpc.Id };
351+
JsonResponse response = new JsonResponse() { Error = ProcessException(Rpc, contextException), Id = Rpc.Id };
352+
callback.Invoke(response);
353+
return response;
322354
}
323355
if (expectsRefException && last != null && last is JsonRpcException)
324356
{
325-
return new JsonResponse() { Error = ProcessException(Rpc, last as JsonRpcException), Id = Rpc.Id };
357+
JsonResponse response = new JsonResponse() { Error = ProcessException(Rpc, last as JsonRpcException), Id = Rpc.Id };
358+
callback.Invoke(response);
359+
return response;
326360
}
327361

328362
return new JsonResponse() { Result = results };
329363
}
330364
catch (Exception ex)
331365
{
366+
JsonResponse response;
332367
if (ex is TargetParameterCountException)
333368
{
334-
return new JsonResponse() { Error = ProcessException(Rpc, new JsonRpcException(-32602, "Invalid params", ex)) };
369+
response = new JsonResponse() { Error = ProcessException(Rpc, new JsonRpcException(-32602, "Invalid params", ex)) };
370+
callback.Invoke(response);
371+
return response;
335372
}
336373

337374
// We really dont care about the TargetInvocationException, just pass on the inner exception
338375
if (ex is JsonRpcException)
339376
{
340-
return new JsonResponse() { Error = ProcessException(Rpc, ex as JsonRpcException) };
377+
response = new JsonResponse() { Error = ProcessException(Rpc, ex as JsonRpcException) };
378+
callback.Invoke(response);
379+
return response;
341380
}
342381
if (ex.InnerException != null && ex.InnerException is JsonRpcException)
343382
{
344-
return new JsonResponse() { Error = ProcessException(Rpc, ex.InnerException as JsonRpcException) };
383+
response = new JsonResponse() { Error = ProcessException(Rpc, ex.InnerException as JsonRpcException) };
384+
callback.Invoke(response);
385+
return response;
345386
}
346387
else if (ex.InnerException != null)
347388
{
348-
return new JsonResponse() { Error = ProcessException(Rpc, new JsonRpcException(-32603, "Internal Error", ex.InnerException)) };
389+
response = new JsonResponse() { Error = ProcessException(Rpc, new JsonRpcException(-32603, "Internal Error", ex.InnerException)) };
390+
callback.Invoke(response);
391+
return response;
349392
}
350393

351-
return new JsonResponse() { Error = ProcessException(Rpc, new JsonRpcException(-32603, "Internal Error", ex)) };
394+
response = new JsonResponse() { Error = ProcessException(Rpc, new JsonRpcException(-32603, "Internal Error", ex)) };
395+
callback.Invoke(response);
396+
return response;
352397
}
353398
finally
354399
{
@@ -371,14 +416,14 @@ private void RemoveRpcContext()
371416
RpcContexts.TryRemove(id, out va);
372417
}
373418
}
374-
375-
private JsonRpcException ProcessException(JsonRequest req,JsonRpcException ex)
419+
420+
private JsonRpcException ProcessException(JsonRequest req, JsonRpcException ex)
376421
{
377-
if(externalErrorHandler!=null)
378-
return externalErrorHandler(req,ex);
422+
if (externalErrorHandler != null)
423+
return externalErrorHandler(req, ex);
379424
return ex;
380425
}
381-
internal JsonRpcException ProcessParseException(string req,JsonRpcException ex)
426+
internal JsonRpcException ProcessParseException(string req, JsonRpcException ex)
382427
{
383428
if (parseErrorHandler != null)
384429
return parseErrorHandler(req, ex);
@@ -392,7 +437,7 @@ internal void SetParseErrorHandler(Func<string, JsonRpcException, JsonRpcExcepti
392437
{
393438
parseErrorHandler = handler;
394439
}
395-
440+
396441
#endregion
397442
private object CleanUpParameter(object p, SMDAdditionalParameters metaData)
398443
{
@@ -404,7 +449,7 @@ private object CleanUpParameter(object p, SMDAdditionalParameters metaData)
404449
}
405450
if (bob != null)
406451
{
407-
452+
408453
// Avoid calling DeserializeObject on types that JValue has an explicit converter for
409454
// try to optimize for the most common types
410455
if (metaData.ObjectType == typeof(string)) return (string)bob;
@@ -442,8 +487,8 @@ private object CleanUpParameter(object p, SMDAdditionalParameters metaData)
442487
{
443488
try
444489
{
445-
if(p is string)
446-
return JsonConvert.DeserializeObject((string) p, metaData.ObjectType);
490+
if (p is string)
491+
return JsonConvert.DeserializeObject((string)p, metaData.ObjectType);
447492
return JsonConvert.DeserializeObject(p.ToString(), metaData.ObjectType);
448493
}
449494
catch (Exception ex)

0 commit comments

Comments
 (0)