Skip to content

Commit 16e11ec

Browse files
committed
various improvements around frames
1 parent 6a0488e commit 16e11ec

File tree

4 files changed

+100
-77
lines changed

4 files changed

+100
-77
lines changed

projects/RabbitMQ.Client/client/impl/Command.cs

-22
Original file line numberDiff line numberDiff line change
@@ -57,11 +57,6 @@ class Command : IDisposable
5757
private const int EmptyFrameSize = 8;
5858
private readonly bool _returnBufferOnDispose;
5959

60-
static Command()
61-
{
62-
CheckEmptyFrameSize();
63-
}
64-
6560
internal Command(MethodBase method) : this(method, null, null, false)
6661
{
6762
}
@@ -80,23 +75,6 @@ public Command(MethodBase method, ContentHeaderBase header, ReadOnlyMemory<byte>
8075

8176
internal MethodBase Method { get; private set; }
8277

83-
public static void CheckEmptyFrameSize()
84-
{
85-
var f = new EmptyOutboundFrame();
86-
byte[] b = new byte[f.GetMinimumBufferSize()];
87-
f.WriteTo(b);
88-
long actualLength = f.ByteCount;
89-
90-
if (EmptyFrameSize != actualLength)
91-
{
92-
string message =
93-
string.Format("EmptyFrameSize is incorrect - defined as {0} where the computed value is in fact {1}.",
94-
EmptyFrameSize,
95-
actualLength);
96-
throw new ProtocolViolationException(message);
97-
}
98-
}
99-
10078
internal void Transmit(int channelNumber, Connection connection)
10179
{
10280
connection.WriteFrame(new MethodOutboundFrame(channelNumber, Method));

projects/RabbitMQ.Client/client/impl/ContentHeaderBase.cs

+3-2
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,9 @@ internal ulong ReadFrom(ReadOnlyMemory<byte> memory)
8383

8484
internal int WriteTo(Memory<byte> memory, ulong bodySize)
8585
{
86-
NetworkOrderSerializer.WriteUInt16(memory.Span, ZERO); // Weight - not used
87-
NetworkOrderSerializer.WriteUInt64(memory.Slice(2).Span, bodySize);
86+
var span = memory.Span;
87+
NetworkOrderSerializer.WriteUInt16(span, ZERO); // Weight - not used
88+
NetworkOrderSerializer.WriteUInt64(span.Slice(2), bodySize);
8889

8990
ContentHeaderPropertyWriter writer = new ContentHeaderPropertyWriter(memory.Slice(10));
9091
WritePropertiesTo(ref writer);

projects/RabbitMQ.Client/client/impl/Frame.cs

+27-53
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@
4545
using System.Runtime.ExceptionServices;
4646
using System.Runtime.InteropServices;
4747
using RabbitMQ.Client.Exceptions;
48-
using RabbitMQ.Client.Framing;
4948
using RabbitMQ.Util;
5049

5150
namespace RabbitMQ.Client.Impl
@@ -73,7 +72,7 @@ internal override int WritePayload(Memory<byte> memory)
7372
NetworkOrderSerializer.WriteUInt16(memory.Span, _header.ProtocolClassId);
7473
// write header (X bytes)
7574
int bytesWritten = _header.WriteTo(memory.Slice(2), (ulong)_bodyLength);
76-
return 2 + bytesWritten;
75+
return bytesWritten + 2;
7776
}
7877
}
7978

@@ -115,8 +114,9 @@ internal override int GetMinimumPayloadBufferSize()
115114

116115
internal override int WritePayload(Memory<byte> memory)
117116
{
118-
NetworkOrderSerializer.WriteUInt16(memory.Span, _method.ProtocolClassId);
119-
NetworkOrderSerializer.WriteUInt16(memory.Slice(2).Span, _method.ProtocolMethodId);
117+
var span = memory.Span;
118+
NetworkOrderSerializer.WriteUInt16(span, _method.ProtocolClassId);
119+
NetworkOrderSerializer.WriteUInt16(span.Slice(2), _method.ProtocolMethodId);
120120
var argWriter = new MethodArgumentWriter(memory.Slice(4));
121121
_method.WriteArgumentsTo(ref argWriter);
122122
argWriter.Flush();
@@ -141,21 +141,25 @@ internal override int WritePayload(Memory<byte> memory)
141141
}
142142
}
143143

144-
abstract class OutboundFrame : Frame
144+
internal abstract class OutboundFrame
145145
{
146-
public int ByteCount { get; private set; } = 0;
147-
public OutboundFrame(FrameType type, int channel) : base(type, channel)
146+
public int Channel { get; }
147+
public FrameType Type { get; }
148+
149+
protected OutboundFrame(FrameType type, int channel)
148150
{
151+
Type = type;
152+
Channel = channel;
149153
}
150154

151155
internal void WriteTo(Memory<byte> memory)
152156
{
153-
memory.Span[0] = (byte)Type;
154-
NetworkOrderSerializer.WriteUInt16(memory.Slice(1).Span, (ushort)Channel);
157+
var span = memory.Span;
158+
span[0] = (byte)Type;
159+
NetworkOrderSerializer.WriteUInt16(span.Slice(1), (ushort)Channel);
155160
int bytesWritten = WritePayload(memory.Slice(7));
156-
NetworkOrderSerializer.WriteUInt32(memory.Slice(3).Span, (uint)bytesWritten);
157-
memory.Span[bytesWritten + 7] = Constants.FrameEnd;
158-
ByteCount = bytesWritten + 8;
161+
NetworkOrderSerializer.WriteUInt32(span.Slice(3), (uint)bytesWritten);
162+
span[bytesWritten + 7] = Constants.FrameEnd;
159163
}
160164

161165
internal abstract int WritePayload(Memory<byte> memory);
@@ -164,6 +168,11 @@ internal int GetMinimumBufferSize()
164168
{
165169
return 8 + GetMinimumPayloadBufferSize();
166170
}
171+
172+
public override string ToString()
173+
{
174+
return $"(type={Type}, channel={Channel})";
175+
}
167176
}
168177

