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

[AMQ-8463] Add advancedMessageStatistics feature #1329

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

Conversation

mattrpav
Copy link
Contributor

@mattrpav mattrpav commented Oct 23, 2024

Reviewer notes:

  • New AdvancedMessageStatisticsEnabled flag per-policyEntry (default: false)
  • No new timestamp sampling added (ie no new System.currentTimeMillis() calls)
  • Values reset on resetStatistics
  • Values exposed via JMX
  • Enqueue Message BrokerInTime, ClientID, MessageID and MessageTimestamp fields
  • Dequeue Message BrokerInTime, BrokerOutTime, ClientID, MessageID and MessageTimestamp fields
  • Unit test for policyEntry runtime configuration modification
  • Unit test for functional testing including network include/exclude verification
  • Non-durable topics do not have brokerInTime or messageTimestamp in scope during dequeue, so those values will always be zero (0)

advanced-message-statistics

@mattrpav mattrpav self-assigned this Oct 23, 2024
@mattrpav mattrpav force-pushed the AMQ-8463 branch 4 times, most recently from a25b984 to dabeb33 Compare October 25, 2024 16:46
@mattrpav mattrpav marked this pull request as ready for review October 25, 2024 17:04
@mattrpav mattrpav changed the title WIP: [AMQ-8463] Add advancedMessageStatistics feature [AMQ-8463] Add advancedMessageStatistics feature Oct 25, 2024
Copy link
Contributor

@cshannon cshannon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One thing I noticed is the new statistic impl classes all are copy and pasted code, it seems like you could just re-use all of that if you used generics.

@cshannon
Copy link
Contributor

I know this would be a much bigger effort but if we intend to keep adding more and more metrics, from a performance and maintainability standpoint, we should really look into moving everything to Micrometer which adds more more flexibility and should be better performance. That kind of change would likely end up being a major version, ie AMQ 7.0 if we wanted to do that.

public class StringStatisticImpl extends UnsampledStatisticImpl implements StringStatistic {

// Note: [AMQ-8463] Adding volatile to 'value' would be more accurate, but performance impact
private String value = null;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should not be compromising correctness for performance. If this is multi-threaded you need to make it thread safe. Furthermore, the impact of volatile is going to be negligible in the real world.

You could use AtomicReference and make this final

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm thinking 'volatile' over AtomicReference. Same thread-safety, fewer objects created.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think the extra object creation matters in this case and the extra features of the atomic classes are nice. One thing i just realized was that if we want to use other Atomic classes like AtomicLong, which would be nice, then we may not be able to use generics after all as that atomic type needs to be different and we'd have slightly different code

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Depending on the use case this is what static atomic field updater types are for, all the features like CAS but only one static allocation.

* Example: Store a timestamp value of a recent message
*
*/
public interface LongStatistic extends UnsampledStatistic {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't need these interfaces if you just use generics as I mentioned in my other comment.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I think this could be changed, but I'm wondering if it gets verbose to the consumer of the metric. I felt my original approach was "following the as-is" vs getting to the optimal target state.

If we go generic, do we add a generic parameter for all the dimensions? Sampled, Summed, Ranged, Fixed value, etc?

I think the interfaces do a good job of communicating the type. Feels like adding generics just pushes the type info to the consuming service code.

   public UnsampledStatisticImpl<Long> getDequeuedMessageBrokerOutTime() {
        return dequeuedMessageBrokerOutTime;
    }

I'm not married to either approach.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it mostly depends on if the different types will have any logic that is different or needs to be overriden. You could also move common code into an abstract class if needed, I was just noticing a lot of copy/paste and seemed like generics could be useful.

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.

3 participants