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
Add FilteredStreamMessage.onCancellation() #3375
Conversation
Motivation: An implementation of the `FilteredStreamMessage` might have resources to release when the `StreamMessage` is complete. For example, an `HttpResponse` from `ContentPreviewingService` should call `ContentPreviewer.produce()` to release the resource and produce the content preview. However, the `FilteredStreamMessage` is not notified when the `StreamMessage` is canceled by the `Subscriber`. Modification: - Add `FilteredStreamMessage.beforeCancel()` so that an implementation of the message can add a hook before `Subscription.cancel()`. Result: - You no longer see that the log is not complete when applying `ContentPreviewingService`.
Codecov Report
@@ Coverage Diff @@
## master #3375 +/- ##
============================================
- Coverage 74.31% 74.29% -0.02%
- Complexity 13527 13534 +7
============================================
Files 1174 1174
Lines 51703 51744 +41
Branches 6631 6641 +10
============================================
+ Hits 38422 38443 +21
- Misses 9915 9931 +16
- Partials 3366 3370 +4 Continue to review full report at Codecov.
|
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.
Could you check this FilteredStreamMessage
?
armeria/grpc/src/main/java/com/linecorp/armeria/internal/client/grpc/GrpcWebTrailersExtractor.java
Lines 133 to 142 in bd09b15
@Override | |
protected void beforeComplete(Subscriber<? super HttpObject> subscriber) { | |
publisher.close(); | |
} | |
@Override | |
protected Throwable beforeError(Subscriber<? super HttpObject> subscriber, Throwable cause) { | |
publisher.close(); | |
return cause; | |
} |
core/src/main/java/com/linecorp/armeria/internal/logging/ContentPreviewingUtil.java
Outdated
Show resolved
Hide resolved
core/src/main/java/com/linecorp/armeria/internal/logging/ContentPreviewingUtil.java
Outdated
Show resolved
Hide resolved
|
Indeed it is. 😅 |
// Call requestContentPreview(null) to make sure that the log is complete. | ||
ctx.logBuilder().responseContentPreview(null); | ||
} | ||
produceResponseContentPreview(responseContentPreviewer); |
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.
Is there any chance that subscriber.onComplete()
and subscription.cancel()
are called concurrently?
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.
Maybe we could have an atomic flag, then we won't even need the cause instanceof CancelledSubscriptionException
checks.
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 realized that if we introduce an atomic flag, a user needs to do the extra work because beforeCancel()
and beforeError()
can be called twice in certain situation.
So let me just remove beforeCancel()
and handle the cancelation event in beforeError
.
core/src/main/java/com/linecorp/armeria/server/encoding/HttpDecodedRequest.java
Outdated
Show resolved
Hide resolved
core/src/main/java/com/linecorp/armeria/server/encoding/HttpEncodedResponse.java
Show resolved
Hide resolved
grpc/src/main/java/com/linecorp/armeria/internal/client/grpc/GrpcWebTrailersExtractor.java
Outdated
Show resolved
Hide resolved
core/src/main/java/com/linecorp/armeria/common/stream/FilteredStreamMessage.java
Outdated
Show resolved
Hide resolved
core/src/main/java/com/linecorp/armeria/common/stream/FilteredStreamMessage.java
Outdated
Show resolved
Hide resolved
core/src/main/java/com/linecorp/armeria/client/encoding/HttpDecodedResponse.java
Outdated
Show resolved
Hide resolved
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.
Thanks a lot! @minwoox
core/src/test/java/com/linecorp/armeria/server/DefaultServiceRequestContextTest.java
Show resolved
Hide resolved
Would you mind resolving the conflicting files? 😄 |
Thanks fixed. 😉 |
core/src/main/java/com/linecorp/armeria/client/encoding/HttpDecodedResponse.java
Outdated
Show resolved
Hide resolved
core/src/main/java/com/linecorp/armeria/client/encoding/HttpDecodedResponse.java
Outdated
Show resolved
Hide resolved
core/src/main/java/com/linecorp/armeria/client/encoding/HttpDecodedResponse.java
Outdated
Show resolved
Hide resolved
core/src/main/java/com/linecorp/armeria/server/encoding/HttpDecodedRequest.java
Outdated
Show resolved
Hide resolved
core/src/main/java/com/linecorp/armeria/server/encoding/HttpDecodedRequest.java
Outdated
Show resolved
Hide resolved
core/src/main/java/com/linecorp/armeria/server/encoding/HttpDecodedRequest.java
Outdated
Show resolved
Hide resolved
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.
Thanks, @minwoox !
Thanks for reviewing. 😉 |
Motivation:
An implementation of the
FilteredStreamMessage
might have resources to release whenthe
StreamMessage
is complete. For example, anHttpResponse
fromContentPreviewingService
should callContentPreviewer.produce()
to release the resource and produce the content preview.However, because we don't provide a hook for
Subscription.cancel()
, it's easy to forget to clean up resources when the stream message is canceled.Modification:
FilteredStreamMessage.onCancellation()
.Result:
FilteredStreamMessage.onCancellation(...)
whenSubscription.cancel()
is called.ContentPreviewingService
.