blob: 3695e7220aba136d8a262207b387845b4277f7db [file] [log] [blame]
// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build mojo
package main
import (
"flag"
"log"
"mojo/public/go/application"
"mojo/public/go/bindings"
"mojo/public/go/system"
"mojom/syncbase"
"v.io/v23"
"v.io/v23/context"
"v.io/v23/rpc"
"v.io/x/ref/runtime/factories/roaming"
bridge "v.io/x/ref/services/syncbase/bridge_mojo"
"v.io/x/ref/services/syncbase/syncbaselib"
)
//#include "mojo/public/c/system/handle.h"
import "C"
type delegate struct {
ctx *context.T
disp rpc.Dispatcher
shutdown func()
srv rpc.Server
cleanup func()
stubs []*bindings.Stub
}
func (d *delegate) Initialize(actx application.Context) {
opts := syncbaselib.Opts{}
opts.InitFlags(flag.CommandLine)
roaming.SetArgs(actx)
d.ctx, d.shutdown = v23.Init() // calls flag.Parse
if err := bridge.SeekAndSetBlessings(d.ctx, actx); err != nil {
panic(err)
}
d.srv, d.disp, d.cleanup = syncbaselib.Serve(d.ctx, opts)
}
const numGoroutines = 100
func (d *delegate) Create(req syncbase.Syncbase_Request) {
impl := bridge.NewMojoImpl(d.ctx, d.srv, d.disp)
stub := syncbase.NewSyncbaseStub(req, impl, bindings.GetAsyncWaiter())
d.stubs = append(d.stubs, stub)
// Spawn a bunch of goroutines to handle incoming requests concurrently.
// Note: It would be better to spawn a goroutine per request as requests
// arrive, but Mojo's Go interfaces make this difficult at best. Discussions
// with Mojo team ongoing (as of Nov 25, 2015).
for i := 0; i < numGoroutines; i++ {
go func(i int) {
for {
if err := stub.ServeRequest(); err != nil {
connErr, ok := err.(*bindings.ConnectionError)
if !ok || !connErr.Closed() {
log.Println(i, err)
}
break
}
}
}(i)
}
}
func (d *delegate) AcceptConnection(conn *application.Connection) {
conn.ProvideServices(&syncbase.Syncbase_ServiceFactory{d})
}
func (d *delegate) Quit() {
for _, stub := range d.stubs {
stub.Close()
}
d.cleanup()
d.shutdown()
}
//export MojoMain
func MojoMain(handle C.MojoHandle) C.MojoResult {
application.Run(&delegate{}, system.MojoHandle(handle))
return C.MOJO_RESULT_OK
}
// NOTE(nlacasse): Mojo runs Go code by calling MojoMain(). The main() method
// below is still needed because the Go tool won't build without it.
func main() {}