blob: 1502dae26a3a0ce3c4317833aa2c1154f705c8a8 [file] [log] [blame]
package modules
import (
"fmt"
"os"
"strings"
"time"
"veyron/lib/testutil/blackbox"
"veyron2/ipc"
"veyron2/naming"
"veyron2/rt"
)
func init() {
blackbox.CommandTable["clock"] = clockChild
blackbox.CommandTable["echo"] = echoChild
}
func clockChild(args []string) {
serve("clock", ipc.SoloDispatcher(NewServerClock(&clockServer{}), nil), args)
}
func echoChild(args []string) {
serve("echo", ipc.SoloDispatcher(NewServerEcho(&echoServer{}), nil), args)
}
func serve(msg string, dispatcher ipc.Dispatcher, args []string) {
rt.Init()
if len(args) != 1 {
bbExitWithError("wrong #args")
}
mp := args[0]
fmt.Println("ready")
server, err := rt.R().NewServer()
if err != nil {
bbExitWithError(fmt.Sprintf("%s failed: %v", msg, err))
}
ep, err := server.Listen("tcp", "127.0.0.1:0")
if err != nil {
bbExitWithError(fmt.Sprintf("%s failed: %v", msg, err))
}
fmt.Printf("NAME=%s\n", naming.MakeTerminal(naming.JoinAddressName(ep.String(), "")))
if err := server.Serve(mp, dispatcher); err != nil {
bbExitWithError(fmt.Sprintf("%s failed: %v", msg, err))
}
fmt.Printf("ADDR=%s\n", ep)
fmt.Printf("PID=%d\n", os.Getpid())
fmt.Println("running")
blackbox.WaitForEOFOnStdin()
}
type clockServer struct{}
func (*clockServer) Time(_ ipc.ServerContext, m string) (string, error) {
return fmt.Sprintf("(%s) %s", time.Now(), m), nil
}
type echoServer struct{}
func (*echoServer) Echo(_ ipc.ServerContext, m string) (string, error) {
return m, nil
}
type clock struct{ client bool }
func NewClockServer() T {
return &clock{false}
}
func NewClockClient() T {
return &clock{true}
}
func (c *clock) Help() string {
if c.client {
return `<name> <message>
executes name.Time(message)`
}
return `<root> <mountpoint>
runs a clock server with root as its root mount table, mounted at <mountpoint>`
}
func (c *clock) Daemon() bool { return !c.client }
func (c *clock) Run(args []string) (Variables, []string, Handle, error) {
if !c.client {
if len(args) != 2 {
return nil, nil, nil, fmt.Errorf("wrong #args: %s", c.Help())
}
return runServer("clock", args)
}
if len(args) != 2 {
return nil, nil, nil, fmt.Errorf("wrong #args: %s", c.Help())
}
name := args[0]
message := args[1]
stub, err := BindClock(name)
if err != nil {
return nil, nil, nil, err
}
r, err := stub.Time(rt.R().NewContext(), message)
if err != nil {
return nil, nil, nil, err
}
v := make(Variables)
v.Update("TIME", strings.TrimRight(r, "\n"))
return v, []string{r}, nil, nil
}
type echo struct{ client bool }
func NewEchoServer() T {
return &echo{false}
}
func NewEchoClient() T {
return &echo{true}
}
func (e *echo) Help() string {
if e.client {
return `<name> <message>
executes name.Echo(message)`
}
return `<root> <mountpoint>
runs a clock server with root as its root mount table, mounted at <mountpoint>`
}
func (e *echo) Daemon() bool { return !e.client }
func (e *echo) Run(args []string) (Variables, []string, Handle, error) {
if !e.client {
if len(args) != 2 {
return nil, nil, nil, fmt.Errorf("wrong #args: %s", e.Help())
}
return runServer("echo", args)
}
if len(args) != 2 {
return nil, nil, nil, fmt.Errorf("wrong #args: %s", e.Help())
}
name := args[0]
message := args[1]
stub, err := BindEcho(name)
if err != nil {
return nil, nil, nil, err
}
r, err := stub.Echo(rt.R().NewContext(), message)
if err != nil {
return nil, nil, nil, err
}
v := make(Variables)
v.Update("ECHO", strings.TrimRight(r, "\n"))
return v, []string{r}, nil, nil
}
func runServer(name string, args []string) (Variables, []string, Handle, error) {
var env []string
if len(args[0]) > 0 {
env = append(env, "NAMESPACE_ROOT="+args[0])
}
c, v, r, err := bbSpawn(name, args[1:], env)
if err != nil {
return v, r, nil, err
}
h := &handle{c}
children.add(h)
return v, r, h, nil
}