-
Notifications
You must be signed in to change notification settings - Fork 511
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Context-aware methods to ProviderClient and ServiceClient
Provide new methods to leverage per-call `context.Context`. This version, suitable to be backported to `v1`, vendors the context package from the v1.21 standard library, to make "context.AfterFunc" available.
- Loading branch information
1 parent
51831d9
commit e8bd3c5
Showing
4 changed files
with
874 additions
and
37 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
package gophercloud | ||
|
||
import ( | ||
"context" | ||
"time" | ||
|
||
future_context "github.com/gophercloud/gophercloud/internal/context" | ||
) | ||
|
||
type mergeContext struct { | ||
context.Context | ||
ctx2 context.Context | ||
} | ||
|
||
// MergeContext returns a context that is cancelled when at least one of the | ||
// parents is cancelled. The returned context also returns the values of ctx1, | ||
// or ctx2 if nil. | ||
func MergeContext(ctx1, ctx2 context.Context) (context.Context, context.CancelFunc) { | ||
ctx, cancel := context.WithCancelCause(ctx1) | ||
stop := future_context.AfterFunc(ctx2, func() { | ||
cancel(future_context.Cause(ctx2)) | ||
}) | ||
|
||
return &mergeContext{ | ||
Context: ctx, | ||
ctx2: ctx2, | ||
}, func() { | ||
stop() | ||
cancel(context.Canceled) | ||
} | ||
} | ||
|
||
// Value returns ctx2's value if ctx's is nil. | ||
func (ctx *mergeContext) Value(key interface{}) interface{} { | ||
if v := ctx.Context.Value(key); v != nil { | ||
return v | ||
} | ||
return ctx.ctx2.Value(key) | ||
} | ||
|
||
// Deadline returns the earlier deadline of the two parents of ctx. | ||
func (ctx *mergeContext) Deadline() (time.Time, bool) { | ||
if d1, ok := ctx.Context.Deadline(); ok { | ||
if d2, ok := ctx.ctx2.Deadline(); ok { | ||
if d1.Before(d2) { | ||
return d1, true | ||
} else { | ||
return d2, true | ||
} | ||
} | ||
return d1, ok | ||
} | ||
return ctx.ctx2.Deadline() | ||
} |
Oops, something went wrong.