mirror of
https://github.com/ipfs/kubo.git
synced 2026-02-27 05:17:49 +08:00
util: fractional context
This commit is contained in:
parent
cc7a869e3d
commit
ec96a0b0b5
22
util/ctx/fracctx.go
Normal file
22
util/ctx/fracctx.go
Normal file
@ -0,0 +1,22 @@
|
||||
package ctxutil
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
|
||||
)
|
||||
|
||||
func WithDeadlineFraction(ctx context.Context, fraction float64) (context.Context, context.CancelFunc) {
|
||||
d, found := ctx.Deadline()
|
||||
if !found { // no deadline
|
||||
return context.WithCancel(ctx)
|
||||
}
|
||||
|
||||
left := d.Sub(time.Now())
|
||||
if left < 0 { // already passed...
|
||||
return context.WithCancel(ctx)
|
||||
}
|
||||
|
||||
left = time.Duration(float64(left) * fraction)
|
||||
return context.WithTimeout(ctx, left)
|
||||
}
|
||||
137
util/ctx/fracctx_test.go
Normal file
137
util/ctx/fracctx_test.go
Normal file
@ -0,0 +1,137 @@
|
||||
package ctxutil
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
|
||||
)
|
||||
|
||||
// this test is on the context tool itself, not our stuff. it's for sanity on ours.
|
||||
func TestDeadline(t *testing.T) {
|
||||
ctx, _ := context.WithTimeout(context.Background(), 5*time.Millisecond)
|
||||
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
t.Fatal("ended too early")
|
||||
default:
|
||||
}
|
||||
|
||||
<-time.After(6 * time.Millisecond)
|
||||
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
default:
|
||||
t.Fatal("ended too late")
|
||||
}
|
||||
}
|
||||
|
||||
func TestDeadlineFractionForever(t *testing.T) {
|
||||
|
||||
ctx, _ := WithDeadlineFraction(context.Background(), 0.5)
|
||||
|
||||
_, found := ctx.Deadline()
|
||||
if found {
|
||||
t.Fatal("should last forever")
|
||||
}
|
||||
}
|
||||
|
||||
func TestDeadlineFractionHalf(t *testing.T) {
|
||||
|
||||
ctx1, _ := context.WithTimeout(context.Background(), 10*time.Millisecond)
|
||||
ctx2, _ := WithDeadlineFraction(ctx1, 0.5)
|
||||
|
||||
select {
|
||||
case <-ctx1.Done():
|
||||
t.Fatal("ctx1 ended too early")
|
||||
case <-ctx2.Done():
|
||||
t.Fatal("ctx2 ended too early")
|
||||
default:
|
||||
}
|
||||
|
||||
<-time.After(2 * time.Millisecond)
|
||||
|
||||
select {
|
||||
case <-ctx1.Done():
|
||||
t.Fatal("ctx1 ended too early")
|
||||
case <-ctx2.Done():
|
||||
t.Fatal("ctx2 ended too early")
|
||||
default:
|
||||
}
|
||||
|
||||
<-time.After(4 * time.Millisecond)
|
||||
|
||||
select {
|
||||
case <-ctx1.Done():
|
||||
t.Fatal("ctx1 ended too early")
|
||||
case <-ctx2.Done():
|
||||
default:
|
||||
t.Fatal("ctx2 ended too late")
|
||||
}
|
||||
|
||||
<-time.After(6 * time.Millisecond)
|
||||
|
||||
select {
|
||||
case <-ctx1.Done():
|
||||
default:
|
||||
t.Fatal("ctx1 ended too late")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestDeadlineFractionCancel(t *testing.T) {
|
||||
|
||||
ctx1, cancel1 := context.WithTimeout(context.Background(), 10*time.Millisecond)
|
||||
ctx2, cancel2 := WithDeadlineFraction(ctx1, 0.5)
|
||||
|
||||
select {
|
||||
case <-ctx1.Done():
|
||||
t.Fatal("ctx1 ended too early")
|
||||
case <-ctx2.Done():
|
||||
t.Fatal("ctx2 ended too early")
|
||||
default:
|
||||
}
|
||||
|
||||
cancel2()
|
||||
|
||||
select {
|
||||
case <-ctx1.Done():
|
||||
t.Fatal("ctx1 should NOT be cancelled")
|
||||
case <-ctx2.Done():
|
||||
default:
|
||||
t.Fatal("ctx2 should be cancelled")
|
||||
}
|
||||
|
||||
cancel1()
|
||||
|
||||
select {
|
||||
case <-ctx1.Done():
|
||||
case <-ctx2.Done():
|
||||
default:
|
||||
t.Fatal("ctx1 should be cancelled")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestDeadlineFractionObeysParent(t *testing.T) {
|
||||
|
||||
ctx1, cancel1 := context.WithTimeout(context.Background(), 10*time.Millisecond)
|
||||
ctx2, _ := WithDeadlineFraction(ctx1, 0.5)
|
||||
|
||||
select {
|
||||
case <-ctx1.Done():
|
||||
t.Fatal("ctx1 ended too early")
|
||||
case <-ctx2.Done():
|
||||
t.Fatal("ctx2 ended too early")
|
||||
default:
|
||||
}
|
||||
|
||||
cancel1()
|
||||
|
||||
select {
|
||||
case <-ctx2.Done():
|
||||
default:
|
||||
t.Fatal("ctx2 should be cancelled")
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user