x/ref/services/wspr: Switching WSPR to the new Server API
and removing any references to DeprecatedServer

MultiPart: 1/10
Change-Id: I56e75bf5c692f69912d03e809778bcee02e6bfd0
diff --git a/services/wspr/internal/app/app.go b/services/wspr/internal/app/app.go
index 6edb6c0..3e67250 100644
--- a/services/wspr/internal/app/app.go
+++ b/services/wspr/internal/app/app.go
@@ -580,20 +580,6 @@
 	ctx.Errorf("close called on non-existent call: %v", id)
 }
 
-func (c *Controller) maybeCreateServer(serverId uint32, opts ...rpc.ServerOpt) (*server.Server, error) {
-	c.Lock()
-	defer c.Unlock()
-	if server, ok := c.servers[serverId]; ok {
-		return server, nil
-	}
-	server, err := server.NewServer(serverId, c.listenSpec, c, opts...)
-	if err != nil {
-		return nil, err
-	}
-	c.servers[serverId] = server
-	return server, nil
-}
-
 // HandleLookupResponse handles the result of a Dispatcher.Lookup call that was
 // run by the Javascript server.
 func (c *Controller) HandleLookupResponse(ctx *context.T, id int32, data string) {
@@ -624,22 +610,25 @@
 	server.HandleAuthResponse(ctx, id, data)
 }
 
