示例#1
0
        public override void HandleBasicDeliver(string consumerTag,
                                                ulong deliveryTag,
                                                bool redelivered,
                                                string exchange,
                                                string routingKey,
                                                IBasicProperties props,
                                                byte[] body)
        {
            try {
                if (body == null || body.Length == 0)
                {
                    return;
                }

                //Console.WriteLine("new msg from amqp");

                MemoryStream stream = new MemoryStream(body);
                var          proto  = new TCompactProtocol(new TStreamTransport(stream, stream));

                sbyte version = proto.ReadByte();
                if (version != 1)
                {
                    throw new ArgumentException("received unsupported version number");
                }

                uint   flags     = (uint)proto.ReadI32();
                string type_name = proto.ReadString();

                byte[] stream_id = null;
                if ((flags & (uint)message_envelope <WaypointsType> .flags_enum.has_stream_id) != 0)
                {
                    stream_id = proto.ReadBinary();
                }
                else
                {
                    stream_id = new byte[0];
                }
                Debug.Assert(stream_id != null);

                var old_subject   = previous_messages.GetOrAdd(routingKey, (_) => { return(new ConcurrentDictionary <string, ConcurrentDictionary <byte[], message_envelope <WaypointsType> > >()); });
                var old_type_name = old_subject.GetOrAdd(type_name, (_) => { return(new ConcurrentDictionary <byte[], message_envelope <WaypointsType> >(new byte_array_comparator())); });
                var rv            = old_type_name.GetOrAdd(stream_id, (_) => { return(new message_envelope <WaypointsType>(message_factory.from_type_name(type_name, routingKey), this, Idle_timeout)); });

                rv.Received_flag = true;

                lock (queue) {
                    Action message_parser = delegate(){             //~~~ message-reading lambda
                        unchecked {
                            if (Save_raw_data_on_wire == true)
                            {
                                rv.Raw_data_on_wire = body;
                            }
                            rv.type_name = type_name;
                            rv.amqp      = new amqp_envelope {
                                routing_key = routingKey, properties = props
                            };
                            rv.wire_size = body.Length;
                            rv.flags     = flags;
                            if (rv.Has_waypoints() == true)
                            {
                                if (rv.waypoints == null)
                                {
                                    rv.waypoints = new WaypointsType();
                                }
                                rv.waypoints.read_in_delta_mode = false;
                                rv.waypoints.Read(proto);
                            }
                            if ((rv.flags & (uint)message_envelope <WaypointsType> .flags_enum.is_delta) != 0)
                            {
                                rv.msg.read_in_delta_mode = true;
                            }
                            else
                            {
                                if (rv.non_delta_seen == false)
                                {
                                    rv.non_delta_seen = true;
                                }
                                rv.msg.read_in_delta_mode = false;
                            }

                            rv.msg.Read(proto, rv);
                            // for testing only
                            //GC.Collect();
                            //GC.WaitForPendingFinalizers();

                            //Console.WriteLine("read...");
                        }
                    };            //```

                    while (stopped == false && rv.pending_decoders.Count > cached_messages_max_size)
                    {
                        Monitor.Wait(queue);
                    }
                    if (stopped == true)
                    {
                        return;
                    }

                    rv.pending_decoders.Enqueue(Tuple.Create <ulong, Action>(++messages_size, message_parser));
                    queue.Enqueue(rv);

                    if (rv.parsing_status == (uint)message_envelope <WaypointsType> .parsing_status_enum.begin && rv.pending_decoders.Count == 1)
                    {
                        rv.parsing_status = (uint)message_envelope <WaypointsType> .parsing_status_enum.in_progress;
                        Start_parsing_job(rv);
                    }
                }
            } catch (Exception e) {
                lock (queue)
                    AddToExceptionText(e.Message);
                stop();
            }
        }