diff --git a/etc/init.sh b/etc/init.sh index 4e303b96..e69de29b 100644 --- a/etc/init.sh +++ b/etc/init.sh @@ -1,4 +0,0 @@ -@debug off -source etc/mp.sh -~web -server start diff --git a/src/context/cli/cli.go b/src/context/cli/cli.go index f5263c54..35ca3bde 100644 --- a/src/context/cli/cli.go +++ b/src/context/cli/cli.go @@ -3,11 +3,10 @@ package cli // {{{ import ( // {{{ "bufio" "context" - _ "context/tcp" - _ "context/web" + // _ "context/tcp" + // _ "context/web" "fmt" "io" - "log" "os" "strconv" "strings" @@ -46,7 +45,7 @@ func (cli *CLI) push(f io.ReadCloser) { // {{{ } // }}} -func (cli *CLI) parse() bool { // {{{ +func (cli *CLI) parse(m *ctx.Message) bool { // {{{ if len(cli.ins) == 1 || cli.Conf("slient") != "yes" { cli.echo(cli.Conf("PS1")) } @@ -100,10 +99,8 @@ back: } ls := strings.Split(line, " ") - msg := &ctx.Message{Wait: make(chan bool)} - msg.Message = cli.Resource[0] - msg.Context = cli.Context - msg.Target = cli.target + msg := m.Spawn(cli.target) + msg.Wait = make(chan bool) r := rune(ls[0][0]) if !unicode.IsNumber(r) || !unicode.IsLetter(r) || r == '$' || r == '_' { @@ -157,55 +154,75 @@ func (cli *CLI) echo(str string, arg ...interface{}) { // {{{ // }}} -func (cli *CLI) Begin(m *ctx.Message) ctx.Server { // {{{ +func (cli *CLI) Begin(m *ctx.Message, arg ...string) ctx.Server { // {{{ cli.history = make([]map[string]string, 0, 100) + cli.alias = map[string]string{ + "~": "context", + "!": "history", + "@": "config", + "$": "cache", + "&": "server", + "*": "message", + } + cli.target = cli.Context - return cli.Server + + cli.Caches["nhistory"] = &ctx.Cache{Name: "历史命令数量", Value: "0", Help: "当前终端已经执行命令的数量"} + + return cli } // }}} -func (cli *CLI) Start(m *ctx.Message) bool { // {{{ +func (cli *CLI) Start(m *ctx.Message, arg ...string) bool { // {{{ cli.Capi("nterm", 1) defer cli.Capi("nterm", -1) + if cli.Messages == nil { + cli.Messages = make(chan *ctx.Message, cli.Confi("MessageQueueSize")) + } + if len(arg) > 0 { + cli.Configs["init.sh"] = &ctx.Config{Name: "启动脚本", Value: arg[0], Help: "模块启动时自动运行的脚本"} + } + if stream, ok := m.Data["io"]; ok { io := stream.(io.ReadWriteCloser) cli.out = io cli.push(io) - cli.echo("%s\n", cli.Conf("开场白")) - if f, e := os.Open(cli.Conf("init.sh")); e == nil { cli.push(f) } - defer recover() - go cli.AssertOne(m, func(c *ctx.Context, m *ctx.Message) { - for cli.parse() { + cli.echo("%s\n", cli.Conf("hello")) + + go cli.AssertOne(m, true, func(c *ctx.Context, m *ctx.Message) { + for cli.parse(m) { } }) } - for cli.Deal(func(msg *ctx.Message) bool { - arg := msg.Meta["detail"] + for cli.Deal(func(msg *ctx.Message, arg ...string) bool { if a, ok := cli.alias[arg[0]]; ok { arg[0] = a } return true - }, func(msg *ctx.Message) bool { - arg := msg.Meta["detail"] + }, func(msg *ctx.Message, arg ...string) bool { cli.history = append(cli.history, map[string]string{ "time": time.Now().Format("15:04:05"), "index": fmt.Sprintf("%d", len(cli.history)), "cli": strings.Join(arg, " "), }) + if len(arg) > 0 { + // cli.next = arg[0] + // arg[0] = "" + } + if cli.exit == true { return false } return true - }) { } @@ -214,27 +231,11 @@ func (cli *CLI) Start(m *ctx.Message) bool { // {{{ // }}} func (cli *CLI) Spawn(c *ctx.Context, m *ctx.Message, arg ...string) ctx.Server { // {{{ - c.Caches = map[string]*ctx.Cache{ - "status": &ctx.Cache{Name: "status", Value: "stop", Help: "服务状态"}, - } - c.Configs = map[string]*ctx.Config{ - "address": &ctx.Config{Name: "address", Value: arg[0], Help: "监听地址"}, - "protocol": &ctx.Config{Name: "protocol", Value: arg[1], Help: "监听协议"}, - "init.sh": &ctx.Config{Name: "init.sh", Value: "", Help: "默认启动脚本"}, - } - c.Commands = cli.Commands - c.Messages = make(chan *ctx.Message, 10) + c.Caches = map[string]*ctx.Cache{} + c.Configs = map[string]*ctx.Config{} s := new(CLI) s.Context = c - s.alias = map[string]string{ - "~": "context", - "!": "history", - "@": "config", - "$": "cache", - "&": "server", - "*": "message", - } return s } @@ -250,23 +251,14 @@ func (cli *CLI) Exit(m *ctx.Message, arg ...string) bool { // {{{ var Index = &ctx.Context{Name: "cli", Help: "管理终端", Caches: map[string]*ctx.Cache{ - "nterm": &ctx.Cache{Name: "nterm", Value: "0", Help: "终端数量"}, - "status": &ctx.Cache{Name: "status", Value: "stop", Help: "服务状态"}, - "nhistory": &ctx.Cache{Name: "nhistory", Value: "0", Help: "终端数量", Hand: func(c *ctx.Context, x *ctx.Cache, arg ...string) string { - if cli, ok := c.Server.(*CLI); ok { // {{{ - return fmt.Sprintf("%d", len(cli.history)) - } - - return x.Value - // }}} - }}, + "nterm": &ctx.Cache{Name: "终端数量", Value: "0", Help: "已经运行的终端数量"}, }, Configs: map[string]*ctx.Config{ - "开场白": &ctx.Config{Name: "开场白", Value: "\n~~~ Hello Context & Message World ~~~\n", Help: "开场白"}, - "结束语": &ctx.Config{Name: "结束语", Value: "\n~~~ Byebye Context & Message World ~~~\n", Help: "结束语"}, - "slient": &ctx.Config{Name: "slient", Value: "yes", Help: "屏蔽脚本输出"}, + "slient": &ctx.Config{Name: "屏蔽脚本输出(yes/no)", Value: "yes", Help: "屏蔽脚本输出的信息,yes:屏蔽,no:不屏蔽"}, + "hello": &ctx.Config{Name: "开场白", Value: "\n~~~ Hello Context & Message World ~~~\n", Help: "模块启动时输出的信息"}, + "byebye": &ctx.Config{Name: "结束语", Value: "\n~~~ Byebye Context & Message World ~~~\n", Help: "模块停止时输出的信息"}, - "PS1": &ctx.Config{Name: "PS1", Value: "target", Help: "命令行提示符", Hand: func(c *ctx.Context, x *ctx.Config, arg ...string) string { + "PS1": &ctx.Config{Name: "命令行提示符(target/detail)", Value: "target", Help: "命令行提示符,target:显示当前模块,detail:显示详细信息", Hand: func(c *ctx.Context, x *ctx.Config, arg ...string) string { cli, ok := c.Server.(*CLI) // {{{ if ok && cli.target != nil { // c = cli.target @@ -457,7 +449,6 @@ var Index = &ctx.Context{Name: "cli", Help: "管理终端", case 1: n, e := strconv.Atoi(arg[0]) if e == nil && 0 <= n && n < len(cli.history) { - log.Println("shy log why:", cli.history[n]["cli"]) cli.next = cli.history[n]["cli"] } default: @@ -496,7 +487,7 @@ var Index = &ctx.Context{Name: "cli", Help: "管理终端", switch len(arg) { // {{{ case 0: for k, v := range m.Target.Configs { - m.Echo("%s(%s): %s\n", k, v.Value, v.Help) + m.Echo("%s(%s): %s\n", k, v.Value, v.Name) } case 1: if v, ok := m.Target.Configs[arg[0]]; ok { @@ -523,7 +514,7 @@ var Index = &ctx.Context{Name: "cli", Help: "管理终端", switch len(arg) { // {{{ case 0: for k, v := range m.Target.Caches { - m.Echo("%s(%s): %s\n", k, v.Value, v.Help) + m.Echo("%s(%s): %s\n", k, v.Value, v.Name) } case 1: if v, ok := m.Target.Caches[arg[0]]; ok { @@ -594,14 +585,7 @@ var Index = &ctx.Context{Name: "cli", Help: "管理终端", } func init() { - cli := &CLI{alias: map[string]string{ - "~": "context", - "!": "history", - "@": "config", - "$": "cache", - "&": "server", - "*": "message", - }} + cli := &CLI{} cli.Context = Index ctx.Index.Register(Index, cli) } diff --git a/src/context/ctx.go b/src/context/ctx.go index 2e0c2b15..c85c35da 100644 --- a/src/context/ctx.go +++ b/src/context/ctx.go @@ -43,7 +43,7 @@ type Command struct { // {{{ // }}} -type Message struct { // {{{ +type Message struct { Code int Time time.Time @@ -230,10 +230,10 @@ func (m *Message) Start(arg ...string) bool { // {{{ } // }}} -// }}} + type Server interface { // {{{ - Begin(m *Message) Server - Start(m *Message) bool + Begin(m *Message, arg ...string) Server + Start(m *Message, arg ...string) bool Spawn(c *Context, m *Message, arg ...string) Server Exit(m *Message, arg ...string) bool } @@ -275,10 +275,9 @@ func (c *Context) Assert(e error) bool { // {{{ } // }}} -func (c *Context) AssertOne(m *Message, hand ...func(c *Context, m *Message)) *Context { // {{{ +func (c *Context) AssertOne(m *Message, safe bool, hand ...func(c *Context, m *Message)) *Context { // {{{ defer func() { if e := recover(); e != nil { - log.Println(c.Name, "error:", e) if c.Conf("debug") == "on" && e != io.EOF { fmt.Println(c.Name, "error:", e) debug.PrintStack() @@ -289,9 +288,12 @@ func (c *Context) AssertOne(m *Message, hand ...func(c *Context, m *Message)) *C } if len(hand) > 1 { - c.AssertOne(m, hand[1:]...) + c.AssertOne(m, safe, hand[1:]...) } else { - panic(e) + if !safe { + log.Println(c.Name, "error:", e) + panic(e) + } } } // Pulse.Wait <- true @@ -333,17 +335,23 @@ func (c *Context) Begin(m *Message) *Context { // {{{ } if c.Server != nil { - c.Server.Begin(m) + if m != nil { + c.Server.Begin(m, m.Meta["detail"]...) + } else { + c.Server.Begin(m) + } } return c } // }}} func (c *Context) Start(m *Message) bool { // {{{ - if x, ok := c.Caches["status"]; ok && x.Value != "start" && c.Server != nil { - defer recover() + if _, ok := c.Caches["status"]; !ok { + c.Caches["status"] = &Cache{Name: "status", Value: "stop", Help: "服务状态"} + } - c.AssertOne(m, func(c *Context, m *Message) { + if c.Cap("status") != "start" && c.Server != nil { + c.AssertOne(m, true, func(c *Context, m *Message) { c.Cap("status", "start") defer c.Cap("status", "stop") @@ -352,7 +360,7 @@ func (c *Context) Start(m *Message) bool { // {{{ defer log.Printf("%d stop(%d): %s %s", m.Code, Index.Capi("nserver"), c.Name, c.Help) c.Resource = []*Message{m} - c.Server.Start(m) + c.Server.Start(m, m.Meta["detail"]...) }) } @@ -373,7 +381,7 @@ func (c *Context) Spawn(m *Message, key string, arg ...string) *Context { // {{{ // }}} -func (c *Context) Deal(pre func(m *Message) bool, post func(m *Message) bool) (live bool) { // {{{ +func (c *Context) Deal(pre func(m *Message, arg ...string) bool, post func(m *Message, arg ...string) bool) (live bool) { // {{{ if c.Messages == nil { c.Messages = make(chan *Message, c.Confi("MessageQueueSize")) @@ -385,19 +393,19 @@ func (c *Context) Deal(pre func(m *Message) bool, post func(m *Message) bool) (l return true } - if pre != nil && !pre(m) { + if pre != nil && !pre(m, m.Meta["detail"]...) { return false } - c.AssertOne(m, func(c *Context, m *Message) { - c.Cmd(m, m.Meta["detail"][0], m.Meta["detail"][1:]...) + arg := m.Meta["detail"] + c.AssertOne(m, true, func(c *Context, m *Message) { + m.Add("result", c.Cmd(m, arg[0], arg[1:]...)) }, func(c *Context, m *Message) { - m.Cmd() + m.Add("result", m.Cmd()) }, func(c *Context, m *Message) { - log.Printf("system command(%s->%s): %v", m.Context.Name, m.Target.Name, m.Meta["detail"]) - arg := m.Meta["detail"] + log.Printf("system command(%s->%s): %v", m.Context.Name, m.Target.Name, arg) cmd := exec.Command(arg[0], arg[1:]...) v, e := cmd.CombinedOutput() if e != nil { @@ -407,7 +415,7 @@ func (c *Context) Deal(pre func(m *Message) bool, post func(m *Message) bool) (l } }) - if post != nil && !post(m) { + if post != nil && !post(m, m.Meta["result"]...) { return false } @@ -811,28 +819,17 @@ func (c *Context) Capi(key string, arg ...int) int { // {{{ // }}} var Pulse = &Message{Code: 0, Time: time.Now(), Index: 0, Name: "root"} -var Index = &Context{Name: "ctx", Help: "根上下文", // {{{ + +var Index = &Context{Name: "ctx", Help: "所有模块的祖模块", Caches: map[string]*Cache{ - "status": &Cache{Name: "status", Value: "stop", Help: "服务状态"}, - "nserver": &Cache{Name: "nserver", Value: "0", Help: "服务数量"}, - "ncontext": &Cache{Name: "ncontext", Value: "0", Help: "上下文数量"}, - "nmessage": &Cache{Name: "nmessage", Value: "0", Help: "消息发送数量"}, + "nserver": &Cache{Name: "服务数量", Value: "0", Help: "显示已经启动运行模块的数量"}, + "ncontext": &Cache{Name: "模块数量", Value: "1", Help: "显示功能树已经注册模块的数量"}, + "nmessage": &Cache{Name: "消息数量", Value: "1", Help: "显示模块启动时所创建消息的数量"}, }, Configs: map[string]*Config{ - "开场白": &Config{Name: "开场白", Value: "你好,上下文", Help: "开场白"}, - "结束语": &Config{Name: "结束语", Value: "再见,上下文", Help: "结束语"}, - - "MessageQueueSize": &Config{Name: "MessageQueueSize", Value: "10", Help: "默认消息队列长度"}, - "MessageListSize": &Config{Name: "MessageListSize", Value: "10", Help: "默认消息列表长度"}, - - "cert": &Config{Name: "cert", Value: "etc/cert.pem", Help: "证书文件"}, - "key": &Config{Name: "key", Value: "etc/key.pem", Help: "私钥文件"}, - - "root": &Config{Name: "root", Value: ".", Help: "工作目录"}, - "debug": &Config{Name: "debug", Value: "off", Help: "调试模式"}, - "start": &Config{Name: "start", Value: "cli", Help: "默认启动模块"}, - "init.sh": &Config{Name: "init.sh", Value: "etc/init.sh", Help: "默认启动脚本"}, - "bench.log": &Config{Name: "bench.log", Value: "var/bench.log", Help: "默认日志文件", Hand: func(c *Context, x *Config, arg ...string) string { + "start": &Config{Name: "启动模块", Value: "cli", Help: "启动时自动运行的模块"}, + "init.sh": &Config{Name: "启动脚本", Value: "etc/init.sh", Help: "模块启动时自动运行的脚本"}, + "bench.log": &Config{Name: "日志文件", Value: "var/bench.log", Help: "模块日志输出的文件", Hand: func(c *Context, x *Config, arg ...string) string { if len(arg) > 0 { // {{{ if e := os.MkdirAll(path.Dir(arg[0]), os.ModePerm); e == nil { if l, e := os.Create(x.Value); e == nil { @@ -843,9 +840,36 @@ var Index = &Context{Name: "ctx", Help: "根上下文", // {{{ return x.Value // }}} }}, + "root": &Config{Name: "工作目录", Value: ".", Help: "所有模块的当前目录", Hand: func(c *Context, x *Config, arg ...string) string { + if len(arg) > 0 { // {{{ + if !path.IsAbs(x.Value) { + wd, e := os.Getwd() + c.Assert(e) + x.Value = path.Join(wd, x.Value) + } + + if e := os.MkdirAll(x.Value, os.ModePerm); e != nil { + fmt.Println(e) + os.Exit(1) + } + if e := os.Chdir(x.Value); e != nil { + fmt.Println(e) + os.Exit(1) + } + } + + return x.Value + // }}} + }}, + + "debug": &Config{Name: "调试模式(off/no)", Value: "off", Help: "是否打印错误信息,off:不打印,on:打印)"}, + "ContextSessionSize": &Config{Name: "会话队列长度", Value: "10", Help: "每个模块可以启动其它模块的数量"}, + "MessageQueueSize": &Config{Name: "消息队列长度", Value: "10", Help: "每个模块接收消息的队列长度"}, + "cert": &Config{Name: "证书文件", Value: "etc/cert.pem", Help: "证书文件"}, + "key": &Config{Name: "私钥文件", Value: "etc/key.pem", Help: "私钥文件"}, }, Commands: map[string]*Command{ - "void": &Command{Name: "void", Help: "建立远程连接", Hand: func(c *Context, m *Message, key string, arg ...string) string { + "void": &Command{Name: "输出简单的信息", Help: "建立远程连接", Hand: func(c *Context, m *Message, key string, arg ...string) string { m.Echo("hello void!\n") // {{{ return "" // }}} @@ -855,34 +879,25 @@ var Index = &Context{Name: "ctx", Help: "根上下文", // {{{ Resource: []*Message{Pulse}, } -// }}} - -func init() { // {{{ +func init() { if len(os.Args) > 1 { - Index.Conf("root", os.Args[1]) - } - if e := os.MkdirAll(Index.Conf("root"), os.ModePerm); e != nil { - fmt.Println(e) - os.Exit(1) - } - if e := os.Chdir(Index.Conf("root")); e != nil { - fmt.Println(e) - os.Exit(1) + Index.Conf("start", os.Args[1]) } if len(os.Args) > 2 { - Index.Conf("bench.log", os.Args[2]) + Index.Conf("init.sh", os.Args[2]) + } + + if len(os.Args) > 3 { + Index.Conf("bench.log", os.Args[3]) } else { Index.Conf("bench.log", Index.Conf("bench.log")) } - if len(os.Args) > 3 { - Index.Conf("init.sh", os.Args[3]) + if len(os.Args) > 4 { + Index.Conf("root", os.Args[4]) } - if len(os.Args) > 4 { - Index.Conf("start", os.Args[4]) - } log.Println("\n\n\n") } @@ -918,5 +933,3 @@ func Start() { } } } - -// }}} diff --git a/src/example/bench.go b/src/example/bench.go index 3157ae05..a125993b 100644 --- a/src/example/bench.go +++ b/src/example/bench.go @@ -2,11 +2,11 @@ package main import ( "context" - _ "context/aaa" + // _ "context/aaa" _ "context/cli" - _ "context/tcp" - _ "context/web" - _ "context/web/mp" + // _ "context/tcp" + // _ "context/web" + // _ "context/web/mp" ) func main() {