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); }
public Task Write() { return(Task.Run(() => { WriterSemaphore.WaitOne(); int writingDirationMs = new Random().Next(1000, 5000); Console.WriteLine($"{DateTime.Now.ToString("hh:mm:ss.fff")}: Writer '{Id}' writes for {writingDirationMs} ms"); Thread.Sleep(TimeSpan.FromMilliseconds(writingDirationMs)); WriterSemaphore.Release(); }, CancellationTokenSource.Token)); }