Conversation
💚 Build Succeeded
Expand to view the summary
Build stats
Test stats 🧪
💚 Flaky test reportTests succeeded. Expand to view the summary
Test stats 🧪
|
Codecov Report
@@ Coverage Diff @@
## master #1599 +/- ##
============================================
+ Coverage 58.77% 59.30% +0.52%
- Complexity 92 3462 +3370
============================================
Files 399 403 +4
Lines 17864 18239 +375
Branches 2475 2512 +37
============================================
+ Hits 10500 10817 +317
- Misses 6641 6663 +22
- Partials 723 759 +36 Continue to review full report at Codecov.
|
| return null; | ||
| } | ||
| try { | ||
| payloadSerializer.blockUntilReady(); |
There was a problem hiding this comment.
Not saying this doesn't work but did you consider providing a Future<MetaData> in the constructor and blocking on Future#get here and call DslJsonSerializer#serializeMetadata(MetaData metaData)? That way, we could keep state management out of the DslJsonSerializer.
There was a problem hiding this comment.
Of course, this is how I started, but there were several reasons I changed that: the first is that nobody really needs the metadata object, it is spread around just so it can be handed to serialization. Spreading a Future made even less sense.
In addition, I wanted to create a central serialization for it, meaning that MetaData (or something else) needs to serialize and hold the serialized data. This would mean that MetaData (or something else) now either create and use a PayloadSerializer, or I extract the metadata serialization from the rest, but that proved to be too painful and risky for this PR. Both options looked bad when I tried them, worse then doing it internally within the serializer.
Lastly, blocking during serialization itself doesn't seem right, for example- you better only start the HTTP request when ready to write to it. So I thought it would be better if the serialization interface provides a good indication for that, instead of relying on Future#get (this is not the only usage of it) that each serializer user needs to figure out.
Bottom line - there are many options to do that and I played with several ending with this. Given the multiple dependencies we had on MetaData and the time I wanted to spend on this, this seems as the least ugly.
There was a problem hiding this comment.
Thanks for explaining the background
There was a problem hiding this comment.
[minor] maybe add a small comment why we do that here in the "least ugly" way
There was a problem hiding this comment.
I don't mind, but I think it is weird to explain why something was chosen over something else you wouldn't necessarily consider as a default option. Imagine you only see this code now for the first time- MetaData can be easily an internal serialization thing not known to the outer world (it is not package private only not to broaden the refactoring of this PR even more). In such case, this is the interface of the serializer- it needs time to fully initialize, no matter why, so users of it should be aware. I made efforts to emphasize this in the API as much as possible, including javadoc and an Exception which is part of the API.
SylvainJuge
left a comment
There was a problem hiding this comment.
Nice! we can definitely see that having an asynchronous fetching of metadata is not without complications.
| return null; | ||
| } | ||
| try { | ||
| payloadSerializer.blockUntilReady(); |
There was a problem hiding this comment.
[minor] maybe add a small comment why we do that here in the "least ugly" way
apm-agent-core/src/main/java/co/elastic/apm/agent/report/serialize/DslJsonSerializer.java
Show resolved
Hide resolved
|
|
||
| void writeBytes(byte[] bytes, int len); | ||
|
|
||
| class UninitializedException extends Exception { |
There was a problem hiding this comment.
I would make this a sub-class of IllegalStateException and not checked exception as it would be thrown only when there is a bug (we didn't waited enough or there was an error), it's not a recoverable error like an IOException .
There was a problem hiding this comment.
The main purpose of this type is to make anyone calling methods that throws it aware of the requirement for initialization, and the javadoc explains that. I prefer you notice this in compilation and for that it needs to be a checked Exception.
it's not a recoverable
Not sure why - it may affect only the first send/serialization and not the subsequent ones.
apm-agent-core/src/test/java/co/elastic/apm/agent/MockReporter.java
Outdated
Show resolved
Hide resolved
apm-agent-core/src/test/java/co/elastic/apm/agent/impl/MetaDataTest.java
Show resolved
Hide resolved
...apm-kafka-headers-plugin/src/test/java/co/elastic/apm/agent/kafka/KafkaClientVersionsIT.java
Outdated
Show resolved
Hide resolved
|
|
||
| @Override | ||
| public boolean onLineAvailable(TailableFile tailableFile, byte[] line, int offset, int length, boolean eol) throws IOException { | ||
| public boolean onLineAvailable(TailableFile tailableFile, byte[] line, int offset, int length, boolean eol) throws Exception { |
There was a problem hiding this comment.
[question] why change to the broad Exception here ? If it's a way to make uses of this API to having to handle potential exceptions, that would be worth to add the the method Javadoc to be explicit.
There was a problem hiding this comment.
Because it felt inappropriate to add UninitializedException (serializer-specific) to the FileChangeListener interface...
Would you prefer that? Or something else?
apm-agent-core/src/main/java/co/elastic/apm/agent/impl/CloudMetadataProvider.java
Show resolved
Hide resolved
| executor.shutdown(); | ||
| } | ||
|
|
||
| long futureTimeout = queryTimeoutMs + 200; |
There was a problem hiding this comment.
[question] why do we add a fixed extra timeout for the future, how do we know that 200ms is fine ?
There was a problem hiding this comment.
why do we add a fixed extra timeout for the future
We want to limit this blocking somehow, but if I use the same timeout used for the HTTP query, that would be too tight, it needs to be longer.
how do we know that 200ms is fine ?
We don't know, we live on the edge 😛
What does this PR do?
Closes #1264
Extending the work started at #1453
Checklist
CLOUD_PROVIDERoptionsCLOUD_PROVIDERoptions