Aeron.NET
Aeron.NET copied to clipboard
ExpandableArrayBuffer has exception
I attempted to upgrade Aeron.Cluster package in my project to the latest version to use ExpandableArrayBuffer, but it seems it's not expanding its size as we did in the Java version.
My old code with UnsafeBuffer and specific size:
_requestBuffer = new UnsafeBuffer(new byte[2000]);
request.Encode(_requestBuffer);
var sendRequestResult = _client.SendRequests(_requestBuffer, 0, request.Length);
And my latest code with ExpandableArrayBuffer
_requestBuffer = new ExpandableArrayBuffer();
request.Encode(_requestBuffer);
var sendRequestResult = _client.SendRequests(_requestBuffer, 0, request.Length);
I got this error:
System.IndexOutOfRangeException: index=0, length=617, capacity=128
at Adaptive.Agrona.Util.ThrowHelper.ThrowIndexOutOfRangeException(String message)
at Adaptive.Agrona.ExpandableArrayBuffer.BoundsCheck(Int32 index, Int32 length)
at Adaptive.Aeron.LogBuffer.ExclusiveTermAppender.AppendUnfragmentedMessage(Int32 termId, Int32 termOffset, HeaderWriter header, IDirectBuffer bufferOne, Int32 offsetOne, Int32 lengthOne, IDirectBuffer bufferTwo, Int32 offsetTwo, Int32 lengthTwo, ReservedValueSupplier reservedValueSupplier)
at Adaptive.Aeron.ExclusivePublication.Offer(IDirectBuffer bufferOne, Int32 offsetOne, Int32 lengthOne, IDirectBuffer bufferTwo, Int32 offsetTwo, Int32 lengthTwo, ReservedValueSupplier reservedValueSupplier)
at Adaptive.Cluster.Client.AeronCluster.Offer(IDirectBuffer buffer, Int32 offset, Int32 length)
at MyCodeNamespace.ClusterClient.SendRequests(IDirectBuffer buffer, Int32 offset, Int32 length)
Thanks for giving it a go @MarshalOfficial
Given that the buffer is still at its initial capacity of 128 and there have been no exceptions trying to write beyond that, I would check for a bug in the code that defines request.Length
.
If not, please share a minimum example that I'm able to run.
@JPWatson Thanks for following up on this. I put some code here, it might be helpful. I wrote below helper classes that "request" is an instance of this class:
public abstract class RequestBase
{
public long CorrelationId { get; set; }
public int Length { get; set; }
public abstract void Encode(IMutableDirectBuffer directBuffer);
}
public class UpdateOperationRequest : RequestBase
{
private GeneratedEncoderFromSBE _updateOperationEncoder = new GeneratedEncoderFromSBE();
private readonly MessageHeaderEncoder _headerEncoder = new MessageHeaderEncoder();
private readonly OpdateOperationDTO _data;
public UpdateAccOperationRequest(OpdateOperationDTO data)
{
_data = data;
}
public override void Encode(IMutableDirectBuffer directBuffer)
{
_updateOperationEncoder.WrapAndApplyHeader(directBuffer, 0, _headerEncoder);
_updateOperationEncoder.CorrelationId((ulong)CorrelationId);
_updateOperationEncoder.OperationCode(_data.OperationCode);
_updateOperationEncoder.Amount(_data.Amount);
_updateOperationEncoder.EffectiveDate((ushort)_data.EffectiveDate);
_updateOperationEncoder.IdType(_data.IdType);
_updateOperationEncoder.Id(_data.Id);
_updateOperationEncoder.RequestId(_data.RequestId);
_updateOperationEncoder.TransactionId(_data.TransactionId);
//Document is string type
if (!string.IsNullOrWhiteSpace(_data.Document))
{
_updateOperationEncoder.PutDocument(Encoding.UTF8.GetBytes(_data.Document), 0);
}
Length = _updateOperationEncoder.EncodedLength() + _headerEncoder.EncodedLength();
}
}
And then I used this helper class when I want to send request:
var request = new UpdateOperationRequest(data);
var _requestBuffer = new ExpandableArrayBuffer();
request.Encode(_requestBuffer);
var sendRequestResult = _client.SendRequests(_requestBuffer, 0, request.Length);
What is _updateOperationEncoder.PutDocument(Encoding.UTF8.GetBytes(_data.Document), 0)
doing behind the scenes?
How is this type generated GeneratedEncoderFromSBE
?
What is
_updateOperationEncoder.PutDocument(Encoding.UTF8.GetBytes(_data.Document), 0)
doing behind the scenes? How is this type generatedGeneratedEncoderFromSBE
?
It is a string type, you are right a better approach to fill that is below function:
_updateOperationEncoder.Document(_data.Document);
But still, I get this error:
System.ArgumentException: Source array was not long enough. Check the source index, length, and the array's lower bounds. (Parameter 'sourceArray')
at System.Array.Copy(Array sourceArray, Int32 sourceIndex, Array destinationArray, Int32 destinationIndex, Int32 length, Boolean reliable)
at System.Array.Copy(Array sourceArray, Array destinationArray, Int32 length)
at Adaptive.Agrona.ExpandableArrayBuffer.EnsureCapacity(Int32 index, Int32 length)
at Adaptive.Agrona.ExpandableArrayBuffer.PutStringWithoutLengthAscii(Int32 index, String value)
at namespaces...GeneratedEncoderFromSBE.Document(String src)
at namespaces...UpdateOperationRequest.Encode(IMutableDirectBuffer directBuffer)
OK, squashed that bug from porting. I will add some tests.
OK, squashed that bug from porting. I will add some tests.
@JPWatson Hi, Is there any update on this issue?
Planning a release in the next week or two.
Planning a release in the next week or two.
Not yet?
Apologies. Now that the 1.40 release is out, I'm aiming for next week.
If you're looking for faster turnaround times, there is an option for commercial support.
Released 1.40.0