Beispiel #1
0
        public Option <T> PreProcessMessageContent(object message)
        {
            if (message == null)
            {
                tell(sys.DeadLetters, DeadLetter.create(Sender, Self, $"Message is null for tell (expected {typeof(T)})", message));
                return(None);
            }

            if (typeof(T) != typeof(string) && message is string)
            {
                try
                {
                    // This allows for messages to arrive from JS and be dealt with at the endpoint
                    // (where the type is known) rather than the gateway (where it isn't)
                    return(Some(Deserialise.Object <T>((string)message)));
                }
                catch
                {
                    tell(sys.DeadLetters, DeadLetter.create(Sender, Self, $"Invalid message type for tell (expected {typeof(T)})", message));
                    return(None);
                }
            }

            if (!(message is T))
            {
                tell(sys.DeadLetters, DeadLetter.create(Sender, Self, $"Invalid message type for tell (expected {typeof(T)})", message));
                return(None);
            }

            return(Some((T)message));
        }
Beispiel #2
0
 /// <summary>
 /// Support for unit testing message serialisation
 /// </summary>
 public static Validation <string, Msg> WillMyMessageSerialise <Msg>(Msg msg)
 {
     try
     {
         var json = JsonConvert.SerializeObject(msg, ActorSystemConfig.Default.JsonSerializerSettings);
         try
         {
             var msg2 = (Msg)Deserialise.Object(json, typeof(Msg));
             if (msg2 == null)
             {
                 return(Fail <string, Msg>($"{typeof(Msg)} failed to deserialise"));
             }
             else
             {
                 return(Success <string, Msg>(msg2));
             }
         }
         catch (Exception e2)
         {
             return(Fail <string, Msg>($"{typeof(Msg)} failed to deserialise: {e2.Message}"));
         }
     }
     catch (Exception e1)
     {
         return(Fail <string, Msg>($"{typeof(Msg)} failed to serialise: {e1.Message}"));
     }
 }
Beispiel #3
0
        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.IfLeft(false))
            {
                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().GetTypeInfo().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);
        }
Beispiel #6
0
        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 = req.ReplyType;
                                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?.ToString() ?? $"An unknown error was thrown by {req.To}");
                            }

                            req.Complete(new AskActorRes(new ProcessException($"Process issue: {ex.Message}", req.To.Path, req.ReplyTo.Path, ex), req.ReplyType));
                        }
                        else
                        {
                            req.Complete(new AskActorRes(res.Message, req.ReplyType));
                        }
                    }
                    catch (Exception e)
                    {
                        req.Complete(new AskActorRes(new ProcessException($"Process issue: {e.Message}", req.To.Path, req.ReplyTo.Path, e), req.ReplyType));
                        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));
        }