veyron2/context: Allow users to remove cancellation and deadlines from contexts.
Also remove the previous hack that prevented unmounting from being canceled.
Change-Id: I23ec4f1441de9a0b74f72df80ca84b86f4d000ff
diff --git a/runtimes/google/ipc/client.go b/runtimes/google/ipc/client.go
index c0d41df..5f53bc8 100644
--- a/runtimes/google/ipc/client.go
+++ b/runtimes/google/ipc/client.go
@@ -296,15 +296,6 @@
return
}
-func allowCancel(opts []ipc.CallOpt) bool {
- for _, o := range opts {
- if _, ok := o.(inaming.NoCancel); ok {
- return false
- }
- }
- return true
-}
-
func mkDischargeImpetus(serverBlessings []string, method string, args []interface{}) security.DischargeImpetus {
var impetus security.DischargeImpetus
if len(serverBlessings) > 0 {
@@ -500,10 +491,7 @@
continue
}
- var doneChan <-chan struct{}
- if allowCancel(opts) {
- doneChan = ctx.Done()
- }
+ doneChan := ctx.Done()
r.flow.SetDeadline(doneChan)
var (
diff --git a/runtimes/google/ipc/full_test.go b/runtimes/google/ipc/full_test.go
index f9859b2..2db17e4 100644
--- a/runtimes/google/ipc/full_test.go
+++ b/runtimes/google/ipc/full_test.go
@@ -88,7 +88,7 @@
}
func testContextWithoutDeadline() *context.T {
- var ctx *context.T
+ ctx, _ := context.RootContext()
ctx, err := ivtrace.Init(ctx, flags.VtraceFlags{})
if err != nil {
panic(err)
diff --git a/runtimes/google/ipc/server.go b/runtimes/google/ipc/server.go
index 936402c..7fc7546 100644
--- a/runtimes/google/ipc/server.go
+++ b/runtimes/google/ipc/server.go
@@ -40,6 +40,7 @@
sync.Mutex
state serverState // track state of the server.
ctx *context.T // context used by the server to make internal RPCs.
+ cancel context.CancelFunc // function to cancel the above context.
streamMgr stream.Manager // stream manager to listen for new flows.
publisher publisher.Publisher // publisher to publish mounttable mounts.
listenerOpts []stream.ListenerOpt // listener opts for Listen.
@@ -147,10 +148,12 @@
func (ReservedNameDispatcher) IPCServerOpt() {}
func InternalNewServer(ctx *context.T, streamMgr stream.Manager, ns naming.Namespace, client ipc.Client, opts ...ipc.ServerOpt) (ipc.Server, error) {
+ ctx, cancel := context.WithRootCancel(ctx)
ctx, _ = vtrace.SetNewSpan(ctx, "NewServer")
statsPrefix := naming.Join("ipc", "server", "routing-id", streamMgr.RoutingID().String())
s := &server{
ctx: ctx,
+ cancel: cancel,
streamMgr: streamMgr,
publisher: publisher.New(ctx, ns, publishPeriod),
listeners: make(map[stream.Listener]struct{}),
@@ -842,6 +845,7 @@
return verror.Make(verror.Internal, s.ctx, firstErr)
}
s.state = stopped
+ s.cancel()
return nil
}
diff --git a/runtimes/google/lib/publisher/publisher_test.go b/runtimes/google/lib/publisher/publisher_test.go
index 1fe0992..a70d1e2 100644
--- a/runtimes/google/lib/publisher/publisher_test.go
+++ b/runtimes/google/lib/publisher/publisher_test.go
@@ -23,7 +23,7 @@
}
func testContext() *context.T {
- var ctx *context.T
+ ctx, _ := context.RootContext()
ctx, err := ivtrace.Init(ctx, flags.VtraceFlags{})
if err != nil {
panic(err)
diff --git a/runtimes/google/naming/namespace/mount.go b/runtimes/google/naming/namespace/mount.go
index 7b7ce3a..0cab494 100644
--- a/runtimes/google/naming/namespace/mount.go
+++ b/runtimes/google/naming/namespace/mount.go
@@ -37,7 +37,7 @@
func unmountFromMountTable(ctx *context.T, client ipc.Client, name, server string, id string) (s status) {
s.id = id
ctx, _ = context.WithTimeout(ctx, callTimeout)
- call, err := client.StartCall(ctx, name, "Unmount", []interface{}{server}, options.NoResolve{}, inaming.NoCancel{})
+ call, err := client.StartCall(ctx, name, "Unmount", []interface{}{server}, options.NoResolve{})
s.err = err
if err != nil {
return
@@ -139,7 +139,7 @@
f := func(context *context.T, mt, id string) status {
return unmountFromMountTable(ctx, client, mt, server, id)
}
- err := ns.dispatch(ctx, name, f, inaming.NoCancel{})
+ err := ns.dispatch(ctx, name, f)
vlog.VI(1).Infof("Unmount(%s, %s) -> %v", name, server, err)
return err
}
diff --git a/runtimes/google/naming/nocancel.go b/runtimes/google/naming/nocancel.go
deleted file mode 100644
index 85e1658..0000000
--- a/runtimes/google/naming/nocancel.go
+++ /dev/null
@@ -1,11 +0,0 @@
-package naming
-
-// NoCancel is an option passed to a resolve or an IPC call that
-// instructs it to ignore cancellation for that call.
-// This is used to allow servers to unmount even after their context
-// has been cancelled.
-// TODO(mattr): Find a better mechanism for this.
-type NoCancel struct{}
-
-func (NoCancel) IPCCallOpt() {}
-func (NoCancel) NSResolveOpt() {}
diff --git a/runtimes/google/rt/runtime_test.go b/runtimes/google/rt/runtime_test.go
index 4f41e20..5d1beaf 100644
--- a/runtimes/google/rt/runtime_test.go
+++ b/runtimes/google/rt/runtime_test.go
@@ -14,7 +14,7 @@
// InitForTest creates a context for use in a test.
func InitForTest(t *testing.T) (*rt.Runtime, *context.T, veyron2.Shutdown) {
- ctx, cancel := context.WithCancel(nil)
+ ctx, cancel := context.RootContext()
r, ctx, shutdown, err := rt.Init(ctx, nil, nil, nil, flags.RuntimeFlags{}, nil)
if err != nil {
t.Fatal(err)
diff --git a/runtimes/google/testing/mocks/ipc/simple_client_test.go b/runtimes/google/testing/mocks/ipc/simple_client_test.go
index a4bd4f0..f14eb7d 100644
--- a/runtimes/google/testing/mocks/ipc/simple_client_test.go
+++ b/runtimes/google/testing/mocks/ipc/simple_client_test.go
@@ -7,11 +7,8 @@
)
func testContext() *context.T {
- // The nil context is not directly usable, we need to create
- // a context specially.
- type key struct{}
- var ctx *context.T
- return context.WithValue(ctx, key{}, nil)
+ ctx, _ := context.RootContext()
+ return ctx
}
func TestSuccessfulCalls(t *testing.T) {