-
-
Notifications
You must be signed in to change notification settings - Fork 885
fix(router): propagate HTTP request context into push notification tasks #869
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
base: master
Are you sure you want to change the base?
Changes from 1 commit
8b6004a
6e1ec2c
0df6075
75f33c7
adb7be4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -280,9 +280,25 @@ | |||||||||||
| return count | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
|
|
||||||||||||
| // withEitherCancel returns a context that is cancelled when either ctx1 or ctx2 is done. | ||||||||||||
| // This is useful for merging an HTTP request context with a queue-task context so that | ||||||||||||
| // a push notification is aborted when the caller disconnects OR when the queue shuts down. | ||||||||||||
| func withEitherCancel(ctx1, ctx2 context.Context) (context.Context, context.CancelFunc) { | ||||||||||||
| ctx, cancel := context.WithCancel(ctx1) | ||||||||||||
| go func() { | ||||||||||||
| select { | ||||||||||||
| case <-ctx2.Done(): | ||||||||||||
| cancel() | ||||||||||||
| case <-ctx.Done(): | ||||||||||||
| } | ||||||||||||
| }() | ||||||||||||
| return ctx, cancel | ||||||||||||
| } | ||||||||||||
|
Comment on lines
+283
to
+296
|
||||||||||||
|
|
||||||||||||
| // HandleNotification add notification to queue list. | ||||||||||||
| func handleNotification( | ||||||||||||
| _ context.Context, | ||||||||||||
| ctx context.Context, | ||||||||||||
| cfg *config.ConfYaml, | ||||||||||||
| req notify.RequestPush, | ||||||||||||
| q *queue.Queue, | ||||||||||||
|
|
@@ -306,10 +322,16 @@ | |||||||||||
| } | ||||||||||||
|
|
||||||||||||
| if isLocalSync { | ||||||||||||
| func(msg *notify.PushNotification, cfg *config.ConfYaml) { | ||||||||||||
| if err := q.QueueTask(func(ctx context.Context) error { | ||||||||||||
| func(msg *notify.PushNotification, cfg *config.ConfYaml, reqCtx context.Context) { | ||||||||||||
| if err := q.QueueTask(func(queueCtx context.Context) error { | ||||||||||||
| defer wg.Done() | ||||||||||||
| resp, err := notify.SendNotification(ctx, msg, cfg) | ||||||||||||
| // Merge the HTTP request context with the queue context so that | ||||||||||||
| // the notification is cancelled when either the client disconnects | ||||||||||||
| // or the queue shuts down. See: | ||||||||||||
| // https://github.com/appleboy/gorush/issues/422 | ||||||||||||
| mergedCtx, cancel := withEitherCancel(reqCtx, queueCtx) | ||||||||||||
| defer cancel() | ||||||||||||
| resp, err := notify.SendNotification(mergedCtx, msg, cfg) | ||||||||||||
| if err != nil { | ||||||||||||
| return err | ||||||||||||
| } | ||||||||||||
|
|
@@ -318,7 +340,7 @@ | |||||||||||
| }); err != nil { | ||||||||||||
|
||||||||||||
| }); err != nil { | |
| }); err != nil { | |
| if cfg.Core.Sync { | |
| wg.Done() | |
| } |
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.
withEitherCancelstarts a goroutine per call. Since this can run per-notification in sync mode, it adds avoidable overhead. Given this repo targets Go 1.25, consider usingcontext.AfterFunc(ctx2, cancel)(and stopping it via the returned stop func) to avoid spawning a goroutine while preserving the same cancellation semantics.