169178
internal readonly struct InboundFrame : IDisposable
@@ -304,47 +313,12 @@ public override string ToString()
304313
return $"(type={Type}, channel={Channel}, {Payload.Length} bytes of payload)";
305314
}
306315
}
307-
308-
class Frame
309-
{
310-
public Frame(FrameType type, int channel)
311-
{
312-
Type = type;
313-
Channel = channel;
314-
Payload = null;
315-
}
316-
317-
public Frame(FrameType type, int channel, ReadOnlyMemory<byte> payload)
318-
{
319-
Type = type;
320-
Channel = channel;
321-
Payload = payload;
322-
}
323-
324-
public int Channel { get; private set; }
325-
326-
public ReadOnlyMemory<byte> Payload { get; private set; }
327-
328-
public FrameType Type { get; private set; }
329-
330-
public override string ToString()
331-
{
332-
return string.Format("(type={0}, channel={1}, {2} bytes of payload)",
333-
Type,
334-
Channel,
335-
Payload.Length.ToString());
336-
}
337-
338-
339-
}
340-
341-
enum FrameType : int
316+
317+
internal enum FrameType : int
342318
{
343-
FrameMethod = 1,
344-
FrameHeader = 2,
345-
FrameBody = 3,
346-
FrameHeartbeat = 8,
347-
FrameEnd = 206,
348-
FrameMinSize = 4096
319+
FrameMethod = Constants.FrameMethod,
320+
FrameHeader = Constants.FrameHeader,
321+
FrameBody = Constants.FrameBody,
322+
FrameHeartbeat = Constants.FrameHeartbeat
349323
}
350324
}

projects/Unit/TestFrameFormatting.cs

+70
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
// This source code is dual-licensed under the Apache License, version
2+
// 2.0, and the Mozilla Public License, version 1.1.
3+
//
4+
// The APL v2.0:
5+
//
6+
//---------------------------------------------------------------------------
7+
// Copyright (c) 2007-2020 VMware, Inc.
8+
//
9+
// Licensed under the Apache License, Version 2.0 (the "License");
10+
// you may not use this file except in compliance with the License.
11+
// You may obtain a copy of the License at
12+
//
13+
// https://www.apache.org/licenses/LICENSE-2.0
14+
//
15+
// Unless required by applicable law or agreed to in writing, software
16+
// distributed under the License is distributed on an "AS IS" BASIS,
17+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18+
// See the License for the specific language governing permissions and
19+
// limitations under the License.
20+
//---------------------------------------------------------------------------
21+
//
22+
// The MPL v1.1:
23+
//
24+
//---------------------------------------------------------------------------
25+
// The contents of this file are subject to the Mozilla Public License
26+
// Version 1.1 (the "License"); you may not use this file except in
27+
// compliance with the License. You may obtain a copy of the License
28+
// at https://www.mozilla.org/MPL/
29+
//
30+
// Software distributed under the License is distributed on an "AS IS"
31+
// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
32+
// the License for the specific language governing rights and
33+
// limitations under the License.
34+
//
35+
// The Original Code is RabbitMQ.
36+
//
37+
// The Initial Developer of the Original Code is Pivotal Software, Inc.
38+
// Copyright (c) 2007-2020 VMware, Inc. All rights reserved.
39+
//---------------------------------------------------------------------------
40+
41+
using NUnit.Framework;
42+
43+
using RabbitMQ.Client.Impl;
44+
45+
namespace RabbitMQ.Client.Unit
46+
{
47+
[TestFixture]
48+
class TestFrameFormatting : WireFormattingFixture
49+
{
50+
[Test]
51+
public void EmptyOutboundFrame()
52+
{
53+
var frame = new EmptyOutboundFrame();
54+
var body = new byte[frame.GetMinimumBufferSize()];
55+
56+
frame.WriteTo(body);
57+
58+
Assert.AreEqual(0, frame.GetMinimumPayloadBufferSize());
59+
Assert.AreEqual(8, frame.GetMinimumBufferSize());
60+
Assert.AreEqual(Constants.FrameHeartbeat, body[0]);
61+
Assert.AreEqual(0, body[1]); // channel
62+
Assert.AreEqual(0, body[2]); // channel
63+
Assert.AreEqual(0, body[3]); // payload size
64+
Assert.AreEqual(0, body[4]); // payload size
65+
Assert.AreEqual(0, body[5]); // payload size
66+
Assert.AreEqual(0, body[6]); // payload size
67+
Assert.AreEqual(Constants.FrameEnd, body[7]);
68+
}
69+
}
70+
}

0 commit comments

Comments
 (0)