Merge "javascript/api: Updated javascript api to match the new serve api in go."
diff --git a/examples/pipetobrowser/browser/services/pipe-to-browser-server.js b/examples/pipetobrowser/browser/services/pipe-to-browser-server.js
index 5f40da4..21dc83e 100644
--- a/examples/pipetobrowser/browser/services/pipe-to-browser-server.js
+++ b/examples/pipetobrowser/browser/services/pipe-to-browser-server.js
@@ -91,17 +91,15 @@
state.publishing = true;
- return server.register('pipe', p2b).then(() => { //TODO(aghassemi) publish-issue add pipe for now since we can't register under empty name
- return server.publish(config.publishNamePrefix + '/' + name).then((endpoint) => { //TODO(aghassemi) publish-issue
- log.debug('published with endpoint:', endpoint);
+ return server.serve(config.publishNamePrefix + '/' + name + '/pipe', p2b).then((endpoint) => { //TODO(aghassemi) publish-issue
+ log.debug('published with endpoint:', endpoint);
- state.published = true;
- state.publishing = false;
- state.fullServiceName = config.publishNamePrefix + '/' + name + '/pipe'; //TODO(aghassemi) publish-issue
- state.date = new Date();
+ state.published = true;
+ state.publishing = false;
+ state.fullServiceName = config.publishNamePrefix + '/' + name + '/pipe'; //TODO(aghassemi) publish-issue
+ state.date = new Date();
- return endpoint;
- });
+ return endpoint;
}).catch((err) => { state.reset(); throw err; });
}
diff --git a/services/wspr/wsprd/lib/server.go b/services/wspr/wsprd/lib/server.go
index 901287e..8b95ea2 100644
--- a/services/wspr/wsprd/lib/server.go
+++ b/services/wspr/wsprd/lib/server.go
@@ -6,7 +6,6 @@
"bytes"
"encoding/json"
"fmt"
- "strings"
"sync"
"veyron2"
@@ -22,6 +21,20 @@
writer clientWriter
}
+// A request from the proxy to javascript to handle an RPC
+type serverRPCRequest struct {
+ ServerId uint64
+ Method string
+ Args []interface{}
+ Context serverRPCRequestContext
+}
+
+// call context for a serverRPCRequest
+type serverRPCRequestContext struct {
+ Suffix string
+ Name string
+}
+
type serverHelper interface {
createNewFlow(server *server, sender sender) *flow
@@ -37,8 +50,10 @@
// The server that handles the ipc layer. Listen on this server is
// lazily started.
- server ipc.Server
- dispatcher exactMatchDispatcher
+ server ipc.Server
+
+ // The saved dispatcher to reuse when serve is called multiple times.
+ dispatcher ipc.Dispatcher
// The endpoint of the server. This is empty until the server has been
// started and listen has been called on it.
@@ -61,7 +76,6 @@
helper: helper,
veyronProxy: veyronProxy,
outstandingServerRequests: make(map[int64]chan *serverRPCReply),
- dispatcher: exactMatchDispatcher{dispatchers: make(map[string]ipc.Dispatcher)},
}
var err error
if server.server, err = helper.rt().NewServer(); err != nil {
@@ -74,7 +88,7 @@
// communicate the result back via a channel to the caller
type remoteInvokeFunc func(methodName string, args []interface{}, call ipc.ServerCall) <-chan *serverRPCReply
-func (s *server) createRemoteInvokerFunc(serviceName string) remoteInvokeFunc {
+func (s *server) createRemoteInvokerFunc() remoteInvokeFunc {
return func(methodName string, args []interface{}, call ipc.ServerCall) <-chan *serverRPCReply {
flow := s.helper.createNewFlow(s, senderWrapper{stream: call})
replyChan := make(chan *serverRPCReply, 1)
@@ -87,11 +101,10 @@
}
// Send a invocation request to JavaScript
message := serverRPCRequest{
- ServerId: s.id,
- ServiceName: serviceName,
- Method: lowercaseFirstCharacter(methodName),
- Args: args,
- Context: context,
+ ServerId: s.id,
+ Method: lowercaseFirstCharacter(methodName),
+ Args: args,
+ Context: context,
}
data := response{Type: responseServerRequest, Message: message}
@@ -114,8 +127,8 @@
}
s.helper.getLogger().VI(3).Infof("request received to call method %q on "+
- "JavaScript server %q with args %v, MessageId %d was assigned.",
- methodName, serviceName, args, flow.id)
+ "JavaScript server with args %v, MessageId %d was assigned.",
+ methodName, args, flow.id)
go proxyStream(call, flow.writer, s.helper.getLogger())
return replyChan
@@ -146,62 +159,28 @@
}
}
-type exactMatchDispatcher struct {
- sync.Mutex
- dispatchers map[string]ipc.Dispatcher
-}
+func (s *server) serve(name string, sig JSONServiceSignature) (string, error) {
+ s.Lock()
+ defer s.Unlock()
-func (em *exactMatchDispatcher) Lookup(suffix string) (ipc.Invoker, security.Authorizer, error) {
- parts := strings.Split(suffix, "/")
- if len(parts) == 0 || len(parts[0]) == 0 {
- return nil, nil, fmt.Errorf("can't extract first path component from %q", suffix)
- }
- name := parts[0]
- em.Lock()
- defer em.Unlock()
- if disp := em.dispatchers[name]; disp == nil {
- return nil, nil, fmt.Errorf("no dispatcher registered for %q, from %q", name, suffix)
- } else {
- suffix = strings.TrimLeft(suffix, "/")
- suffix = strings.TrimPrefix(suffix, name)
- suffix = strings.TrimLeft(suffix, "/")
- return disp.Lookup(suffix)
- }
-}
-
-// register associates a dispatcher with name, where name cannot contain
-// any /s. Incoming invocations of the form <name>/... will be passed
-// on to the dispatcher with <name>/... as the parameter to its lookup
-// method.
-func (s *server) register(name string, sig JSONServiceSignature) error {
serviceSig, err := sig.ServiceSignature()
if err != nil {
- return err
+ return "", err
}
- if strings.Contains(name, "/") {
- return fmt.Errorf("%q must not contain /", name)
- }
-
- remoteInvokeFunc := s.createRemoteInvokerFunc(name)
+ remoteInvokeFunc := s.createRemoteInvokerFunc()
invoker, err := newInvoker(serviceSig, remoteInvokeFunc)
if err != nil {
- return err
+ return "", err
}
- dispatcher := newDispatcher(invoker, security.NewACLAuthorizer(
- security.ACL{security.AllPrincipals: security.AllLabels},
- ))
- s.dispatcher.Lock()
- s.dispatcher.dispatchers[name] = dispatcher
- s.dispatcher.Unlock()
- return nil
-}
+ if s.dispatcher == nil {
+ s.dispatcher = newDispatcher(invoker, security.NewACLAuthorizer(
+ security.ACL{security.AllPrincipals: security.AllLabels},
+ ))
+ }
-func (s *server) publish(name string) (string, error) {
- s.Lock()
- defer s.Unlock()
if s.endpoint == "" {
endpoint, err := s.server.Listen("veyron", s.veyronProxy)
@@ -210,7 +189,7 @@
}
s.endpoint = endpoint.String()
}
- if err := s.server.Serve(name, &s.dispatcher); err != nil {
+ if err := s.server.Serve(name, s.dispatcher); err != nil {
return "", err
}
s.helper.getLogger().VI(1).Infof("endpoint is %s", s.endpoint)
diff --git a/services/wspr/wsprd/lib/wspr.go b/services/wspr/wsprd/lib/wspr.go
index 0147432..b48a310 100644
--- a/services/wspr/wsprd/lib/wspr.go
+++ b/services/wspr/wsprd/lib/wspr.go
@@ -87,8 +87,8 @@
// Making a veyron client request, streaming or otherwise
websocketVeyronRequest websocketMessageType = 0
- // Publishing this websocket under an object name
- websocketPublishServer = 1
+ // Serving this websocket under an object name
+ websocketServe = 1
// A response from a service in javascript to a request
// from the proxy.
@@ -112,7 +112,7 @@
// This contains the json encoded payload.
Data string
- // Whether it is an rpc request or a publish request.
+ // Whether it is an rpc request or a serve request.
Type websocketMessageType
}
@@ -135,32 +135,11 @@
IsStreaming bool
}
-// A request javascript to publish on a particular name
-type publishRequest struct {
+// A request javascript to serve undern a particular name
+type serveRequest struct {
Name string
ServerId uint64
- Services map[string]JSONServiceSignature
-}
-
-// A request from javascript to register a particular prefix
-type registerRequest struct {
- Prefix string
- // TODO(bjornick): Do we care about the methods?
-}
-
-// A request from the proxy to javascript to handle an RPC
-type serverRPCRequest struct {
- ServerId uint64
- ServiceName string
- Method string
- Args []interface{}
- Context serverRPCRequestContext
-}
-
-// call context for a serverRPCRequest
-type serverRPCRequestContext struct {
- Suffix string
- Name string
+ Service JSONServiceSignature
}
// The response from the javascript server to the proxy.
@@ -355,7 +334,7 @@
// A manager that handles fetching and caching signature of remote services
signatureManager *signatureManager
- // We maintain multiple Veyron server per websocket pipe for publishing JavaScript
+ // We maintain multiple Veyron server per websocket pipe for serving JavaScript
// services.
servers map[uint64]*server
@@ -613,8 +592,8 @@
wsp.sendOnStream(msg.Id, msg.Data, ww)
case websocketStreamClose:
wsp.closeStream(msg.Id)
- case websocketPublishServer:
- go wsp.handlePublishRequest(msg.Data, ww)
+ case websocketServe:
+ go wsp.handleServeRequest(msg.Data, ww)
case websocketStopServer:
go wsp.handleStopRequest(msg.Data, ww)
case websocketServerResponse:
@@ -655,25 +634,18 @@
server.Stop()
}
-func (wsp *websocketPipe) publish(publishRequest publishRequest, w clientWriter) {
+func (wsp *websocketPipe) serve(serveRequest serveRequest, w clientWriter) {
// Create a server for the websocket pipe, if it does not exist already
- server, err := wsp.maybeCreateServer(publishRequest.ServerId)
+ server, err := wsp.maybeCreateServer(serveRequest.ServerId)
if err != nil {
w.sendError(verror.Internalf("error creating server: %v", err))
}
- wsp.ctx.logger.VI(2).Infof("publishing under name: %q", publishRequest.Name)
+ wsp.ctx.logger.VI(2).Infof("serving under name: %q", serveRequest.Name)
- // Register each service under the server
- for serviceName, jsonIDLSig := range publishRequest.Services {
- if err := server.register(serviceName, jsonIDLSig); err != nil {
- w.sendError(verror.Internalf("error registering service: %v", err))
- }
- }
-
- endpoint, err := server.publish(publishRequest.Name)
+ endpoint, err := server.serve(serveRequest.Name, serveRequest.Service)
if err != nil {
- w.sendError(verror.Internalf("error publishing service: %v", err))
+ w.sendError(verror.Internalf("error serving service: %v", err))
return
}
// Send the endpoint back
@@ -689,17 +661,17 @@
}
}
-// handlePublishRequest takes a request to publish a server, creates
+// handleServeRequest takes a request to serve a server, creates
// a server, registers the provided services and sends the endpoint back.
-func (wsp *websocketPipe) handlePublishRequest(data string, w *websocketWriter) {
- // Decode the publish request which includes IDL, registered services and name
- var publishRequest publishRequest
+func (wsp *websocketPipe) handleServeRequest(data string, w *websocketWriter) {
+ // Decode the serve request which includes IDL, registered services and name
+ var serveRequest serveRequest
decoder := json.NewDecoder(bytes.NewBufferString(data))
- if err := decoder.Decode(&publishRequest); err != nil {
+ if err := decoder.Decode(&serveRequest); err != nil {
w.sendError(verror.Internalf("can't unmarshal JSONMessage: %v", err))
return
}
- wsp.publish(publishRequest, w)
+ wsp.serve(serveRequest, w)
}
// handleStopRequest takes a request to stop a server.
diff --git a/services/wspr/wsprd/lib/wspr_test.go b/services/wspr/wsprd/lib/wspr_test.go
index 15d4ac3..f8d6b9f 100644
--- a/services/wspr/wsprd/lib/wspr_test.go
+++ b/services/wspr/wsprd/lib/wspr_test.go
@@ -364,7 +364,7 @@
proxyServer *proxy.Proxy
}
-func publishServer() (*runningTest, error) {
+func serveServer() (*runningTest, error) {
mounttableServer, endpoint, err := startMountTableServer()
if err != nil {
@@ -389,11 +389,9 @@
return &writer
}
wsp.setup()
- wsp.publish(publishRequest{
- Name: "adder",
- Services: map[string]JSONServiceSignature{
- "adder": adderServiceSignature,
- },
+ wsp.serve(serveRequest{
+ Name: "adder",
+ Service: adderServiceSignature,
}, &writer)
return &runningTest{
@@ -401,14 +399,14 @@
}, nil
}
-func TestJavascriptPublishServer(t *testing.T) {
- rt, err := publishServer()
+func TestJavascriptServeServer(t *testing.T) {
+ rt, err := serveServer()
defer rt.mounttableServer.Stop()
defer rt.proxyServer.Shutdown()
defer rt.wsp.cleanup()
if err != nil {
- t.Errorf("could not publish server %v", err)
+ t.Errorf("could not serve server %v", err)
}
if len(rt.writer.stream) != 1 {
@@ -419,7 +417,7 @@
resp := rt.writer.stream[0]
if resp.Type != responseFinal {
- t.Errorf("unknown stream message Got: %v, expected: publish response", resp)
+ t.Errorf("unknown stream message Got: %v, expected: serve response", resp)
return
}
@@ -428,17 +426,17 @@
return
}
}
- t.Errorf("invalid endpdoint returned from publish: %v", resp.Message)
+ t.Errorf("invalid endpdoint returned from serve: %v", resp.Message)
}
func TestJavascriptStopServer(t *testing.T) {
- rt, err := publishServer()
+ rt, err := serveServer()
defer rt.mounttableServer.Stop()
defer rt.proxyServer.Shutdown()
defer rt.wsp.cleanup()
if err != nil {
- t.Errorf("could not publish server %v", err)
+ t.Errorf("could not serve server %v", err)
return
}
@@ -489,13 +487,13 @@
}
func runJsServerTestCase(t *testing.T, test jsServerTestCase) {
- rt, err := publishServer()
+ rt, err := serveServer()
defer rt.mounttableServer.Stop()
defer rt.proxyServer.Shutdown()
defer rt.wsp.cleanup()
if err != nil {
- t.Errorf("could not publish server %v", err)
+ t.Errorf("could not serve server %v", err)
}
if len(rt.writer.stream) != 1 {
@@ -506,17 +504,17 @@
resp := rt.writer.stream[0]
if resp.Type != responseFinal {
- t.Errorf("unknown stream message Got: %v, expected: publish response", resp)
+ t.Errorf("unknown stream message Got: %v, expected: serve response", resp)
return
}
msg, ok := resp.Message.(string)
if !ok {
- t.Errorf("invalid endpdoint returned from publish: %v", resp.Message)
+ t.Errorf("invalid endpdoint returned from serve: %v", resp.Message)
}
if _, err := r.NewEndpoint(msg); err != nil {
- t.Errorf("invalid endpdoint returned from publish: %v", resp.Message)
+ t.Errorf("invalid endpdoint returned from serve: %v", resp.Message)
}
rt.writer.stream = nil
@@ -528,7 +526,7 @@
t.Errorf("unable to create client: %v", err)
}
- call, err := client.StartCall(rt.wspr.rt.NewContext(), "/"+msg+"//adder", test.method, test.inArgs)
+ call, err := client.StartCall(rt.wspr.rt.NewContext(), "/"+msg+"/adder", test.method, test.inArgs)
if err != nil {
t.Errorf("failed to start call: %v", err)
}
@@ -537,10 +535,9 @@
response{
Type: responseServerRequest,
Message: map[string]interface{}{
- "serverId": 0.0,
- "serviceName": "adder",
- "method": lowercaseFirstCharacter(test.method),
- "args": test.inArgs,
+ "serverId": 0.0,
+ "method": lowercaseFirstCharacter(test.method),
+ "args": test.inArgs,
"context": map[string]interface{}{
"name": "adder",
"suffix": "adder",