-// Serve instructs WSPR to start listening for calls on behalf
-// of a javascript server.
-func (c *Controller) Serve(ctx *context.T, _ rpc.ServerCall, name string, serverId uint32, rpcServerOpts []RpcServerOption) error {
-
+// NewServer instructs WSPR to create a server and start listening for calls on
+// behalf of a JavaScript server.
+func (c *Controller) NewServer(ctx *context.T, _ rpc.ServerCall, name string, serverId uint32, rpcServerOpts []RpcServerOption) error {
 	opts, err := c.serverOpts(rpcServerOpts)
 	if err != nil {
 		return verror.Convert(verror.ErrInternal, nil, err)
 	}
-	server, err := c.maybeCreateServer(serverId, opts...)
+
+	s, err := server.NewServer(serverId, name, c.listenSpec, c, opts...)
 	if err != nil {
 		return verror.Convert(verror.ErrInternal, nil, err)
 	}
-	ctx.VI(2).Infof("serving under name: %q", name)
-	if err := server.Serve(name); err != nil {
-		return verror.Convert(verror.ErrInternal, nil, err)
-	}
+
+	c.Lock()
+	c.servers[serverId] = s
+	c.Unlock()
+
+	ctx.VI(2).Infof("server created under name: %q", name)
+
 	return nil
 }
 
@@ -661,11 +650,11 @@
 
 // AddName adds a published name to an existing server.
 func (c *Controller) AddName(_ *context.T, _ rpc.ServerCall, serverId uint32, name string) error {
-	// Create a server for the pipe, if it does not exist already
-	server, err := c.maybeCreateServer(serverId)
+	server, err := c.getServerById(serverId)
 	if err != nil {
-		return verror.Convert(verror.ErrInternal, nil, err)
+		return err
 	}
+
 	// Add name
 	if err := server.AddName(name); err != nil {
 		return verror.Convert(verror.ErrInternal, nil, err)
@@ -675,11 +664,11 @@
 
 // RemoveName removes a published name from an existing server.
 func (c *Controller) RemoveName(_ *context.T, _ rpc.ServerCall, serverId uint32, name string) error {
-	// Create a server for the pipe, if it does not exist already
-	server, err := c.maybeCreateServer(serverId)
+	server, err := c.getServerById(serverId)
 	if err != nil {
-		return verror.Convert(verror.ErrInternal, nil, err)
+		return err
 	}
+
 	// Remove name
 	server.RemoveName(name)
 	// Remove name from signature cache as well
@@ -687,6 +676,18 @@
 	return nil
 }
 
+// getServerById return a server for the given id or an error if id does not match any servers.
+func (c *Controller) getServerById(serverId uint32) (*server.Server, error) {
+	c.Lock()
+	defer c.Unlock()
+	server, ok := c.servers[serverId]
+	if !ok {
+		return nil, verror.Convert(verror.ErrInternal, nil, fmt.Errorf("Trying to getServerById, but id %d does not match any servers.", serverId))
+	}
+
+	return server, nil
+}
+
 // HandleServerResponse handles the completion of outstanding calls to JavaScript services
 // by filling the corresponding channel with the result from JavaScript.
 func (c *Controller) HandleServerResponse(ctx *context.T, id int32, data string) {
diff --git a/services/wspr/internal/app/app_test.go b/services/wspr/internal/app/app_test.go
index 8731152..567ec85 100644
--- a/services/wspr/internal/app/app_test.go
+++ b/services/wspr/internal/app/app_test.go
@@ -352,7 +352,7 @@
 	typeEncoder := vom.NewTypeEncoder(typeStream)
 	req, err := makeRequest(typeEncoder, RpcRequest{
 		Name:       "__controller",
-		Method:     "Serve",
+		Method:     "NewServer",
 		NumInArgs:  3,
 		NumOutArgs: 1,
 		Deadline:   vdltime.Deadline{},
diff --git a/services/wspr/internal/app/controller.vdl b/services/wspr/internal/app/controller.vdl
index e464467..33f1bef 100644
--- a/services/wspr/internal/app/controller.vdl
+++ b/services/wspr/internal/app/controller.vdl
@@ -12,9 +12,9 @@
 )
 
 type Controller interface {
-	// Serve instructs WSPR to start listening for calls on behalf
-	// of a javascript server.
-	Serve(name string, serverId uint32, serverOpts []RpcServerOption) error
+	// NewServer instructs WSPR to create a server and start listening for calls on
+	// behalf of a JavaScript server.
+	NewServer(name string, serverId uint32, serverOpts []RpcServerOption) error
 	// Stop instructs WSPR to stop listening for calls for the
 	// given javascript server.
 	Stop(serverId uint32) error
diff --git a/services/wspr/internal/app/controller.vdl.go b/services/wspr/internal/app/controller.vdl.go
index 439110e..0f73a4c 100644
--- a/services/wspr/internal/app/controller.vdl.go
+++ b/services/wspr/internal/app/controller.vdl.go
@@ -22,9 +22,9 @@
 // ControllerClientMethods is the client interface
 // containing Controller methods.
 type ControllerClientMethods interface {
-	// Serve instructs WSPR to start listening for calls on behalf
-	// of a javascript server.
-	Serve(ctx *context.T, name string, serverId uint32, serverOpts []RpcServerOption, opts ...rpc.CallOpt) error
+	// NewServer instructs WSPR to create a server and start listening for calls on
+	// behalf of a JavaScript server.
+	NewServer(ctx *context.T, name string, serverId uint32, serverOpts []RpcServerOption, opts ...rpc.CallOpt) error
 	// Stop instructs WSPR to stop listening for calls for the
 	// given javascript server.
 	Stop(ctx *context.T, serverId uint32, opts ...rpc.CallOpt) error
@@ -74,8 +74,8 @@
 	name string
 }
 
-func (c implControllerClientStub) Serve(ctx *context.T, i0 string, i1 uint32, i2 []RpcServerOption, opts ...rpc.CallOpt) (err error) {
-	err = v23.GetClient(ctx).Call(ctx, c.name, "Serve", []interface{}{i0, i1, i2}, nil, opts...)
+func (c implControllerClientStub) NewServer(ctx *context.T, i0 string, i1 uint32, i2 []RpcServerOption, opts ...rpc.CallOpt) (err error) {
+	err = v23.GetClient(ctx).Call(ctx, c.name, "NewServer", []interface{}{i0, i1, i2}, nil, opts...)
 	return
 }
 
@@ -157,9 +157,9 @@
 // ControllerServerMethods is the interface a server writer
 // implements for Controller.
 type ControllerServerMethods interface {
-	// Serve instructs WSPR to start listening for calls on behalf
-	// of a javascript server.
-	Serve(ctx *context.T, call rpc.ServerCall, name string, serverId uint32, serverOpts []RpcServerOption) error
+	// NewServer instructs WSPR to create a server and start listening for calls on
+	// behalf of a JavaScript server.
+	NewServer(ctx *context.T, call rpc.ServerCall, name string, serverId uint32, serverOpts []RpcServerOption) error
 	// Stop instructs WSPR to stop listening for calls for the
 	// given javascript server.
 	Stop(ctx *context.T, call rpc.ServerCall, serverId uint32) error
@@ -229,8 +229,8 @@
 	gs   *rpc.GlobState
 }
 
-func (s implControllerServerStub) Serve(ctx *context.T, call rpc.ServerCall, i0 string, i1 uint32, i2 []RpcServerOption) error {
-	return s.impl.Serve(ctx, call, i0, i1, i2)
+func (s implControllerServerStub) NewServer(ctx *context.T, call rpc.ServerCall, i0 string, i1 uint32, i2 []RpcServerOption) error {
+	return s.impl.NewServer(ctx, call, i0, i1, i2)
 }
 
 func (s implControllerServerStub) Stop(ctx *context.T, call rpc.ServerCall, i0 uint32) error {
@@ -310,8 +310,8 @@
 	PkgPath: "v.io/x/ref/services/wspr/internal/app",
 	Methods: []rpc.MethodDesc{
 		{
-			Name: "Serve",
-			Doc:  "// Serve instructs WSPR to start listening for calls on behalf\n// of a javascript server.",
+			Name: "NewServer",
+			Doc:  "// NewServer instructs WSPR to create a server and start listening for calls on\n// behalf of a JavaScript server.",
 			InArgs: []rpc.ArgDesc{
 				{"name", ``},       // string
 				{"serverId", ``},   // uint32
diff --git a/services/wspr/internal/rpc/server/server.go b/services/wspr/internal/rpc/server/server.go
index 08661c0..5e693f3 100644
--- a/services/wspr/internal/rpc/server/server.go
+++ b/services/wspr/internal/rpc/server/server.go
@@ -68,19 +68,12 @@
 	// This should be locked before outstandingRequestLock.
 	serverStateLock sync.Mutex
 
-	// The rpc.ListenSpec to use with server.Listen
-	listenSpec *rpc.ListenSpec
+	// The server that handles the rpc layer.
+	server rpc.Server
 
-	// The server that handles the rpc layer.  Listen on this server is
-	// lazily started.
-	server rpc.DeprecatedServer
-
-	// The saved dispatcher to reuse when serve is called multiple times.
+	// The saved dispatcher.
 	dispatcher *dispatcher
 
-	// Whether the server is listening.
-	isListening bool
-
 	// The server id.
 	id     uint32
 	helper ServerHelper
@@ -100,11 +93,10 @@
 
 type serverContextKey struct{}
 
-func NewServer(id uint32, listenSpec *rpc.ListenSpec, helper ServerHelper, opts ...rpc.ServerOpt) (*Server, error) {
+func NewServer(id uint32, name string, listenSpec *rpc.ListenSpec, helper ServerHelper, opts ...rpc.ServerOpt) (*Server, error) {
 	server := &Server{
-		id:                            id,
-		helper:                        helper,
-		listenSpec:                    listenSpec,
+		id:     id,
+		helper: helper,
 		outstandingServerRequests:     make(map[int32]chan *lib.ServerRpcReply),
 		outstandingAuthRequests:       make(map[int32]chan error),
 		outstandingValidationRequests: make(map[int32]chan []error),
@@ -112,10 +104,20 @@
 	var err error
 	ctx := helper.Context()
 	ctx = context.WithValue(ctx, serverContextKey{}, server)
-	if server.server, err = v23.NewServer(ctx, opts...); err != nil {
+
+	server.serverStateLock.Lock()
+	defer server.serverStateLock.Unlock()
+
+	server.dispatcher = newDispatcher(server.id, server, server, server, server.helper)
+	ctx = v23.WithListenSpec(ctx, *listenSpec)
+
+	if ctx, server.server, err = v23.WithNewDispatchingServer(ctx, name, server.dispatcher, opts...); err != nil {
 		return nil, err
 	}
 	server.ctx = ctx
+	server.statusClose = make(chan struct{}, 1)
+	go server.readStatus()
+
 	return server, nil
 }
 
@@ -602,29 +604,6 @@
 	}
 }
 
-func (s *Server) Serve(name string) error {
-	s.serverStateLock.Lock()
-	defer s.serverStateLock.Unlock()
-
-	if s.dispatcher == nil {
-		s.dispatcher = newDispatcher(s.id, s, s, s, s.helper)
-	}
-
-	if !s.isListening {
-		_, err := s.server.Listen(*s.listenSpec)
-		if err != nil {
-			return err
-		}
-		s.isListening = true
-	}
-	if err := s.server.ServeDispatcher(name, s.dispatcher); err != nil {
-		return err
-	}
-	s.statusClose = make(chan struct{}, 1)
-	go s.readStatus()
-	return nil
-}
-
 func (s *Server) popServerRequest(id int32) chan *lib.ServerRpcReply {
 	s.outstandingRequestLock.Lock()
 	defer s.outstandingRequestLock.Unlock()