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

Implement rollback stage for kubernetes plugin #5390

Merged
merged 12 commits into from
Dec 6, 2024
Merged

Conversation

Warashi
Copy link
Contributor

@Warashi Warashi commented Dec 4, 2024

What this PR does:

  • Implement executeK8sRollbackStage
  • refactor duplicates of executeK8sSyncStage and executeK8sRollbackStage
    • There are some duplicates remaining, but these parts has unimplemented TODOs. so I didn't refactor all of them.

Why we need it:

We have to support rollback of k8s stages

Which issue(s) this PR fixes:

Part of #4980

Does this PR introduce a user-facing change?: No

  • How are users affected by this change:
  • Is this breaking change:
  • How to migrate (if breaking change):

…text cancellation handling

Signed-off-by: Shinnosuke Sawada-Dazai <[email protected]>
Signed-off-by: Shinnosuke Sawada-Dazai <[email protected]>
Signed-off-by: Shinnosuke Sawada-Dazai <[email protected]>
Copy link

codecov bot commented Dec 4, 2024

Codecov Report

Attention: Patch coverage is 8.65385% with 95 lines in your changes missing coverage. Please review.

Project coverage is 25.81%. Comparing base (5831f36) to head (02a4df2).
Report is 3 commits behind head on master.

Files with missing lines Patch % Lines
...app/pipedv1/plugin/kubernetes/deployment/server.go 0.00% 80 Missing ⚠️
pkg/rpc/server.go 0.00% 6 Missing and 1 partial ⚠️
pkg/rpc/signal_interceptor.go 0.00% 5 Missing ⚠️
pkg/plugin/signalhandler/handler.go 81.81% 2 Missing ⚠️
pkg/app/pipedv1/plugin/kubernetes/server.go 0.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #5390      +/-   ##
==========================================
- Coverage   25.82%   25.81%   -0.01%     
==========================================
  Files         448      450       +2     
  Lines       48281    48337      +56     
==========================================
+ Hits        12468    12480      +12     
- Misses      34841    34885      +44     
  Partials      972      972              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Comment on lines 215 to 217
if !response.GetStatus().IsCompleted() && errors.Is(ctx.Err(), context.Canceled) {
return
}
Copy link
Member

Choose a reason for hiding this comment

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

@Warashi
[Ask]
I thought that we should not mark the log persisted as completed when stage is still running regardless of context cancel.
Also, we should not mark the log persister as completed when the context is canceled.
WDYT?

it means we should !response.GetStatus().IsCompleted() || errors.Is(ctx.Err(), context.Canceled) ?

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 realized that we have to handle two cancellations, but we cannot determine the cause because the cancel is propagated beyond the gRPC layer.

  1. cancellation occurred by graceful shutdown.
    • in this case, we should not mark the log persister as completed.
  2. cancellation occurred by the user via the web UI.
    • in this case, we should return the status as canceled and mark the log persister as completed.

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 realized the plugin receives SIGTERM or SIGINT when the graceful shutdown is going, so I implemented the handling of them.
When the cancellation occurs without receiving such signals, the log persister should be completed.

@Warashi
Copy link
Contributor Author

Warashi commented Dec 6, 2024

I realized that the plugin should return the StageStatus and should not return an error even if the error has occurred.
Because the plugin can return StageStatus_FAILURE if the error occurs.
I'll change my codes.

👉🏻 DONE

…eStageResponse

Signed-off-by: Shinnosuke Sawada-Dazai <[email protected]>
Copy link
Member

@khanhtc1202 khanhtc1202 left a comment

Choose a reason for hiding this comment

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

LGTM with small nits

Co-authored-by: Khanh Tran <[email protected]>
Signed-off-by: Shinnosuke Sawada-Dazai <[email protected]>
@Warashi Warashi requested a review from khanhtc1202 December 6, 2024 03:47
khanhtc1202
khanhtc1202 previously approved these changes Dec 6, 2024
Copy link
Member

@khanhtc1202 khanhtc1202 left a comment

Choose a reason for hiding this comment

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

LGTM 👍

Comment on lines +25 to +31
// SignalHandlingInterceptor is a gRPC interceptor that cancels the context when a termination signal is received.
func SignalHandlingInterceptor(ctx context.Context, req any, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp any, err error) {
ctx, cancel := signal.NotifyContext(ctx, syscall.SIGINT, syscall.SIGTERM)
defer cancel()

return handler(ctx, req)
}
Copy link
Member

Choose a reason for hiding this comment

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

@Warashi Sorry, I noticed that we can't distinguish Graceful Shutdown and context cancel for now. piped still treats both as context canceled.

We might use signal.Notify like this.

Suggested change
// SignalHandlingInterceptor is a gRPC interceptor that cancels the context when a termination signal is received.
func SignalHandlingInterceptor(ctx context.Context, req any, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp any, err error) {
ctx, cancel := signal.NotifyContext(ctx, syscall.SIGINT, syscall.SIGTERM)
defer cancel()
return handler(ctx, req)
}
// SignalHandlingInterceptor is a gRPC interceptor that cancels the context when a termination signal is received.
var terminated atomic.Bool
// SignalHandlingInterceptor is a gRPC interceptor that cancels the context when a termination signal is received.
func SignalHandlingInterceptor(ctx context.Context, req any, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp any, err error) {
sigCh := make(chan os.Signal, 1)
signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM)
ctx, cancel := context.WithCancel(ctx)
defer cancel()
go func() {
select {
case <-sigCh:
// received a termination signal
terminated.Store(true)
cancel()
}
}()
return handler(ctx, req)
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@ffjlabo
I implemented the determination of the Graceful Shutdown in this file. Is it not enough?

pkg/plugin/signalhandler/handler.go

Copy link
Member

Choose a reason for hiding this comment

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

@Warashi I got it. Sorry, I missed it. 🙏

Copy link
Member

@ffjlabo ffjlabo left a comment

Choose a reason for hiding this comment

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

Thank you for the fix! left a nit comment.

Comment on lines 37 to 44
func init() {
ctx, cancel := signal.NotifyContext(context.Background(), signals...)
go func() {
defer cancel()
<-ctx.Done()
terminated.Store(true)
}()
}
Copy link
Member

Choose a reason for hiding this comment

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

[nit] We should add a comment to describe that this distinguishes context.Cancel and Graceful shutdown.

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 added the comments. Please check whether the comments are enough.
02a4df2

Copy link
Member

@ffjlabo ffjlabo left a comment

Choose a reason for hiding this comment

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

LGTM 👍

@Warashi Warashi merged commit 1d3b532 into master Dec 6, 2024
16 of 18 checks passed
@Warashi Warashi deleted the k8s-plugin-rollback branch December 6, 2024 07:06
@github-actions github-actions bot mentioned this pull request Jan 21, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants