예제 #1
0
func GoRpcServerOpts(env jutil.Env, obj jutil.Object) ([]rpc.ServerOpt, error) {
	var opts []rpc.ServerOpt

	if opt, err := jutil.JBoolField(env, obj, "servesMountTable"); err != nil {
		return nil, err
	} else {
		opts = append(opts, options.ServesMountTable(opt))
	}

	if opt, err := getDuration(env, obj, "lameDuckTimeout"); err != nil {
		return nil, err
	} else if opt != nil {
		opts = append(opts, options.LameDuckTimeout(*opt))
	}

	if opt, err := jutil.JBoolField(env, obj, "isLeaf"); err != nil {
		return nil, err
	} else {
		opts = append(opts, options.IsLeaf(opt))
	}

	if opt, err := getDuration(env, obj, "channelTimeout"); err != nil {
		return nil, err
	} else if opt != nil {
		opts = append(opts, options.ChannelTimeout(*opt))
	}

	return opts, nil
}
예제 #2
0
func GoRpcOpts(env jutil.Env, obj jutil.Object) ([]rpc.CallOpt, error) {
	var opts []rpc.CallOpt

	if opt, err := getAuthorizer(env, obj, "nameResolutionAuthorizer"); err != nil {
		return nil, err
	} else if opt != nil {
		opts = append(opts, options.NameResolutionAuthorizer{opt})
	}

	if opt, err := getAuthorizer(env, obj, "serverAuthorizer"); err != nil {
		return nil, err
	} else if opt != nil {
		opts = append(opts, options.ServerAuthorizer{opt})
	}

	if opt, err := getPreresolved(env, obj); err != nil {
		return nil, err
	} else if opt != nil {
		opts = append(opts, options.Preresolved{opt})
	}

	if opt, err := jutil.JBoolField(env, obj, "noRetry"); err != nil {
		return nil, err
	} else if opt {
		opts = append(opts, options.NoRetry{})
	}

	if opt, err := getDuration(env, obj, "connectionTimeout"); err != nil {
		return nil, err
	} else if opt != nil {
		opts = append(opts, options.ConnectionTimeout(*opt))
	}

	if opt, err := getDuration(env, obj, "channelTimeout"); err != nil {
		return nil, err
	} else if opt != nil {
		opts = append(opts, options.ChannelTimeout(*opt))
	}

	return opts, nil
}
예제 #3
0
파일: jni.go 프로젝트: vanadium/go.jni
//export Java_io_v_impl_google_services_syncbase_SyncbaseServer_nativeWithNewServer
func Java_io_v_impl_google_services_syncbase_SyncbaseServer_nativeWithNewServer(jenv *C.JNIEnv, jSyncbaseServerClass C.jclass, jContext C.jobject, jSyncbaseServerParams C.jobject) C.jobject {
	env := jutil.Env(uintptr(unsafe.Pointer(jenv)))
	jCtx := jutil.Object(uintptr(unsafe.Pointer(jContext)))
	jParams := jutil.Object(uintptr(unsafe.Pointer(jSyncbaseServerParams)))

	// Read and translate all of the server params.
	jPerms, err := jutil.CallObjectMethod(env, jParams, "getPermissions", nil, permissionsSign)
	if err != nil {
		jutil.JThrowV(env, err)
		return nil
	}
	perms, err := jaccess.GoPermissions(env, jPerms)
	if err != nil {
		jutil.JThrowV(env, err)
		return nil
	}
	name, err := jutil.CallStringMethod(env, jParams, "getName", nil)
	if err != nil {
		jutil.JThrowV(env, err)
		return nil
	}
	rootDir, err := jutil.CallStringMethod(env, jParams, "getStorageRootDir", nil)
	if err != nil {
		jutil.JThrowV(env, err)
		return nil
	}
	if rootDir == "" {
		rootDir = filepath.Join(os.TempDir(), "syncbaseserver")
		if err := os.Mkdir(rootDir, 0755); err != nil && !os.IsExist(err) {
			jutil.JThrowV(env, err)
			return nil
		}
	}
	jEngine, err := jutil.CallObjectMethod(env, jParams, "getStorageEngine", nil, storageEngineSign)
	if err != nil {
		jutil.JThrowV(env, err)
		return nil
	}
	engine, err := GoStorageEngine(env, jEngine)
	if err != nil {
		jutil.JThrowV(env, err)
		return nil
	}
	ctx, cancel, err := jcontext.GoContext(env, jCtx)
	if err != nil {
		jutil.JThrowV(env, err)
		return nil
	}

	// Create the rpc server before the service so that connections are shared between
	// clients in the service and the rpc server. (i.e. connections are shared if the
	// context returned from WithNewDispatchingServer is used for client calls).
	d := dispatcher.NewDispatcherWrapper()
	ctx, s, err := v23.WithNewDispatchingServer(ctx, name, d, options.ChannelTimeout(vsync.NeighborConnectionTimeout))
	if err != nil {
		cancel()
		jutil.JThrowV(env, err)
		return nil
	}

	service, err := server.NewService(ctx, server.ServiceOptions{
		Perms:   perms,
		RootDir: rootDir,
		Engine:  engine,
	})
	if err != nil {
		cancel()
		jutil.JThrowV(env, err)
		return nil
	}
	// Set the dispatcher in the dispatcher wrapper for the server to start responding
	// to incoming rpcs.
	d.SetDispatcher(server.NewDispatcher(service))

	if err := service.AddNames(ctx, s); err != nil {
		cancel()
		jutil.JThrowV(env, err)
		return nil
	}
	jNewCtx, err := jcontext.JavaContext(env, ctx, cancel)
	if err != nil {
		jutil.JThrowV(env, err)
		return nil
	}
	jServer, err := jrpc.JavaServer(env, s)
	if err != nil {
		jutil.JThrowV(env, err)
		return nil
	}
	// Attach a server to the new context.
	jServerAttCtx, err := jutil.CallStaticObjectMethod(env, jVRuntimeImplClass, "withServer", []jutil.Sign{contextSign, serverSign}, contextSign, jNewCtx, jServer)
	if err != nil {
		jutil.JThrowV(env, err)
		return nil
	}
	return C.jobject(unsafe.Pointer(jServerAttCtx))
}
예제 #4
0
파일: funcs.go 프로젝트: vanadium/go.jni
func btAndDiscoveryFunc(ctx *context.T, w io.Writer) error {
	bothf := func(ctx *context.T, w io.Writer, format string, args ...interface{}) {
		fmt.Fprintf(w, format, args...)
		ctx.Infof(format, args...)
	}
	defer bothf(ctx, w, "finishing!")

	dis, err := v23.NewDiscovery(ctx)
	if err != nil {
		bothf(ctx, w, "Can't create discovery %v", err)
		return err
	}

	ctx = v23.WithListenSpec(ctx, rpc.ListenSpec{Addrs: rpc.ListenAddrs{{Protocol: "bt", Address: "/0"}}})
	_, server, err := v23.WithNewServer(ctx, "", &echoServer{}, security.AllowEveryone())
	if err != nil {
		bothf(ctx, w, "Can't create server %v", err)
		return err
	}
	ctx.Infof("Server listening on %v", server.Status().Endpoints)
	ctx.Infof("Server listen errors: %v", server.Status().ListenErrors)

	interfaces := []string{
		"v.io/x/jni/impl/google/services/vango/Echo",
		"v.io/x/jni/impl/google/services/vango/Echo2",
		"v.io/x/jni/impl/google/services/vango/Echo3",
		"v.io/x/jni/impl/google/services/vango/Echo4",
	}
	type adstate struct {
		ad   *discovery.Advertisement
		stop func()
	}
	ads := []adstate{}
	for _, name := range interfaces {
		ad := &discovery.Advertisement{
			InterfaceName: name,
			Attributes: discovery.Attributes{
				"one":   "A value of some kind",
				"two":   "Yet another value",
				"three": "More and more",
				"four":  "This is insane",
			},
		}
		nctx, ncancel := context.WithCancel(ctx)
		ch, err := libdiscovery.AdvertiseServer(nctx, dis, server, "", ad, nil)
		if err != nil {
			bothf(nctx, w, "Can't advertise server %v", err)
			return err
		}

		stop := func() {
			ncancel()
			<-ch
		}
		ads = append(ads, adstate{ad, stop})
	}

	type updateState struct {
		ch   <-chan discovery.Update
		stop func()
	}
	var updates []updateState
	for _, name := range interfaces {
		nctx, ncancel := context.WithCancel(ctx)
		u, err := dis.Scan(nctx, `v.InterfaceName="`+name+`"`)
		if err != nil {
			bothf(nctx, w, "Can't scan %v", err)
			return err
		}
		stop := func() {
			ncancel()
		}
		updates = append(updates, updateState{u, stop})
	}

	for _, u := range updates[1:] {
		go func(up updateState) {
			for _ = range up.ch {
			}
		}(u)
	}

	makeopt := func(ad discovery.Advertisement) options.Preresolved {
		me := &naming.MountEntry{
			IsLeaf: true,
		}
		for _, a := range ad.Addresses {
			addr, _ := naming.SplitAddressName(a)
			me.Servers = append(me.Servers, naming.MountedServer{
				Server: addr,
			})
		}
		return options.Preresolved{Resolution: me}
	}

	alive := map[discovery.AdId]options.Preresolved{}
	ticker := time.NewTicker(time.Second)
	for {
		select {
		case <-ticker.C:
			if len(alive) == 0 {
				bothf(ctx, w, "No live connections to dial.")
			}
			for _, opt := range alive {
				dialtime := options.ConnectionTimeout(5 * time.Second)
				channeltime := options.ChannelTimeout(2 * time.Second)
				data := make([]byte, 1024)
				summary, err := runTimedCall(ctx, "A timed call.", string(data), opt, dialtime, channeltime)
				if err != nil {
					bothf(ctx, w, "failed call %s, %v, %v", summary, err, opt.Resolution.Servers)
				} else {
					bothf(ctx, w, "succeeded call: %s, %v", summary, opt.Resolution.Servers)
				}
			}

		case u := <-updates[0].ch:
			if u.IsLost() {
				bothf(ctx, w, "lost %v", u.Addresses())
				delete(alive, u.Id())
			} else {
				bothf(ctx, w, "found %v", u.Addresses())
				alive[u.Id()] = makeopt(u.Advertisement())
			}
		}
	}
}
예제 #5
0
파일: main.go 프로젝트: jeffallen/mqtt
func main() {
	ctx, shutdown := v23.Init()
	defer shutdown()

	// Run server
	if *to == "" {
		// We are not the caller, so make the RPC available for the
		// caller to call in on.
		bsrv := ifc.BridgeServer(makeImpl())
		_, server, err := v23.WithNewServer(ctx, *serviceName, bsrv,
			security.DefaultAuthorizer())

		if err != nil {
			ctx.Error("Error serving service: ", err)
			return
		}

		endpoint := server.Status().Endpoints[0]
		fmt.Printf("Listening at: %v\n", endpoint)

		// Wait forever.
		<-signals.ShutdownOnSignals(ctx)
	} else if *to != "" && *from != "" {
		// pipe mode
		ifct := ifcTopics(*topics)
		tmout := options.ChannelTimeout(*timeout)

		leftc := ifc.BridgeClient(*to)
		rightc := ifc.BridgeClient(*from)

		leftcc, err := leftc.Link(ctx, ifct, tmout)
		if err != nil {
			ctx.Error(err)
			return
		}

		rightcc, err := rightc.Link(ctx, ifct, tmout)
		if err != nil {
			ctx.Error(err)
			return
		}

		errCh := make(chan error, 2)

		wg := &sync.WaitGroup{}
		wg.Add(2)
		go linkToLink(leftcc.RecvStream(), rightcc.SendStream(), errCh, wg)
		go linkToLink(rightcc.RecvStream(), leftcc.SendStream(), errCh, wg)
		wg.Wait()
		select {
		case err := <-errCh:
			log.Print("pipe error: ", err)
		default:
			// don't block on channel read
		}
	} else {
		cc, mu, err := mqttConnect()
		if err != nil {
			ctx.Error("mqtt connect: ", err)
			return
		}

		bc := ifc.BridgeClient(*to)

		ifct := ifcTopics(*topics)
		bcc, err := bc.Link(ctx, ifct, options.ChannelTimeout(*timeout))
		if err != nil {
			ctx.Error(err)
			return
		}

		done := make(chan error, 2)
		go func() {
			done <- transmitter(ifct, bcc.SendStream(), cc, mu)
			println("send done")
		}()
		go func() {
			done <- receiver(bcc.RecvStream(), cc, mu)
			println("recv done")
		}()
		err = <-done
		log.Print("Stopped with error ", err)

		// Stop sender by closing cc.Incoming
		cc.Disconnect()
	}
}