From ff2d9a1a62b8e82507c3699015c8566253f18410 Mon Sep 17 00:00:00 2001 From: shaoying Date: Fri, 3 Nov 2017 08:51:38 +0800 Subject: [PATCH] =?UTF-8?q?mac=20pro=20code=20=E6=95=B4=E7=90=86=E4=BA=86?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=EF=BC=8C=E4=B8=B2=E8=81=94cli=E5=92=8Ctcp?= =?UTF-8?q?=E5=BB=BA=E7=AB=8B=E8=BF=9C=E7=A8=8B=E8=BF=9E=E6=8E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- etc/go.snippets | 112 ++++++++++ etc/{hi.sh => init.sh} | 3 +- src/context/cli/cli.go | 455 +++++++++++++++++++++++------------------ src/context/ctx.go | 289 +++++++++++++------------- src/context/tcp/tcp.go | 28 ++- src/toolkit/bench.go | 3 +- 6 files changed, 528 insertions(+), 362 deletions(-) create mode 100644 etc/go.snippets rename etc/{hi.sh => init.sh} (75%) diff --git a/etc/go.snippets b/etc/go.snippets new file mode 100644 index 00000000..fac4805b --- /dev/null +++ b/etc/go.snippets @@ -0,0 +1,112 @@ +snippet p + package ${1:main} + + ${2} +snippet i + import ( + "${1}" + ) + + ${2} +snippet t + type ${1} struct { + ${2} + } + ${3} +snippet ti + type ${1} interface { + ${2} + } + ${3} +snippet c + package `Filename()` + + import ( + "context" + ) + + type `toupper(substitute(expand("%:t"), ".go", "", ""))` struct { + *ctx.Context + *ctx.CTX + } + + func (`Filename()` *`toupper(substitute(expand("%:t"), ".go", "", ""))`) Begin() bool { + return true + } + + func (`Filename()` *`toupper(substitute(expand("%:t"), ".go", "", ""))`) Start() bool { + return true + } + + func (`Filename()` *`toupper(substitute(expand("%:t"), ".go", "", ""))`) Spawn(c *ctx.Context, arg ...string) ctx.Server { + c.Caches = map[string]*ctx.Cache{} + c.Configs = map[string]*ctx.Config{} + c.Commands = map[string]*ctx.Command{} + s := new(`toupper(substitute(expand("%:t"), ".go", "", ""))`) + s.CTX = ctx.Ctx + s.Context = c + return s + } + + var Index = &ctx.Context{Name: "`Filename()`", Help: "${1}", + Caches: map[string]*ctx.Cache{}, + Configs: map[string]*ctx.Config{}, + Commands: map[string]*ctx.Command{}, + } + + func init() { + `Filename()` := &`toupper(substitute(expand("%:t"), ".go", "", ""))`{} + `Filename()`.CTX = ctx.Ctx + `Filename()`.Context = Index + ctx.Index.Register(Index, `Filename()`) + } +snippet v + var ( + ${1} + ) + ${2} +snippet m + func main() { + ${1} + } + +snippet h + func(w http.ResponseWriter, r *http.Request) { + ${1} + }) +snippet f + func${1}(${2}) ${3}{ + ${4} + }${5} +snippet " + "${1}"${2} +snippet ` + `${1}`${2} +snippet ( + (${1})${2} +snippet [ + [${1}]${2} +snippet { + {${1}}${2} +snippet if + if ${1} { + ${2} + } + ${3} +snippet for + for ${1}{ + ${2} + } + ${3} +snippet switch + switch ${1}{ + case ${2}: + ${3} + } + ${4} +snippet select + select { + case ${1}: + ${2} + } + ${3} diff --git a/etc/hi.sh b/etc/init.sh similarity index 75% rename from etc/hi.sh rename to etc/init.sh index 7e3da636..1bda9b54 100644 --- a/etc/hi.sh +++ b/etc/init.sh @@ -5,5 +5,4 @@ alias $ cache alias & server alias * message -~root -~tcp +remote slave listen :9393 tcp diff --git a/src/context/cli/cli.go b/src/context/cli/cli.go index 1127af03..00fac86a 100644 --- a/src/context/cli/cli.go +++ b/src/context/cli/cli.go @@ -18,11 +18,11 @@ import ( // {{{ // }}} type CLI struct { - in *os.File - ins []*os.File + out io.WriteCloser + in io.ReadCloser + ins []io.ReadCloser bio *bufio.Reader bios []*bufio.Reader - out *os.File history []map[string]string alias map[string]string @@ -31,11 +31,12 @@ type CLI struct { target *ctx.Context *ctx.Context + *ctx.CTX } -func (cli *CLI) push(f *os.File) { // {{{ +func (cli *CLI) push(f io.ReadCloser) { // {{{ if cli.ins == nil || cli.bios == nil { - cli.ins = make([]*os.File, 0, 3) + cli.ins = make([]io.ReadCloser, 0, 3) cli.bios = make([]*bufio.Reader, 0, 3) } @@ -47,7 +48,7 @@ func (cli *CLI) push(f *os.File) { // {{{ // }}} func (cli *CLI) parse() bool { // {{{ - if len(cli.ins) == 1 { + if len(cli.ins) == 1 || cli.Conf("slient") != "yes" { cli.echo(cli.Conf("PS1")) } @@ -63,8 +64,6 @@ func (cli *CLI) parse() bool { // {{{ } cli.echo("\n") cli.exit <- true - return false - } else { cli.ins = cli.ins[:l-1] cli.bios = cli.bios[:l-1] @@ -75,24 +74,24 @@ func (cli *CLI) parse() bool { // {{{ } cli.Check(e) line = l + + if len(cli.ins) > 1 || cli.Conf("slient") != "yes" { + cli.echo(line) + } + + if len(line) == 1 { + return true + } } else { line = cli.next - if len(cli.ins) == 1 { + cli.next = "" + + if cli.Conf("slient") != "yes" { cli.echo(line) cli.echo("\n") } } - if len(cli.ins) > 1 { - cli.echo(cli.Conf("PS1")) - cli.echo(line) - } - cli.next = "" - - if len(line) == 1 { - return true - } - line = strings.TrimSpace(line) if line[0] == '#' { return true @@ -142,34 +141,33 @@ func (cli *CLI) parse() bool { // {{{ func (cli *CLI) deal(msg *ctx.Message) bool { // {{{ defer func() { if e := recover(); e != nil { - msg.Echo("%s", e) + msg.Echo("%s\n", e) debug.PrintStack() log.Println(e) + msg.End(false) } }() detail := msg.Meta["detail"] - switch cli.Conf("mode") { - case "local": - if a, ok := cli.alias[detail[0]]; ok { - detail[0] = a - } - - if _, ok := cli.Commands[detail[0]]; ok { - cli.next = cli.Cmd(msg, detail...) - } else if _, ok := cli.target.Commands[detail[0]]; ok { - cli.target.Message = msg - cli.next = cli.target.Cmd(msg, detail...) - } else { - cmd := exec.Command(detail[0], detail[1:]...) - v, e := cmd.CombinedOutput() - if e != nil { - msg.Echo("%s\n", e) - } - msg.Echo(string(v)) - log.Println(cli.Name, "command:", detail) - } + if a, ok := cli.alias[detail[0]]; ok { + detail[0] = a } + + if _, ok := cli.Commands[detail[0]]; ok { + cli.next = cli.Cmd(msg, detail...) + } else if _, ok := cli.target.Commands[detail[0]]; ok { + cli.next = cli.target.Cmd(msg, detail...) + } else { + cmd := exec.Command(detail[0], detail[1:]...) + v, e := cmd.CombinedOutput() + if e != nil { + msg.Echo("%s\n", e) + } + msg.Echo(string(v)) + log.Println(cli.Name, "command:", detail) + } + msg.End(true) + cli.history = append(cli.history, map[string]string{ "time": time.Now().Format("15:04:05"), "index": fmt.Sprintf("%d", len(cli.history)), @@ -188,34 +186,39 @@ func (cli *CLI) echo(str string, arg ...interface{}) { // {{{ // }}} func (cli *CLI) Begin() bool { // {{{ - cli.history = make([]map[string]string, 0, 100) - cli.alias = make(map[string]string, 10) - cli.exit = make(chan bool) - cli.target = cli.Context - if f, e := os.Open(cli.Conf("init.sh")); e == nil { cli.push(f) } + cli.history = make([]map[string]string, 0, 100) + cli.alias = make(map[string]string, 10) + cli.exit = make(chan bool) + cli.target = cli.Context + return true +} + +// }}} +func (cli *CLI) Start() bool { // {{{ + if msg, ok := cli.Session["remote"]; ok { + cli.push(msg.Data["result"].(io.ReadCloser)) + cli.out = msg.Data["result"].(io.WriteCloser) + cli.echo(cli.Conf("开场白")) + } if cli.Conf("slient") != "yes" { cli.echo("\n") cli.echo(cli.Conf("开场白")) cli.echo("\n") } - return true -} + if cli.Conf("mode") == "local" { + go func() { + defer recover() + for cli.parse() { + } + }() + } -// }}} -func (cli *CLI) Start() bool { // {{{ - go func() { - for cli.parse() { - } - }() - - for { - msg := cli.Get() - msg.End(cli.deal(msg)) + for cli.deal(cli.Get()) { } return true @@ -223,6 +226,12 @@ func (cli *CLI) Start() bool { // {{{ // }}} func (cli *CLI) Spawn(c *ctx.Context, arg ...string) ctx.Server { // {{{ + c.Caches = map[string]*ctx.Cache{} + c.Configs = map[string]*ctx.Config{ + "address": &ctx.Config{Name: "address", Value: arg[0], Help: "监听地址"}, + "protocol": &ctx.Config{Name: "protocol", Value: arg[1], Help: "监听协议"}, + } + s := new(CLI) s.Context = c return s @@ -240,12 +249,10 @@ var Index = &ctx.Context{Name: "cli", Help: "本地控制", cli := c.Server.(*CLI) // {{{ cli.out = os.Stdout cli.push(os.Stdin) - return arg // }}} }}, - "slient": &ctx.Config{Name: "slient", Value: "yes", Help: "静默启动"}, - "init.sh": &ctx.Config{Name: "init.sh", Value: "etc/hi.sh", Help: "启动脚本"}, + "slient": &ctx.Config{Name: "slient", Value: "yes", Help: "静默启动"}, "PS1": &ctx.Config{Name: "PS1", Value: "etcvpn>", Help: "命令行提示符", Hand: func(c *ctx.Context, arg string) string { cli := c.Server.(*CLI) // {{{ if cli != nil && cli.target != nil { @@ -256,95 +263,130 @@ var Index = &ctx.Context{Name: "cli", Help: "本地控制", }}, }, Commands: map[string]*ctx.Command{ - "cache": &ctx.Command{"cache [name [value [help]]]", "查看修改添加配置", func(c *ctx.Context, msg *ctx.Message, arg ...string) string { - cli := c.Server.(*CLI) // {{{ - + "context": &ctx.Command{"context [spawn|find|search name [which]]|root|back|home", "查看上下文", func(c *ctx.Context, msg *ctx.Message, arg ...string) string { + cli, ok := c.Server.(*CLI) // {{{ switch len(arg) { case 1: - for k, v := range cli.target.Caches { - msg.Echo("%s(%s): %s\n", k, v.Value, v.Help) + cs := []*ctx.Context{msg.Target} + for i := 0; i < len(cs); i++ { + if len(cs[i].Contexts) > 0 { + msg.Echo("%s: ", cs[i].Name) + for k, v := range cs[i].Contexts { + cs = append(cs, v) + msg.Echo("%s, ", k) + } + msg.Echo("\n") + } } case 2: - if v, ok := cli.target.Caches[arg[1]]; ok { - msg.Echo("%s: %s\n", v.Name, v.Help) - } - case 3: switch arg[1] { - case "delete": - if _, ok := cli.target.Caches[arg[2]]; ok { - delete(cli.target.Caches, arg[2]) + case "root": + if ok { + cli.target = cli.Context.Root + } else { + msg.Target = msg.Target.Root + } + case "back": + if ok { + if cli.Context.Context != nil { + cli.target = cli.Context.Context + } + } else { + if msg.Target.Context != nil { + msg.Target = msg.Target.Context + } + } + case "home": + if ok { + cli.target = cli.Context + } else { + msg.Target = msg.Context } default: - if _, ok := cli.target.Caches[arg[1]]; ok { - msg.Echo("%s: %s\n", arg[1], cli.target.Cap(arg[1:]...)) + if cs := msg.Target.Find(strings.Split(arg[1], ".")); cs != nil { + if ok { + cli.target = cs + } else { + msg.Target = cs + } } } - case 5: - cli.target.Cap(arg[1:]...) + case 3, 4: + switch arg[1] { + case "spawn": + msg.Target.Spawn(arg[2]) + case "find": + cs := msg.Target.Find(strings.Split(arg[2], ".")) + if cs != nil { + msg.Echo("%s: %s\n", cs.Name, cs.Help) + if len(arg) == 4 { + if ok { + cli.target = cs + } else { + msg.Target = cs + } + } + } + case "search": + cs := msg.Target.Search(arg[2]) + for i, v := range cs { + msg.Echo("[%d] %s: %s\n", i, v.Name, v.Help) + } + + if len(arg) == 4 { + n, e := strconv.Atoi(arg[3]) + if 0 <= n && n < len(cs) && e == nil { + if ok { + cli.target = cs[n] + } else { + msg.Target = cs[n] + } + } else { + msg.Echo("参数错误(0<=n<%s)", len(cs)) + } + } + } + } + + return "" + // }}} + }}, + "message": &ctx.Command{"message detail...", "查看上下文", func(c *ctx.Context, msg *ctx.Message, arg ...string) string { + msg.Meta["detail"] = arg[1:] // {{{ + if c == msg.Target { + go msg.Target.Post(msg) + } else { + msg.Target.Post(msg) } return "" // }}} }}, - "config": &ctx.Command{"config [name [value [help]]]", "查看修改添加配置", func(c *ctx.Context, msg *ctx.Message, arg ...string) string { - cli := c.Server.(*CLI) // {{{ - + "server": &ctx.Command{"server start|stop|switch", "服务启动停止切换", func(c *ctx.Context, msg *ctx.Message, arg ...string) string { + s := msg.Target // {{{ switch len(arg) { case 1: - for k, v := range cli.target.Configs { - msg.Echo("%s(%s): %s\n", k, v.Value, v.Help) - } + return "server start" case 2: - if v, ok := cli.target.Configs[arg[1]]; ok { - msg.Echo("%s: %s\n", v.Name, v.Help) - } - case 3: switch arg[1] { - case "delete": - if _, ok := cli.target.Configs[arg[2]]; ok { - delete(cli.target.Configs, arg[2]) - } - default: - if _, ok := cli.target.Configs[arg[1]]; ok { - cli.target.Conf(arg[1:]...) - } - } - case 5: - cli.target.Conf(arg[1:]...) - } - return "" - // }}} - }}, - "command": &ctx.Command{"command [name [value [help]]]", "查看修改添加配置", func(c *ctx.Context, msg *ctx.Message, arg ...string) string { - cli := c.Server.(*CLI) // {{{ - - switch len(arg) { - case 1: - for k, v := range cli.target.Commands { - msg.Echo("%s: %s\n", k, v.Help) - } - case 2: - if v, ok := cli.target.Commands[arg[1]]; ok { - msg.Echo("%s: %s\n", v.Name, v.Help) - } - case 3: - switch arg[1] { - case "delete": - if _, ok := cli.target.Commands[arg[2]]; ok { - delete(cli.target.Commands, arg[2]) + case "start": + if s != nil { + go s.Start() } + case "stop": + case "switch": } } - - msg.Echo("\n") return "" // }}} }}, "source": &ctx.Command{"source file", "运行脚本", func(c *ctx.Context, msg *ctx.Message, arg ...string) string { cli := c.Server.(*CLI) // {{{ - - f, e := os.Open(arg[1]) - c.Check(e) - cli.push(f) + switch len(arg) { + case 2: + f, e := os.Open(arg[1]) + c.Check(e) + cli.push(f) + } return "" // }}} @@ -384,101 +426,118 @@ var Index = &ctx.Context{Name: "cli", Help: "本地控制", return "" // }}} }}, - "message": &ctx.Command{"message detail...", "查看上下文", func(c *ctx.Context, msg *ctx.Message, arg ...string) string { - msg.Meta["detail"] = arg[1:] - msg.Target.Post(msg) - return "" - }}, - "server": &ctx.Command{"server start|stop|switch", "服务启动停止切换", func(c *ctx.Context, msg *ctx.Message, arg ...string) string { - s := msg.Target // {{{ - switch len(arg) { + "command": &ctx.Command{"command [name [value [help]]]", "查看修改添加配置", func(c *ctx.Context, msg *ctx.Message, arg ...string) string { + switch len(arg) { // {{{ case 1: - return "server start" + for k, v := range msg.Target.Commands { + msg.Echo("%s: %s\n", k, v.Help) + } case 2: + if v, ok := msg.Target.Commands[arg[1]]; ok { + msg.Echo("%s: %s\n", v.Name, v.Help) + } + case 3: switch arg[1] { - case "start": - go s.Start() - case "stop": - case "switch": + case "delete": + if _, ok := msg.Target.Commands[arg[2]]; ok { + delete(msg.Target.Commands, arg[2]) + } } } + + msg.Echo("\n") return "" // }}} }}, - "context": &ctx.Command{"context [spawn|fork|find|search name [switch]]|root|back|home", "查看上下文", func(c *ctx.Context, msg *ctx.Message, arg ...string) string { - cli := c.Server.(*CLI) // {{{ - - switch len(arg) { + "config": &ctx.Command{"config [name [value [help]]]", "查看修改添加配置", func(c *ctx.Context, msg *ctx.Message, arg ...string) string { + switch len(arg) { // {{{ case 1: - cs := []*ctx.Context{cli.target} - for i := 0; i < len(cs); i++ { - if len(cs[i].Contexts) > 0 { - msg.Echo("%s: ", cs[i].Name) - for k, v := range cs[i].Contexts { - cs = append(cs, v) - msg.Echo("%s, ", k) - } - msg.Echo("\n") - } + for k, v := range msg.Target.Configs { + msg.Echo("%s(%s): %s\n", k, v.Value, v.Help) } - case 2, 3, 4, 5: + case 2: + if v, ok := msg.Target.Configs[arg[1]]; ok { + msg.Echo("%s: %s\n", v.Name, v.Help) + } + case 3: switch arg[1] { - case "spawn": - msg.Target.Spawn(arg[2]) - case "root": - cli.target = cli.Context.Root - case "back": - if cli.Context.Context != nil { - cli.target = cli.Context.Context - } - case "home": - cli.target = cli.Context - case "find": - cs := c.Root.Find(strings.Split(arg[2], ".")) - if cs != nil { - msg.Echo("%s: %s\n", cs.Name, cs.Help) - if len(arg) == 4 { - cli.target = cs - } - } - case "search": - cs := c.Root.Search(arg[2]) - for i, v := range cs { - msg.Echo("[%d] %s: %s\n", i, v.Name, v.Help) - } - - if len(arg) == 5 { - n, e := strconv.Atoi(arg[4]) - if 0 <= n && n < len(cs) && e == nil { - cli.target = cs[0] - } else { - msg.Echo("参数错误(0<=n<%s)", len(cs)) - } - } - - if len(arg) == 4 { - cli.target = cs[0] + case "delete": + if _, ok := msg.Target.Configs[arg[2]]; ok { + delete(msg.Target.Configs, arg[2]) } default: - cs := c.Root.Find(strings.Split(arg[1], ".")) - if cs != nil { - msg.Echo("%s: %s\n", cs.Name, cs.Help) - if cs != nil { - cli.target = cs - } + if _, ok := msg.Target.Configs[arg[1]]; ok { + msg.Target.Conf(arg[1:]...) + } + } + case 5: + msg.Target.Conf(arg[1:]...) + } + return "" + // }}} + }}, + "cache": &ctx.Command{"cache [name [value [help]]]", "查看修改添加配置", func(c *ctx.Context, msg *ctx.Message, arg ...string) string { + switch len(arg) { // {{{ + case 1: + for k, v := range msg.Target.Caches { + msg.Echo("%s(%s): %s\n", k, v.Value, v.Help) + } + case 2: + if v, ok := msg.Target.Caches[arg[1]]; ok { + msg.Echo("%s: %s\n", v.Name, v.Help) + } + case 3: + switch arg[1] { + case "delete": + if _, ok := msg.Target.Caches[arg[2]]; ok { + delete(msg.Target.Caches, arg[2]) + } + default: + if _, ok := msg.Target.Caches[arg[1]]; ok { + msg.Echo("%s: %s\n", arg[1], msg.Target.Cap(arg[1:]...)) + } + } + case 5: + msg.Target.Cap(arg[1:]...) + } + return "" + // }}} + }}, + "remote": &ctx.Command{"remote master|slave listen|dial address protocol", "建立远程连接", func(c *ctx.Context, m *ctx.Message, arg ...string) string { + switch len(arg) { + case 1: + case 5: + if arg[1] == "master" { + if arg[2] == "dial" { + } else { + } + } else { + if arg[2] == "listen" { + msg := &ctx.Message{Code: c.Root.Capi("nmessage", 1), Time: time.Now()} + msg.Add("mode", "local") + msg.Target = c.Root.Find(strings.Split(arg[4], ".")) + msg.Context = m.Context + msg.Target.Cmd(msg, "listen", arg[3]) + } else { } } } - return "" - // }}} + }}, + "accept": &ctx.Command{"accept address protocl", "建立远程连接", func(c *ctx.Context, msg *ctx.Message, arg ...string) string { + s := msg.Context.Spawn(arg[1], arg[2]) + s.Session = make(map[string]*ctx.Message) + s.Session["remote"] = msg + s.Start() + return "" }}, }, Messages: make(chan *ctx.Message, 10), } func init() { - self := &CLI{} - self.Context = Index - ctx.Index.Register(Index, self) + cli := &CLI{} + cli.CTX = ctx.Ctx + cli.Context = Index + ctx.Index.Register(Index, cli) } diff --git a/src/context/ctx.go b/src/context/ctx.go index 39d11083..81b4ffe2 100644 --- a/src/context/ctx.go +++ b/src/context/ctx.go @@ -38,18 +38,18 @@ type Command struct { // {{{ // }}} type Message struct { // {{{ - Code int Time time.Time + Code int Meta map[string][]string Data map[string]interface{} Wait chan bool + Index int + Target *Context + Name string *Context - - Target *Context - Index int } func (m *Message) Add(key string, value ...string) string { // {{{ @@ -109,7 +109,6 @@ func (m *Message) Echo(str string, arg ...interface{}) string { // {{{ // }}} func (m *Message) End(s bool) { // {{{ - // log.Println(m.Name, "end", m.Code, ":", m.Meta["detail"]) if m.Wait != nil { m.Wait <- s } @@ -132,19 +131,20 @@ type Context struct { // {{{ Caches map[string]*Cache Configs map[string]*Config Commands map[string]*Command + Messages chan *Message Message *Message Server - Root *Context - Context *Context - Contexts map[string]*Context + Resource []*Message + Session map[string]*Message Index map[string]*Context Shadows map[string]*Context - Session map[string]*Message - Resource []*Message + Contexts map[string]*Context + Context *Context + Root *Context } func (c *Context) Check(e error) bool { // {{{ @@ -159,33 +159,105 @@ func (c *Context) Check(e error) bool { // {{{ } // }}} - -func (c *Context) Request(arg ...string) bool { // {{{ - if c.Session == nil { - c.Session = make(map[string]*Message) +func (c *Context) Register(s *Context, self Server) bool { // {{{ + if c.Contexts == nil { + c.Contexts = make(map[string]*Context) } - m := &Message{ - Code: c.Capi("nmessage", 1), - Time: time.Now(), - Meta: map[string][]string{}, - Data: map[string]interface{}{}, - Name: arg[0], + if x, ok := c.Contexts[s.Name]; ok { + panic(errors.New(c.Name + " 上下文已存在" + x.Name)) } - m.Context = c + + c.Contexts[s.Name] = s + s.Context = c + s.Root = c.Root + s.Server = self + + log.Println(c.Name, "register:", s.Name) return true } // }}} -func (c *Context) Release(key string) bool { // {{{ +func (c *Context) Init(arg ...string) { // {{{ + if c.Root != nil { + return + } - return true + root := c + for root.Context != nil { + root = root.Context + } + + if len(arg) > 0 { + root.Conf("bench.log", arg[0]) + } else { + root.Conf("bench.log", root.Conf("bench.log")) + } + + if len(arg) > 1 { + root.Conf("init.sh", arg[1]) + } else { + root.Conf("init.sh", root.Conf("init.sh")) + } + + cs := []*Context{root} + + for i := 0; i < len(cs); i++ { + cs[i].Root = root + cs[i].Begin() + + for _, v := range cs[i].Contexts { + cs = append(cs, v) + } + } + + if len(arg) > 2 { + for _, v := range arg[2:] { + cs = root.Search(v) + for _, s := range cs { + go s.Start() + } + } + } else { + go root.Find(strings.Split(root.Conf("default"), ".")).Start() + } + + <-make(chan bool) } // }}} -func (c *Context) Destroy(index int) bool { // {{{ +func (c *Context) Find(name []string) *Context { // {{{ + if x, ok := c.Contexts[name[0]]; ok { + log.Println(c.Name, "find:", x.Name) + if len(name) == 1 { + return x + } + return x.Find(name[1:]) + } - return true + log.Println(c.Name, "not find:", name[0]) + return nil +} + +// }}} +func (c *Context) Search(name string) []*Context { // {{{ + ps := make([]*Context, 0, 3) + + cs := []*Context{c} + for i := 0; i < len(cs); i++ { + for _, v := range cs[i].Contexts { + cs = append(cs, v) + } + + if strings.Contains(cs[i].Name, name) || strings.Contains(cs[i].Help, name) { + ps = append(ps, cs[i]) + log.Println(c.Name, "search:", i, cs[i].Name, "[match]") + } else { + log.Println(c.Name, "search:", i, cs[i].Name) + } + } + + return ps } // }}} @@ -354,125 +426,40 @@ func (c *Context) Del(arg ...string) { // {{{ // }}} -func (c *Context) Find(name []string) *Context { // {{{ - if x, ok := c.Contexts[name[0]]; ok { - log.Println(c.Name, "find:", x.Name) - if len(name) == 1 { - return x - } - return x.Find(name[1:]) +func (c *Context) Request(s *Context, key string) *Message { // {{{ + if c.Session == nil { + c.Session = make(map[string]*Message) + } + if s.Resource == nil { + s.Resource = make([]*Message, 0, c.Confi("MessageListSize")) } - log.Println(c.Name, "not find:", name[0]) - return nil -} + m := &Message{Index: len(s.Resource), Name: key} -// }}} -func (c *Context) Search(name string) []*Context { // {{{ - ps := make([]*Context, 0, 3) + m.Target = s + m.Context = c - cs := []*Context{c} - for i := 0; i < len(cs); i++ { - for _, v := range cs[i].Contexts { - cs = append(cs, v) - } - - if strings.Contains(cs[i].Name, name) || strings.Contains(cs[i].Help, name) { - ps = append(ps, cs[i]) - log.Println(c.Name, "search:", i, cs[i].Name, "[match]") - } else { - log.Println(c.Name, "search:", i, cs[i].Name) - } - } - - return ps -} - -// }}} -func (c *Context) Register(s *Context, self Server) bool { // {{{ - if c.Contexts == nil { - c.Contexts = make(map[string]*Context) - } - - if x, ok := c.Contexts[s.Name]; ok { - panic(errors.New(c.Name + " 上下文已存在" + x.Name)) - } - - c.Contexts[s.Name] = s - s.Context = c - s.Root = c.Root - s.Server = self - - log.Println(c.Name, "register:", s.Name) - return true -} - -// }}} -func (c *Context) Init(arg ...string) { // {{{ - if c.Root != nil { - return - } - - root := c - for root.Context != nil { - root = root.Context - } - - if len(arg) > 0 { - root.Conf("log", arg[0]) - } else { - root.Conf("log", root.Conf("log")) - } - - if len(arg) > 1 { - root.Conf("init.sh", arg[1]) - } else { - root.Conf("init.sh", root.Conf("init.sh")) - } - - cs := []*Context{root} - - for i := 0; i < len(cs); i++ { - cs[i].Root = root - cs[i].Begin() - - for _, v := range cs[i].Contexts { - cs = append(cs, v) - } - } - - if len(arg) > 2 { - for _, v := range arg[2:] { - cs = root.Search(v) - for _, s := range cs { - log.Println(v, "match start:", s.Name) - go s.Start() - } - } - } else { - go root.Find(strings.Split(root.Conf("default"), ".")).Start() - } - - <-make(chan bool) + return m } // }}} func (c *Context) Begin() bool { // {{{ + c.Root.Capi("ncontext", 1) for k, v := range c.Configs { c.Conf(k, v.Value) } - if c.Server != nil && c.Server.Begin() { - c.Root.Capi("ncontext", 1) - return true + if c.Server != nil { + return c.Server.Begin() } - - return false + return true } // }}} func (c *Context) Start() bool { // {{{ + defer recover() + if c.Server != nil && c.Cap("status") != "start" { c.Cap("status", "status", "start", "服务状态") defer c.Cap("status", "stop") @@ -499,29 +486,14 @@ func (c *Context) Spawn(arg ...string) *Context { // {{{ } // }}} -func (c *Context) Get() *Message { // {{{ - if c.Messages == nil { - c.Messages = make(chan *Message, c.Confi("MessageQueueSize")) - } - select { - case msg := <-c.Messages: - // log.Println(c.Name, "get", msg.Code, ":", msg.Meta["detail"]) - return msg - } - - return nil -} - -// }}} func (c *Context) Post(m *Message) bool { // {{{ if c.Messages == nil { c.Messages = make(chan *Message, c.Confi("MessageQueueSize")) } + m.Time = time.Now() m.Code = c.Root.Capi("nmessage", 1) - // log.Println(c.Name, "post", m.Code, ":", m.Meta["detail"]) - // defer log.Println(c.Name, "done", m.Code, ":", m.Meta["detail"]) c.Messages <- m if m.Wait != nil { @@ -530,6 +502,15 @@ func (c *Context) Post(m *Message) bool { // {{{ return true } +// }}} +func (c *Context) Get() *Message { // {{{ + if c.Messages == nil { + c.Messages = make(chan *Message, c.Confi("MessageQueueSize")) + } + + return <-c.Messages +} + // }}} func (c *Context) Cmd(m *Message, arg ...string) string { // {{{ @@ -642,13 +623,18 @@ func (c *Context) Capi(key string, value int) int { // {{{ n, e := strconv.Atoi(c.Cap(key)) c.Check(e) c.Cap(key, strconv.Itoa(n+value)) - // log.Println(c.Name, "cache:", n+value) + log.Println(c.Name, "cache:", key, n+value) return n } // }}} // }}} +type CTX struct { +} + +var Ctx = &CTX{} + var Index = &Context{Name: "ctx", Help: "根上下文", Caches: map[string]*Cache{ "status": &Cache{Name: "status", Value: "stop", Help: "服务状态"}, @@ -661,22 +647,25 @@ var Index = &Context{Name: "ctx", 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: "私钥文件"}, "debug": &Config{Name: "debug", Value: "on", Help: "调试模式"}, "default": &Config{Name: "default", Value: "cli", Help: "默认启动模块"}, - "init.sh": &Config{Name: "init.sh", Value: "etc/hi.sh", Help: "默认启动脚本"}, - "log": &Config{Name: "log", Value: "var/bench.log", Help: "默认日志文件", Hand: func(c *Context, arg string) string { - if l, e := os.Create(arg); e == nil { // {{{ - log.SetOutput(l) - } else { - log.Println("log", arg, "create error") - } + "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, arg string) string { + l, e := os.Create(arg) // {{{ + c.Check(e) + log.SetOutput(l) return arg // }}} }}, }, Commands: map[string]*Command{}, } + +func Start() { + Index.Init(os.Args[1:]...) +} diff --git a/src/context/tcp/tcp.go b/src/context/tcp/tcp.go index 96cce721..5a874567 100644 --- a/src/context/tcp/tcp.go +++ b/src/context/tcp/tcp.go @@ -4,23 +4,20 @@ import ( "context" "log" "net" + "time" ) type TCP struct { listener net.Listener - conn []net.Conn - - target *ctx.Context *ctx.Context + *ctx.CTX } func (tcp *TCP) Begin() bool { - tcp.conn = make([]net.Conn, 0, 3) return true } func (tcp *TCP) Start() bool { - log.Println(tcp.Conf("address")) if tcp.Conf("address") == "" { return true } @@ -35,8 +32,14 @@ func (tcp *TCP) Start() bool { c, e := l.Accept() log.Println(tcp.Name, "accept:", c.LocalAddr(), "<-", c.RemoteAddr()) tcp.Check(e) - tcp.conn = append(tcp.conn, c) - tcp.Capi("nclient", 1) + + msg := &ctx.Message{Code: tcp.Root.Capi("nmessage", 1), Time: time.Now()} + msg.Context = tcp.Resource[0].Context + msg.Index = tcp.Capi("nclient", 1) + msg.Target = tcp.Context + msg.Put("result", c) + msg.Context.Cmd(msg, "accept", c.RemoteAddr().String(), "tcp") + tcp.Resource = append(tcp.Resource, msg) } return true } @@ -72,6 +75,10 @@ var Index = &ctx.Context{Name: "tcp", Help: "网络连接", } case 2: s := c.Spawn(arg[1:]...) + s.Resource = make([]*ctx.Message, 0, 3) + s.Resource = append(s.Resource, m) + m.Target = s + m.Index = 0 go s.Start() } return "" @@ -80,13 +87,13 @@ var Index = &ctx.Context{Name: "tcp", Help: "网络连接", tcp := c.Server.(*TCP) switch len(arg) { case 1: - for i, v := range tcp.conn { - m.Echo(tcp.Name, "conn: %s %s -> %s\n", i, v.LocalAddr(), v.RemoteAddr()) + for i, v := range tcp.Resource { + conn := v.Data["result"].(net.Conn) + m.Echo(tcp.Name, "conn: %s %s -> %s\n", i, conn.LocalAddr(), conn.RemoteAddr()) } case 2: conn, e := net.Dial("tcp", arg[1]) c.Check(e) - tcp.conn = append(tcp.conn, conn) log.Println(tcp.Name, "dial:", conn.LocalAddr(), "->", conn.RemoteAddr()) } return "" @@ -96,6 +103,7 @@ var Index = &ctx.Context{Name: "tcp", Help: "网络连接", func init() { tcp := &TCP{} + tcp.CTX = ctx.Ctx tcp.Context = Index ctx.Index.Register(Index, tcp) } diff --git a/src/toolkit/bench.go b/src/toolkit/bench.go index 6012ab1b..bddf2800 100644 --- a/src/toolkit/bench.go +++ b/src/toolkit/bench.go @@ -6,9 +6,8 @@ import ( _ "context/ssh" _ "context/tcp" _ "context/web" - "os" ) func main() { - ctx.Index.Init(os.Args[1:]...) + ctx.Start() }