public static Either <string, object> IsMessageValidForProcess(object message, Type[] inboxDeclaredType) { if (message == null) { return(Left <string, object>("Message invalid (null)")); } var result = IsMessageValidForProcess(message.GetType(), inboxDeclaredType); if (result.IsRight && result.Lift()) { return(result.Map(_ => message)); } else { if (message is string) { foreach (var type in inboxDeclaredType) { var value = Deserialise.Object((string)message, type); if (value != null) { return(Right <string, object>(value)); } } return(Left <string, object>("Message-type (" + message.GetType().FullName + ") is string, but couldn't convert it to any inbox supported type: " + String.Join(", ", inboxDeclaredType.Map(x => x.FullName)))); } else { return(Left <string, object>("Message-type (" + message.GetType().FullName + ") doesn't match inbox declared type: " + String.Join(", ", inboxDeclaredType.Map(x => x.FullName)))); } } }
static S ProxyMsgInbox <S>(S process, ProxyMsg msg) { var types = msg.ArgTypes.Map(Type.GetType).ToArray(); var args = msg.Args.Map((i, x) => Deserialise.Object(x, types[i])).ToArray(); var method = process.GetType().GetMethod(msg.Method, types); var result = method.Invoke(process, args); if (msg.ReturnType != "System.Void" && notnull(result)) { replyOrTellSender(result); } return(process); }
private static object DeserialiseMsgContent(RemoteMessageDTO msg) { object content = null; if (msg.Content == null) { throw new Exception($"Message content is null from {msg.Sender}"); } else { var contentType = Type.GetType(msg.ContentType); if (contentType == null) { throw new Exception($"Can't resolve type: {msg.ContentType}"); } content = Deserialise.Object(msg.Content, contentType); } return(content); }
public static Tuple <long, Dictionary <long, AskActorReq> > Inbox(Tuple <long, Dictionary <long, AskActorReq> > state, object msg) { var reqId = state.Item1; var dict = state.Item2; if (msg is AskActorReq) { reqId++; var req = (AskActorReq)msg; ActorContext.System(req.To).Ask(req.To, new ActorRequest(req.Message, req.To, Self, reqId), Self); dict.Add(reqId, req); } else { var res = (ActorResponse)msg; if (dict.ContainsKey(res.RequestId)) { var req = dict[res.RequestId]; try { if (res.IsFaulted) { Exception ex = null; // Let's be reeeally safe here and do everything we can to get some valid information out of // the response to report to the process doing the 'ask'. try { var msgtype = Type.GetType(res.ResponseMessageType); if (msgtype == res.Message.GetType() && typeof(Exception).GetTypeInfo().IsAssignableFrom(msgtype.GetTypeInfo())) { // Type is fine, just return it as an error ex = (Exception)res.Message; } else { if (res.Message is string) { ex = (Exception)Deserialise.Object(res.Message.ToString(), msgtype); } else { ex = (Exception)Deserialise.Object(JsonConvert.SerializeObject(res.Message), msgtype); } } } catch { ex = new Exception(res.Message == null ? $"An unknown error was thrown by {req.To}" : res.Message.ToString()); } req.Complete(new AskActorRes(new ProcessException($"Process issue: {ex.Message}", req.To.Path, req.ReplyTo.Path, ex))); } else { req.Complete(new AskActorRes(res.Message)); } } catch (Exception e) { req.Complete(new AskActorRes(new ProcessException($"Process issue: {e.Message}", req.To.Path, req.ReplyTo.Path, e))); logSysErr(e); } finally { dict.Remove(res.RequestId); } } else { logWarn($"Request ID doesn't exist: {res.RequestId}"); } } return(new Tuple <long, Dictionary <long, AskActorReq> >(reqId, dict)); }