Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AMQNET-625: Content Property of IBytesMessage should be idempotent #48

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

Havret
Copy link
Contributor

@Havret Havret commented Nov 15, 2019

Content Property getter should not generate side effects.

@cjwmorgan-sol could you please take a look at it?

@michaelandrepearce
Copy link
Contributor

michaelandrepearce commented Nov 16, 2019

Can you add a test where when byte message is 24 bytes long, and three read calls with a dest byte array is size 8 bytes. Expected out come is first read returns first 8 bytes aka bytes in position 0-7, second read returns bytes position 8-13 , and last read returns bytes in position 14 to 23. Test should include a further read which obviously would not return data as no further bytes to be read unless message is reset

Content Property should not generate side effects
@Havret Havret force-pushed the content-property-of-IBytesMessage-should-be-idempotent branch from ce3ee46 to c988ccc Compare November 17, 2019 12:59
@Havret
Copy link
Contributor Author

Havret commented Nov 17, 2019

@michaelandrepearce Done. Moreover I've changed slightly the name of the first test to make it more descriptive.

The other thing is that I am not sure what should be the expected behavior of Content setter when somebody starts messing with Write* methods. Content property is a peculiar thing for NMS IBytesMessage and there is no equivalent of it in JMS API, thus it would be a futile attempt to look for inspiration in qpid-jms, as I used to do to tackle previous problems.

My implementation mimics what was done in NMS MSMQ:

https://github.com/apache/activemq-nms-msmq/blob/b6d954d9a97f11459f1b34956aeae675e456dfdd/src/main/csharp/BaseMessage.cs#L42-L47

where Content Property circumvents all the bits related to Binary Writers and Readers and exposes direct access to underlying message body.

@cjwmorgan-sol, @gemmellr, @michaelandrepearce What do you think?

@cjwmorgan-sol
Copy link
Contributor

Currently modifying the return byte array reference modifies the underlying message byte array from message.Content is this desired? Or are you looking for a block copy of the Content when using get? And set?

@Havret
Copy link
Contributor Author

Havret commented Nov 18, 2019

@cjwmorgan-sol You are correct. I do return direct reference. TBH I don't know what is the expected behavior. Even if we allow mutating the underlying message representation, user always operates on deep copy of the message.

@cjwmorgan-sol
Copy link
Contributor

cjwmorgan-sol commented Nov 18, 2019

Sounds good to me. It might be worth adding a comment describing the behaviour implemented for Content set and get for bytes messages though. Where get allows read write access to the buffer's bytes and set allows modifying the Buffer (ie size), or something along those lines. Also that "user always operates on deep copy of the message". Otherwise developers have to another layer deep (amqpnetlite) to find out the byte array is safe.

@michaelandrepearce
Copy link
Contributor

So a message can only ever be in write or read mode. There are details in the spec around this and some tests that exist. Ill try dig it out and pass to you offline

@alaendle
Copy link

I "rediscovered" this issue (also can be found here: https://issues.apache.org/jira/browse/AMQNET-625), can anything be done to get the PR incorporated? The current behaviour is really annoying if you play around in test code with .Content.Length and afterwards take a look at the .Content and only see a lot of nulls 🤦‍♂️. For sure it is bad style to re-access/copy the underlying byte array, but from an equational reasoning standpoint it is hard to explain why var x = msg.Content; var l = msg.Content.Length; leads to a different result than swapping the statements var l = msg.Content.Length; var x = msg.Content; 😄

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants