-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
8161e71
commit f153691
Showing
13 changed files
with
203 additions
and
146 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
namespace RabbitMQ.Next.Methods; | ||
|
||
public interface IHasContentMethod | ||
{ | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
using System; | ||
using RabbitMQ.Next.Buffers; | ||
using RabbitMQ.Next.Transport; | ||
|
||
namespace RabbitMQ.Next.Channels; | ||
|
||
internal interface IFrameHandler | ||
{ | ||
void Release(Exception ex); | ||
|
||
FrameType AcceptFrame(FrameType type, MemoryBlock payload); | ||
} |
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
using System; | ||
using Microsoft.Extensions.ObjectPool; | ||
using RabbitMQ.Next.Buffers; | ||
using RabbitMQ.Next.Methods; | ||
using RabbitMQ.Next.Transport; | ||
using RabbitMQ.Next.Transport.Methods; | ||
|
||
namespace RabbitMQ.Next.Channels; | ||
|
||
internal class MethodFrameHandler<TMethod> : IFrameHandler | ||
where TMethod: struct, IIncomingMethod | ||
{ | ||
private readonly IMessageHandler<TMethod> wrapped; | ||
private readonly IMethodParser<TMethod> parser; | ||
private readonly ObjectPool<MemoryBlock> memoryPool; | ||
|
||
public MethodFrameHandler(IMessageHandler<TMethod> wrapped, IMethodParser<TMethod> parser, ObjectPool<MemoryBlock> memoryPool) | ||
{ | ||
this.wrapped = wrapped; | ||
this.parser = parser; | ||
this.memoryPool = memoryPool; | ||
} | ||
|
||
public void Release(Exception ex = null) | ||
{ | ||
this.wrapped.Release(ex); | ||
} | ||
|
||
public FrameType AcceptFrame(FrameType type, MemoryBlock payload) | ||
{ | ||
if (type != FrameType.Method) | ||
{ | ||
throw new InvalidOperationException($"Unexpected {type} frame, when Method frame was expected"); | ||
} | ||
|
||
ReadOnlySpan<byte> data = payload; | ||
data = data.Read(out uint _); | ||
|
||
var methodArgs = this.parser.Parse(data); | ||
this.memoryPool.Return(payload); | ||
this.wrapped.Handle(methodArgs, null); | ||
|
||
return FrameType.Method; | ||
} | ||
} |
111 changes: 111 additions & 0 deletions
111
src/RabbitMQ.Next/Channels/MethodWithContentFrameHandler.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
using System; | ||
using Microsoft.Extensions.ObjectPool; | ||
using RabbitMQ.Next.Buffers; | ||
using RabbitMQ.Next.Methods; | ||
using RabbitMQ.Next.Transport; | ||
using RabbitMQ.Next.Transport.Methods; | ||
|
||
namespace RabbitMQ.Next.Channels; | ||
|
||
internal class MethodWithContentFrameHandler<TMethod> : IFrameHandler | ||
where TMethod: struct, IIncomingMethod | ||
{ | ||
private readonly IMessageHandler<TMethod> wrapped; | ||
private readonly IMethodParser<TMethod> parser; | ||
private readonly ObjectPool<MemoryBlock> memoryPool; | ||
private readonly ObjectPool<LazyMessageProperties> messagePropertiesPool; | ||
|
||
private FrameType expectedFrameType = FrameType.Method; | ||
private MemoryBlock methodFrame; | ||
private MemoryBlock contentHeader; | ||
private long pendingContentSize; | ||
private MemoryBlock contentBodyHead; | ||
private MemoryBlock contentBodyTail; | ||
|
||
public MethodWithContentFrameHandler(IMessageHandler<TMethod> wrapped, IMethodParser<TMethod> parser, ObjectPool<MemoryBlock> memoryPool, ObjectPool<LazyMessageProperties> messagePropertiesPool) | ||
{ | ||
this.wrapped = wrapped; | ||
this.parser = parser; | ||
this.memoryPool = memoryPool; | ||
this.messagePropertiesPool = messagePropertiesPool; | ||
} | ||
|
||
public void Release(Exception ex = null) | ||
{ | ||
this.wrapped.Release(ex); | ||
} | ||
|
||
public FrameType AcceptFrame(FrameType type, MemoryBlock payload) | ||
{ | ||
if (type != this.expectedFrameType) | ||
{ | ||
throw new InvalidOperationException($"Expected frame type is {this.expectedFrameType} but got {type}"); | ||
} | ||
|
||
this.expectedFrameType = type switch | ||
{ | ||
FrameType.Method => this.ParseMethodFrame(payload), | ||
FrameType.ContentHeader => this.ParseContentHeaderFrame(payload), | ||
FrameType.ContentBody => this.ParseContentBodyFrame(payload), | ||
_ => throw new ArgumentOutOfRangeException(nameof(type), type, $"Non supported frame type: {type}"), | ||
}; | ||
|
||
if (this.expectedFrameType == FrameType.None) | ||
{ | ||
PayloadAccessor payloadAccessor = null; | ||
|
||
if (this.contentHeader != null) | ||
{ | ||
payloadAccessor = new PayloadAccessor(this.messagePropertiesPool, this.memoryPool, this.contentHeader, this.contentBodyHead); | ||
} | ||
|
||
var methodArgs = this.parser.Parse(((ReadOnlySpan<byte>)this.methodFrame).Read(out uint _)); | ||
|
||
this.wrapped.Handle(methodArgs, payloadAccessor); | ||
|
||
this.memoryPool.Return(this.methodFrame); | ||
|
||
// reset state | ||
this.expectedFrameType = FrameType.Method; | ||
this.methodFrame = null; | ||
this.contentHeader = null; | ||
this.pendingContentSize = 0; | ||
this.contentBodyHead = null; | ||
this.contentBodyTail = null; | ||
} | ||
|
||
return this.expectedFrameType; | ||
} | ||
|
||
private FrameType ParseMethodFrame(MemoryBlock payload) | ||
{ | ||
this.methodFrame = payload; | ||
return FrameType.ContentHeader; | ||
} | ||
|
||
private FrameType ParseContentHeaderFrame(MemoryBlock payload) | ||
{ | ||
((ReadOnlySpan<byte>)payload)[4..] // skip 2 obsolete shorts | ||
.Read(out ulong contentSize); | ||
|
||
this.pendingContentSize = (long)contentSize; | ||
this.contentHeader = payload; | ||
return FrameType.ContentBody; | ||
} | ||
|
||
private FrameType ParseContentBodyFrame(MemoryBlock payload) | ||
{ | ||
if (this.contentBodyHead == null) | ||
{ | ||
this.contentBodyHead = payload; | ||
this.contentBodyTail = payload; | ||
} | ||
else | ||
{ | ||
this.contentBodyTail = this.contentBodyTail.Append(payload); | ||
} | ||
|
||
this.pendingContentSize -= payload.Length; | ||
return (this.pendingContentSize > 0) ? FrameType.ContentBody : FrameType.None; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.