示例#1
0
        /// <summary>
        /// Increases all queue counters according to the provided message and
        /// puts a message into the queue.
        /// </summary>
        /// <param name="message">The message being put into the queue.</param>
        /// <param name="onlyCheckIn">Check the message in without adding it to any queues.</param>
        public void AddMessage(Message message, bool onlyCheckIn)
        {
            BinaryLogWriter binaryLogWriter = GenuineLoggingServices.BinaryLogWriter;

            using (new ReaderAutoLocker(this._disposeLock))
            {
                if (this._disposed)
                {
                    throw OperationException.WrapException(this._disposeException);
                }

                int maxContentSize = 0;
                if (message.SecuritySessionParameters != null)
                {
                    maxContentSize = message.SecuritySessionParameters.MaxContentSize;
                }
                if (maxContentSize == 0)
                {
                    maxContentSize = this._maxContentSize;
                }
                if (maxContentSize > 0 && !this._noSizeChecking)
                {
                    // calculate message effective size
                    try
                    {
                        if (message.SerializedContent != null && message.SerializedContent.CanSeek)
                        {
                            message.EffectiveMessageSize = (int)message.SerializedContent.Length;
                        }
//						else if (message.Stream != null && message.Stream.CanSeek)
//							message.EffectiveMessageSize = (int) message.Stream.Length;
                    }
                    catch (Exception ex)
                    {
                        // LOG:
                        if (binaryLogWriter != null && binaryLogWriter[LogCategory.ImplementationWarning] > 0)
                        {
                            binaryLogWriter.WriteEvent(LogCategory.ImplementationWarning, "MessageContainer.AddMessage",
                                                       LogMessageType.Warning, ex, message, message.Recipient,
                                                       null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name,
                                                       null, null, -1, 0, 0, 0, null, null, null, null,
                                                       "Message stream doesn't support the Length property. Set the NoSizeChecking parameter to true to increase performance");
                        }
                    }

                    try
                    {
                        if (message.SerializedContent != null && message.EffectiveMessageSize == 0 && message.SerializedContent.CanSeek)
                        {
                            message.EffectiveMessageSize = Math.Min(message.EffectiveMessageSize, (int)message.SerializedContent.Length);
                        }
                    }
                    catch (Exception ex)
                    {
                        // LOG:
                        if (binaryLogWriter != null && binaryLogWriter[LogCategory.ImplementationWarning] > 0)
                        {
                            binaryLogWriter.WriteEvent(LogCategory.ImplementationWarning, "MessageContainer.AddMessage",
                                                       LogMessageType.Warning, ex, message, message.Recipient,
                                                       null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name,
                                                       null, null, -1, 0, 0, 0, null, null, null, null,
                                                       "Message stream doesn't support the Length property. Set the NoSizeChecking parameter to true to increase performance");
                        }
                    }

                    // check the message size
                    if (message.EffectiveMessageSize > maxContentSize)
                    {
                        throw GenuineExceptions.Get_Send_TooLargePacketSize((int)message.EffectiveMessageSize, maxContentSize);
                    }
                }

                bool overloaded = false;

                lock (this._queue)
                {
                    // check on total size
                    if (this._currentTotalMessages + 1 > this._maxQueuedItems ||
                        message.EffectiveMessageSize + this._currentTotalSize > this._maxTotalSize)
                    {
                        // to prevent a deadlock
                        overloaded = true;
                    }
                    else
                    {
                        this._currentTotalMessages++;
                        this._currentTotalSize += message.EffectiveMessageSize;

                        // put it into the queue or awaiting list
                        if (!onlyCheckIn)
                        {
                            this._queue.Enqueue(message);

                            // reflect the change in the queue state
                            if (message.Recipient != null)
                            {
                                message.Recipient.QueueLength = this._queue.Count;
                            }

                            // LOG:
                            if (binaryLogWriter != null && binaryLogWriter[LogCategory.MessageProcessing] > 0)
                            {
                                binaryLogWriter.WriteEvent(LogCategory.MessageProcessing, "MessageContainer.AddMessage",
                                                           LogMessageType.MessageIsEnqueued, null, message, message.Recipient, null,
                                                           GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, null, -1, 0, 0, 0, null, null, null, null,
                                                           "The message has been enqueued because no connections are available. Messages in the queue: {0}. Queue size: {1}.",
                                                           this._currentTotalMessages, this._currentTotalSize);
                            }
                        }
                    }
                }                 // lock (this._queue)

                if (overloaded)
                {
                    Exception exception = GenuineExceptions.Get_Send_QueueIsOverloaded(this._maxQueuedItems, this._currentTotalMessages + 1, this._maxTotalSize, message.EffectiveMessageSize + this._currentTotalSize);

                    // LOG:
                    if (binaryLogWriter != null && binaryLogWriter[LogCategory.MessageProcessing] > 0)
                    {
                        binaryLogWriter.WriteEvent(LogCategory.MessageProcessing, "MessageContainer.AddMessage",
                                                   LogMessageType.MessageIsEnqueued, exception, message, message.Recipient, null,
                                                   GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, null, -1, 0, 0, 0, null, null, null, null,
                                                   "Queue is overrun.");
                    }

                    this.Dispose(exception);
                    throw exception;
                }
            }
        }