Exemplo n.º 1
0
        async Task <bool> Receive()
        {
            try
            {
                NetMQMessage msg = null;
                // NOTE:
                // After switching to async IO, when we close the socket in Dispose() the ReceiveMultipartMessage() wasn't returning.
                // So, we TryReceive() with a timeout.  If it times out the receive loop will check if we retry or exit.
                // If we get an async-friendly version of NetMQ (or switch transports) we can probably go back to regular Receive().
                if (socket.TryReceiveMultipartMessage(ReceiveTimeout, ref msg))
                {
                    if (msg == null || ZeroMQ.PubSubUtil.IsStoppingMessage(msg))
                    {
                        PublisherLogger.Info("stopped by stpping message!");
                        return(false);
                    }

                    var topic   = msg[0].ConvertToString();
                    var msgType = msg[1].ConvertToString();
                    if (MsgHandlers.TryGetValue(msgType, out Delegate mh))
                    {
                        var respBytes = msg[2].Buffer;
                        using (var proto = ThriftUtil.CreateReadProtocol(respBytes))
                        {
                            Type t = GeneratedTypeCache.GetType(msgType);
                            if (t == null)
                            {
                                throw new TargetInvocationException(new Exception("can't get type for: " + msgType));
                            }
                            TBase ret = Activator.CreateInstance(t) as TBase;
                            await ret.ReadAsync(proto, cts.Token);

                            mh.DynamicInvoke(topic, ret);
                        }
                    }
                    return(true);
                }
                else
                {
                    // Receive timed out.  Return true so receive loop can check if we should exit or try again.
                    return(true);
                }
            }
            catch (Exception e)
            {
                if (e is TargetInvocationException ee)
                {
                    Log($"invoke exception: {(ee).InnerException.Message} \n {ee.InnerException.StackTrace}", Logging.LogLevel.Warn);
                    return(true);
                }
                if (e is TerminatingException)
                {
                    Log($"terminated: {e.Message}", Logging.LogLevel.Info);
                    return(false);
                }
                else
                {
                    if (disposing)
                    {
                        Log("disposing exception: " + e.Message, Logging.LogLevel.Info);
                    }
                    else
                    {
                        Log($"receive exception: {e.Message} \n {e.StackTrace}", Logging.LogLevel.Error);
                    }

                    return(false);
                }
            }
        }