Beispiel #1
0
        public async ValueTask <bool> Publish(string exchangeName, string routingKey, bool mandatory, bool immediate, ContentHeaderProperties properties, ReadOnlyMemory <byte> message)
        {
            if (IsClosed)
            {
                return(false);
            }
            Session.LockEvent.Wait();
            var info    = new BasicPublishInfo(exchangeName, routingKey, mandatory, immediate);
            var content = new ContentHeader(60, message.Length, ref properties);

            if (message.Length <= Session.Tune.FrameMax)
            {
                var allinfo = new PublishAllInfo(ChannelId, ref message, ref info, content);
                try
                {
                    await Session.PublishAllAsync(allinfo).ConfigureAwait(false);
                }catch (Exception e)
                {
                    Debugger.Break();
                    var cts = new CancellationTokenSource(Session.Options.ConnectionTimeout);
                    using (var timeoutRegistratiuon = cts.Token.Register(() => cts.Cancel()))
                    {
                        return(await PublishAllContinuation(allinfo, cts.Token));
                    }
                }
            }


            await WriterSemaphore.WaitAsync().ConfigureAwait(false);

            var written     = 0;
            var partialInfo = new PublishPartialInfo(ref info, ref content);
            await Session.PublishPartialAsync(ChannelId, partialInfo).ConfigureAwait(false);

            while (written < content.BodySize)
            {
                var batchCnt = 0;
                while (batchCnt < _publishBatchSize && written < content.BodySize)
                {
                    var writable = Math.Min(Session.Tune.FrameMax, (int)content.BodySize - written);
                    _publishBatch[batchCnt] = message.Slice(written, writable);
                    batchCnt++;
                    written += writable;
                }
                await Session.PublishBodyAsync(ChannelId, _publishBatch).ConfigureAwait(false);

                _publishBatch.AsSpan().Fill(ReadOnlyMemory <byte> .Empty);
            }

            WriterSemaphore.Release();
            return(true);
        }
Beispiel #2
0
        private async ValueTask <bool> PublishAllContinuation(PublishAllInfo allInfo, CancellationToken timeout)
        {
            Session.LockEvent.Wait();
            while (true)
            {
                if (timeout.IsCancellationRequested)
                {
                    return(false);
                }
                try
                {
                    await Session.PublishAllAsync(allInfo).ConfigureAwait(false);

                    return(true);
                }
                catch (Exception e)
                {
                    Debugger.Break();
                    continue;
                }
            }
        }
Beispiel #3
0
 internal static ValueTask PublishAllAsync(this RabbitMQSession session, PublishAllInfo info, CancellationToken token = default)
 {
     return(session.Writer.WriteAsync(_fullWriter, info, token));
 }