-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
base: main
Are you sure you want to change the base?
Conversation
a25b984
to
dabeb33
Compare
There was a problem hiding this 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.
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. |
activemq-client/src/main/java/org/apache/activemq/management/UnsampledStatisticImpl.java
Show resolved
Hide resolved
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; |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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 { |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
Reviewer notes: