diff --git a/base/aaa/user.go b/base/aaa/user.go
index 3f03b68d..25f617d4 100644
--- a/base/aaa/user.go
+++ b/base/aaa/user.go
@@ -3,13 +3,16 @@ package aaa
import (
ice "github.com/shylinux/icebergs"
"github.com/shylinux/icebergs/base/cli"
- "github.com/shylinux/icebergs/base/gdb"
"github.com/shylinux/icebergs/base/mdb"
kit "github.com/shylinux/toolkits"
"strings"
)
+const (
+ USER_CREATE = "user.create"
+)
+
func _user_list(m *ice.Message) {
m.Richs(USER, nil, kit.MDB_FOREACH, func(key string, value map[string]interface{}) {
m.Push(key, value, []string{kit.MDB_TIME, USERZONE, USERNICK, USERNAME})
@@ -50,7 +53,7 @@ func _user_create(m *ice.Message, name, word string) {
USERNODE, cli.NodeName,
))
m.Log_CREATE(USERNAME, name, "hash", h)
- m.Event(gdb.USER_CREATE, name)
+ m.Event(USER_CREATE, name)
}
func _user_search(m *ice.Message, kind, name, text string, arg ...string) {
m.Richs(USER, nil, kit.MDB_FOREACH, func(key string, val map[string]interface{}) {
diff --git a/base/ctx/conf.go b/base/ctx/conf.go
index 542ced8c..330aff8f 100644
--- a/base/ctx/conf.go
+++ b/base/ctx/conf.go
@@ -60,7 +60,7 @@ func _config_load(m *ice.Message, name string, arg ...string) {
for k, v := range data {
msg.Search(k, func(p *ice.Context, s *ice.Context, key string) {
- m.Log_IMPORT(CONFIG, kit.Keys(s.Name, key), kit.MDB_FILE, name)
+ // m.Log_IMPORT(CONFIG, kit.Keys(s.Name, key), kit.MDB_FILE, name)
s.Configs[key].Value = v
})
}
diff --git a/base/gdb/event.go b/base/gdb/event.go
new file mode 100644
index 00000000..94e52996
--- /dev/null
+++ b/base/gdb/event.go
@@ -0,0 +1,56 @@
+package gdb
+
+import (
+ ice "github.com/shylinux/icebergs"
+ "github.com/shylinux/icebergs/base/mdb"
+ kit "github.com/shylinux/toolkits"
+)
+
+func _event_listen(m *ice.Message, event string, cmd string) {
+ h := m.Cmdx(mdb.INSERT, EVENT, "", mdb.HASH, EVENT, event)
+ m.Cmdy(mdb.INSERT, EVENT, kit.Keys(kit.MDB_HASH, h), mdb.LIST, kit.SSH_CMD, cmd)
+}
+func _event_action(m *ice.Message, event string, arg ...string) {
+ m.Option(mdb.FIELDS, "time,id,cmd")
+ m.Cmd(mdb.SELECT, EVENT, kit.Keys(kit.MDB_HASH, kit.Hashs(event)), mdb.LIST).Table(func(index int, value map[string]string, head []string) {
+ m.Cmd(kit.Split(value[kit.SSH_CMD]), event, arg).Cost("event %v %v", event, arg)
+ })
+}
+
+const EVENT = "event"
+
+func init() {
+ Index.Merge(&ice.Context{
+ Configs: map[string]*ice.Config{
+ EVENT: {Name: EVENT, Help: "事件流", Value: kit.Data(
+ kit.MDB_SHORT, EVENT,
+ )},
+ },
+ Commands: map[string]*ice.Command{
+ EVENT: {Name: "event event id auto 监听", Help: "事件流", Action: map[string]*ice.Action{
+ LISTEN: {Name: "listen event cmd", Help: "监听", Hand: func(m *ice.Message, arg ...string) {
+ _event_listen(m, m.Option(EVENT), m.Option(kit.SSH_CMD))
+ }},
+ ACTION: {Name: "action event arg", Help: "触发", Hand: func(m *ice.Message, arg ...string) {
+ _event_action(m, m.Option(EVENT), arg[2:]...)
+ }},
+ mdb.REMOVE: {Name: "remove", Help: "删除", Hand: func(m *ice.Message, arg ...string) {
+ m.Cmdy(mdb.DELETE, EVENT, "", mdb.HASH, EVENT, m.Option(EVENT))
+ }},
+ }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
+ if len(arg) == 0 {
+ m.Option(mdb.FIELDS, "time,event,count")
+ m.Cmdy(mdb.SELECT, EVENT, "", mdb.HASH)
+ m.PushAction(ACTION, mdb.REMOVE)
+ return
+ }
+
+ m.Option(mdb.FIELDS, kit.Select("time,id,cmd", mdb.DETAIL, len(arg) > 1))
+ m.Cmdy(mdb.SELECT, EVENT, kit.Keys(kit.MDB_HASH, kit.Hashs(arg[0])), mdb.LIST, kit.MDB_ID, arg[1:])
+ if len(arg) == 1 {
+ m.Sort(kit.MDB_ID)
+ }
+ }},
+ },
+ }, nil)
+}
diff --git a/base/gdb/gdb.go b/base/gdb/gdb.go
index 173ad355..0d659a8b 100644
--- a/base/gdb/gdb.go
+++ b/base/gdb/gdb.go
@@ -3,67 +3,39 @@ package gdb
import (
ice "github.com/shylinux/icebergs"
"github.com/shylinux/icebergs/base/cli"
- "github.com/shylinux/icebergs/base/mdb"
"github.com/shylinux/icebergs/base/nfs"
kit "github.com/shylinux/toolkits"
"os"
- "os/signal"
- "syscall"
"time"
)
type Frame struct {
- s chan os.Signal
t <-chan time.Time
- d chan []string
+ s chan os.Signal
+ e chan bool
}
func (f *Frame) Spawn(m *ice.Message, c *ice.Context, arg ...string) ice.Server {
return &Frame{}
}
func (f *Frame) Begin(m *ice.Message, arg ...string) ice.Server {
+ f.t = time.Tick(kit.Duration(m.Cap(ice.CTX_STREAM, ice.MOD_TICK)))
+ f.s = make(chan os.Signal, ice.MOD_CHAN)
+ f.e = make(chan bool, 1)
return f
}
func (f *Frame) Start(m *ice.Message, arg ...string) bool {
for {
select {
- case s, ok := <-f.s:
- if !ok {
- return true
- }
- // 信号事件
- m.Logs(EVENT, SIGNAL, s)
- m.Cmd(m.Confv(SIGNAL, kit.Keys(kit.MDB_HASH, s)), kit.Keys(s))
+ case <-f.e:
+ return true
- case t, ok := <-f.t:
- if !ok {
- return true
- }
+ case s := <-f.s:
+ m.Cmd(SIGNAL, ACTION, SIGNAL, s)
- // 定时事件
- stamp := int(t.Unix())
- m.Confm(TIMER, kit.MDB_HASH, func(key string, value map[string]interface{}) {
- if kit.Int(value["next"]) <= stamp {
- m.Logs(EVENT, TIMER, key, kit.MDB_TIME, value["next"])
- value["next"] = stamp + int(kit.Duration(value["interval"]))/int(time.Second)
- m.Cmd(value["cmd"])
- m.Grow(TIMER, nil, map[string]interface{}{
- "create_time": kit.Format(t), "interval": value["interval"],
- "cmd": value["cmd"], "key": key,
- })
- }
- })
-
- case d, ok := <-f.d:
- if !ok {
- return true
- }
- // 异步事件
- m.Logs(EVENT, d[0], d[1:])
- m.Grows(EVENT, d[0], "", "", func(index int, value map[string]interface{}) {
- m.Cmd(value["cmd"], d).Cost("event %v", d)
- })
+ case <-f.t:
+ _timer_action(m.Spawn())
}
}
return true
@@ -73,147 +45,37 @@ func (f *Frame) Close(m *ice.Message, arg ...string) bool {
}
const (
- SYSTEM_INIT = "system.init"
-
- SERVE_START = "serve.start"
- SERVE_CLOSE = "serve.close"
- SPACE_START = "space.start"
- SPACE_CLOSE = "space.close"
- DREAM_START = "dream.start"
- DREAM_CLOSE = "dream.close"
-
- USER_CREATE = "user.create"
- CHAT_CREATE = "chat.create"
- MISS_CREATE = "miss.create"
- MIND_CREATE = "mind.create"
-)
-
-const (
- INIT = "init"
- AUTO = "auto"
- MAKE = "make"
-
BEGIN = "begin"
END = "end"
- OPEN = "open"
- CLOSE = "close"
+
START = "start"
STOP = "stop"
RESTART = "restart"
)
-const (
- LISTEN = "listen"
- ACTION = "action"
-)
-const (
- ROUTINE = "routine"
- SIGNAL = "signal"
- TIMER = "timer"
- EVENT = "event"
- DEBUG = "debug"
-)
+const GDB = "gdb"
-var Index = &ice.Context{Name: "gdb", Help: "事件模块",
- Configs: map[string]*ice.Config{
- ROUTINE: {Name: "routine", Help: "协程", Value: kit.Data()},
-
- SIGNAL: {Name: "signal", Help: "信号器", Value: kit.Dict(
- kit.MDB_META, kit.Dict("pid", "var/run/ice.pid"),
- kit.MDB_LIST, kit.List(),
- kit.MDB_HASH, kit.Dict(
- "2", []interface{}{"exit", "1"},
- "3", []interface{}{"exit", "0"},
- "15", []interface{}{"exit", "1"},
- // "20", []interface{}{"void"},
- "30", []interface{}{"exit"},
- "31", []interface{}{"exit", "1"},
- // "28", []interface{}{"void"},
- ),
- )},
- TIMER: {Name: "timer", Help: "定时器", Value: kit.Data("tick", "100ms")},
- EVENT: {Name: "event", Help: "触发器", Value: kit.Data()},
- },
+var Index = &ice.Context{Name: GDB, Help: "事件模块",
Commands: map[string]*ice.Command{
ice.CTX_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
- if os.Getenv("ctx_mod") != "" {
- m.Cmd(nfs.SAVE, kit.Select(m.Conf(SIGNAL, "meta.pid"),
- m.Conf(cli.RUNTIME, "conf.ctx_pid")), m.Conf(cli.RUNTIME, "host.pid"))
- }
- // 进程标识
- if f, ok := m.Target().Server().(*Frame); ok {
- // 注册信号
- f.s = make(chan os.Signal, ice.MOD_CHAN)
- m.Richs(SIGNAL, nil, kit.MDB_FOREACH, func(key string, value string) {
- m.Logs(LISTEN, key, value)
- signal.Notify(f.s, syscall.Signal(kit.Int(key)))
- })
- // 启动心跳
- f.t = time.Tick(kit.Duration(m.Cap(ice.CTX_STREAM, m.Conf(TIMER, "meta.tick"))))
- // 分发事件
- f.d = make(chan []string, ice.MOD_CHAN)
- }
+ m.Cmd(nfs.SAVE, kit.Select(m.Conf(SIGNAL, kit.META_PATH), m.Conf(cli.RUNTIME, "conf.ctx_pid")), m.Conf(cli.RUNTIME, "host.pid"))
+
+ m.Cmd(SIGNAL, LISTEN, SIGNAL, "3", kit.MDB_NAME, "退出", kit.SSH_CMD, "exit 0")
+ m.Cmd(SIGNAL, LISTEN, SIGNAL, "2", kit.MDB_NAME, "重启", kit.SSH_CMD, "exit 1")
+ m.Load()
}},
ice.CTX_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
if f, ok := m.Target().Server().(*Frame); ok {
- // 停止心跳
- close(f.s)
- // 停止事件
- close(f.d)
+ f.e <- true
}
+ m.Save(TIMER)
}},
-
- ROUTINE: {Name: "routine hash auto", Help: "协程", Action: map[string]*ice.Action{
- mdb.CREATE: {Name: "create", Help: "创建", Hand: func(m *ice.Message, arg ...string) {
- m.Cmdy(mdb.INSERT, ROUTINE, "", mdb.LIST, arg)
- }},
- }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
- m.Option(mdb.FIELDS, "time,fileline")
- m.Cmdy(mdb.SELECT, ROUTINE, "", mdb.LIST, arg)
- }},
-
- SIGNAL: {Name: "signal", Help: "信号器", Action: map[string]*ice.Action{
- LISTEN: {Name: "listen signal cmd...", Help: "监听事件", Hand: func(m *ice.Message, arg ...string) {
- m.Rich(SIGNAL, arg[0], arg[1:])
- }},
- }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {}},
-
- TIMER: {Name: "timer", Help: "定时器", Action: map[string]*ice.Action{
- LISTEN: {Name: "listen delay interval cmd...", Help: "监听事件", Hand: func(m *ice.Message, arg ...string) {
- m.Rich(TIMER, nil, kit.Dict(
- "next", time.Now().Add(kit.Duration(arg[0])).Unix(),
- "interval", arg[1], "cmd", arg[2:],
- ))
- }},
- }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {}},
-
- EVENT: {Name: "event", Help: "触发器", Action: map[string]*ice.Action{
- LISTEN: {Name: "listen event cmd...", Help: "监听事件", Hand: func(m *ice.Message, arg ...string) {
- m.Grow(EVENT, arg[0], kit.Dict("cmd", arg[1:]))
- m.Logs(LISTEN, arg[0], arg[1:])
- }},
- ACTION: {Name: "action event arg...", Help: "触发事件", Hand: func(m *ice.Message, arg ...string) {
- if f, ok := m.Target().Server().(*Frame); ok {
- m.Logs(ACTION, arg[0], arg[1:])
- f.d <- arg
- }
- }},
- }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {}},
-
- DEBUG: {Name: "debug", Help: "调试器", Action: map[string]*ice.Action{
- LISTEN: {Name: "listen event cmd...", Help: "监听事件", Hand: func(m *ice.Message, arg ...string) {
- m.Grow(EVENT, arg[0], kit.Dict("cmd", arg[1:]))
- m.Logs(LISTEN, arg[0], "cmd", arg[1:])
- }},
- ACTION: {Name: "action event arg...", Help: "触发事件", Hand: func(m *ice.Message, arg ...string) {
- if f, ok := m.Target().Server().(*Frame); ok {
- m.Logs(ACTION, arg[0], "arg", arg[1:])
- f.d <- arg
- }
- }},
- }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {}},
},
}
-func init() { ice.Index.Register(Index, &Frame{}, SIGNAL, TIMER, EVENT, DEBUG) }
+func init() {
+ ice.Index.Register(Index, &Frame{},
+ ROUTINE, SIGNAL, EVENT, TIMER,
+ )
+}
diff --git a/base/gdb/gdb.shy b/base/gdb/gdb.shy
new file mode 100644
index 00000000..93a014a8
--- /dev/null
+++ b/base/gdb/gdb.shy
@@ -0,0 +1,7 @@
+chapter "gdb"
+
+field "协程池" routine
+field "信号量" signal
+field "事件流" event
+
+field "定时器" timer
diff --git a/base/gdb/routine.go b/base/gdb/routine.go
new file mode 100644
index 00000000..6fe9de32
--- /dev/null
+++ b/base/gdb/routine.go
@@ -0,0 +1,61 @@
+package gdb
+
+import (
+ ice "github.com/shylinux/icebergs"
+ "github.com/shylinux/icebergs/base/mdb"
+ kit "github.com/shylinux/toolkits"
+
+ "strings"
+)
+
+const (
+ INNER = "inner"
+)
+const ROUTINE = "routine"
+
+func init() {
+ Index.Merge(&ice.Context{
+ Configs: map[string]*ice.Config{
+ ROUTINE: {Name: ROUTINE, Help: "协程池", Value: kit.Data()},
+ },
+ Commands: map[string]*ice.Command{
+ ROUTINE: {Name: "routine hash auto 清理", Help: "协程池", Action: map[string]*ice.Action{
+ mdb.CREATE: {Name: "create fileline status", Help: "创建", Hand: func(m *ice.Message, arg ...string) {
+ m.Cmdy(mdb.INSERT, ROUTINE, "", mdb.HASH, arg)
+ }},
+ mdb.MODIFY: {Name: "modify", Help: "编辑", Hand: func(m *ice.Message, arg ...string) {
+ m.Cmdy(mdb.MODIFY, ROUTINE, "", mdb.HASH, kit.MDB_HASH, m.Option(kit.MDB_HASH), arg)
+ }},
+ mdb.REMOVE: {Name: "remove", Help: "删除", Hand: func(m *ice.Message, arg ...string) {
+ m.Cmdy(mdb.DELETE, ROUTINE, "", mdb.HASH, kit.MDB_HASH, m.Option(kit.MDB_HASH))
+ }},
+ mdb.PRUNES: {Name: "prunes", Help: "清理", Hand: func(m *ice.Message, arg ...string) {
+ m.Option(mdb.FIELDS, "time,hash,status,fileline")
+ m.Cmdy(mdb.PRUNES, ROUTINE, "", mdb.HASH, kit.MDB_STATUS, STOP)
+ }},
+
+ INNER: {Name: "inner", Help: "源码", Hand: func(m *ice.Message, arg ...string) {
+ switch kit.Select("", arg, 0) {
+ case kit.SSH_RUN:
+ m.Cmdy(INNER, arg[1:])
+ default:
+ ls := kit.Split(m.Option("fileline"), ":")
+ switch kit.Split(ls[0], "/")[0] {
+ case "usr":
+ ls[0] = strings.TrimPrefix(ls[0], "usr/icebergs/")
+ case "icebergs":
+ ls[0] = strings.TrimPrefix(ls[0], "icebergs/")
+ }
+
+ m.PushPlugin(INNER, INNER, kit.SSH_RUN)
+ m.Push("args", kit.Format([]string{"usr/icebergs/", ls[0], ls[1]}))
+ }
+ }},
+ }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
+ m.Option(mdb.FIELDS, kit.Select("time,hash,status,fileline", mdb.DETAIL, len(arg) > 0))
+ m.Cmdy(mdb.SELECT, ROUTINE, "", mdb.HASH, kit.MDB_HASH, arg)
+ m.PushAction(INNER, mdb.REMOVE)
+ }},
+ },
+ }, nil)
+}
diff --git a/base/gdb/signal.go b/base/gdb/signal.go
new file mode 100644
index 00000000..09fed6fe
--- /dev/null
+++ b/base/gdb/signal.go
@@ -0,0 +1,58 @@
+package gdb
+
+import (
+ ice "github.com/shylinux/icebergs"
+ "github.com/shylinux/icebergs/base/mdb"
+ kit "github.com/shylinux/toolkits"
+
+ "os/signal"
+ "syscall"
+)
+
+func _signal_listen(m *ice.Message, s int, arg ...string) {
+ if f, ok := m.Target().Server().(*Frame); ok {
+ m.Cmdy(mdb.INSERT, SIGNAL, "", mdb.HASH, arg)
+ signal.Notify(f.s, syscall.Signal(s))
+ }
+}
+func _signal_action(m *ice.Message, s int) {
+ m.Option(mdb.FIELDS, "time,signal,name,cmd")
+ msg := m.Cmd(mdb.SELECT, SIGNAL, "", mdb.HASH, SIGNAL, s)
+ msg.Table(func(index int, value map[string]string, head []string) {
+ m.Cmdy(kit.Split(value[kit.SSH_CMD]))
+ })
+}
+
+const (
+ LISTEN = "listen"
+ ACTION = "action"
+)
+const SIGNAL = "signal"
+
+func init() {
+ Index.Merge(&ice.Context{
+ Configs: map[string]*ice.Config{
+ SIGNAL: {Name: SIGNAL, Help: "信号器", Value: kit.Data(
+ kit.MDB_PATH, "var/run/ice.pid", kit.MDB_SHORT, SIGNAL,
+ )},
+ },
+ Commands: map[string]*ice.Command{
+ SIGNAL: {Name: "signal auto 监听", Help: "信号器", Action: map[string]*ice.Action{
+ LISTEN: {Name: "listen signal name cmd", Help: "监听", Hand: func(m *ice.Message, arg ...string) {
+ _signal_listen(m, kit.Int(m.Option(SIGNAL)), arg...)
+ }},
+ ACTION: {Name: "action signal", Help: "触发", Hand: func(m *ice.Message, arg ...string) {
+ _signal_action(m, kit.Int(m.Option(SIGNAL)))
+ }},
+ mdb.REMOVE: {Name: "remove", Help: "删除", Hand: func(m *ice.Message, arg ...string) {
+ m.Cmdy(mdb.DELETE, SIGNAL, "", mdb.HASH, SIGNAL, m.Option(SIGNAL))
+ }},
+ }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
+ m.Option(mdb.FIELDS, "time,signal,name,cmd")
+ m.Cmdy(mdb.SELECT, SIGNAL, "", mdb.HASH, SIGNAL, arg)
+ m.PushAction(ACTION, mdb.REMOVE)
+ m.Sort(SIGNAL)
+ }},
+ },
+ }, nil)
+}
diff --git a/base/gdb/timer.go b/base/gdb/timer.go
new file mode 100644
index 00000000..6099fd48
--- /dev/null
+++ b/base/gdb/timer.go
@@ -0,0 +1,76 @@
+package gdb
+
+import (
+ ice "github.com/shylinux/icebergs"
+ "github.com/shylinux/icebergs/base/mdb"
+ kit "github.com/shylinux/toolkits"
+
+ "time"
+)
+
+func _timer_create(m *ice.Message, arg ...string) {
+ m.Cmdy(mdb.INSERT, TIMER, "", mdb.HASH, "delay", "10ms", "interval", "10m", "order", 1, "next", m.Time(m.Option("delay")), arg)
+}
+func _timer_action(m *ice.Message, arg ...string) {
+ now := time.Now().UnixNano()
+ m.Option(mdb.FIELDS, "time,hash,delay,interval,order,next,cmd")
+
+ m.Richs(TIMER, "", kit.MDB_FOREACH, func(key string, value map[string]interface{}) {
+ if value = kit.GetMeta(value); value[kit.MDB_STATUS] == STOP {
+ return
+ }
+
+ order := kit.Int(value["order"])
+ if n := kit.Time(kit.Format(value["next"])); now > n && order > 0 {
+ m.Logs(TIMER, "key", key, "order", order)
+
+ msg := m.Cmd(value[kit.SSH_CMD])
+ m.Grow(TIMER, kit.Keys(kit.MDB_HASH, key), kit.Dict("res", msg.Result()))
+ if value["order"] = kit.Format(order - 1); order > 1 {
+ value["next"] = msg.Time(value["interval"])
+ }
+ }
+ })
+}
+
+const TIMER = "timer"
+
+func init() {
+ Index.Merge(&ice.Context{
+ Configs: map[string]*ice.Config{
+ TIMER: {Name: TIMER, Help: "定时器", Value: kit.Data("tick", "100ms")},
+ },
+ Commands: map[string]*ice.Command{
+ TIMER: {Name: "timer hash id auto 添加 清理", Help: "定时器", Action: map[string]*ice.Action{
+ mdb.CREATE: {Name: "create delay=10ms interval=10s order=3 cmd=runtime", Help: "添加", Hand: func(m *ice.Message, arg ...string) {
+ _timer_create(m, arg...)
+ }},
+ mdb.MODIFY: {Name: "modify", Help: "编辑", Hand: func(m *ice.Message, arg ...string) {
+ m.Cmdy(mdb.MODIFY, TIMER, "", mdb.HASH, kit.MDB_HASH, m.Option(kit.MDB_HASH), arg)
+ }},
+ mdb.REMOVE: {Name: "remove", Help: "删除", Hand: func(m *ice.Message, arg ...string) {
+ m.Cmdy(mdb.DELETE, TIMER, "", mdb.HASH, kit.MDB_HASH, m.Option(kit.MDB_HASH))
+ }},
+ mdb.PRUNES: {Name: "prunes", Help: "清理", Hand: func(m *ice.Message, arg ...string) {
+ m.Option(mdb.FIELDS, "time,hash,delay,interval,order,next,cmd")
+ m.Cmdy(mdb.PRUNES, TIMER, "", mdb.HASH, "order", 0)
+ }},
+
+ ACTION: {Name: "action", Help: "执行", Hand: func(m *ice.Message, arg ...string) {
+ _timer_action(m, arg...)
+ }},
+ }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
+ if len(arg) == 0 {
+ m.Option(mdb.FIELDS, kit.Select("time,hash,delay,interval,order,next,cmd", mdb.DETAIL, len(arg) > 0))
+ m.Cmdy(mdb.SELECT, TIMER, "", mdb.HASH, kit.MDB_HASH, arg)
+ m.PushAction(mdb.REMOVE)
+ return
+ }
+
+ m.Option(mdb.FIELDS, kit.Select("time,id,res", mdb.DETAIL, len(arg) > 1))
+ m.Cmdy(mdb.SELECT, TIMER, kit.Keys(kit.MDB_HASH, arg[0]), mdb.LIST, kit.MDB_ID, arg[1:])
+ return
+ }},
+ },
+ }, nil)
+}
diff --git a/base/mdb/mdb.go b/base/mdb/mdb.go
index 8760668a..7cb14121 100644
--- a/base/mdb/mdb.go
+++ b/base/mdb/mdb.go
@@ -9,8 +9,12 @@ import (
"os"
"path"
"sort"
+ "strings"
)
+func _fields(m *ice.Message) []string {
+ return kit.Split(kit.Select("time,hash,type,name,text", strings.Join(kit.Simple(m.Optionv(FIELDS)), ",")))
+}
func _file_name(m *ice.Message, arg ...string) string {
return kit.Select(path.Join("usr/export", path.Join(arg[:2]...)), arg, 3)
}
@@ -29,7 +33,7 @@ func _hash_select(m *ice.Message, prefix, chain, field, value string) {
if field == kit.MDB_HASH && value == RANDOM {
value = kit.MDB_RANDOMS
}
- fields := kit.Split(kit.Select("time,hash,type,name,text", m.Option(FIELDS)))
+ fields := _fields(m)
m.Richs(prefix, chain, value, func(key string, val map[string]interface{}) {
if val[kit.MDB_META] != nil {
val = val[kit.MDB_META].(map[string]interface{})
diff --git a/base/ssh/scripts.go b/base/ssh/scripts.go
index 7ef55b73..ba514dc0 100644
--- a/base/ssh/scripts.go
+++ b/base/ssh/scripts.go
@@ -17,60 +17,6 @@ import (
"time"
)
-type item struct {
- c chan []byte
- last []byte
-}
-
-func (i item) Read(buf []byte) (int, error) {
- b := <-i.c
- n := copy(buf, b)
- return n, nil
-}
-
-type tmux struct {
- input io.Reader
- waits []chan []byte
-}
-
-func (t *tmux) get() *item {
- c := make(chan []byte)
- t.waits = append(t.waits, c)
- return &item{c: c}
-}
-func (t *tmux) loop() {
- buf := make([]byte, 1024)
- for {
- n, e := t.input.Read(buf)
- if e != nil {
- break
- }
- if len(t.waits) > 0 {
- wait := t.waits[len(t.waits)-1]
- wait <- buf[:n]
- }
- }
-}
-func (t *tmux) read(cb func(buf []byte)) {
- c := make(chan []byte)
- t.waits = append(t.waits, c)
- go func() {
- for {
- cb(<-c)
- }
- }()
- return
-}
-func (t *tmux) over() {
- if len(t.waits) > 0 {
- t.waits = t.waits[:len(t.waits)-1]
- }
-}
-
-var stdin = &tmux{input: os.Stdin}
-
-func init() { go stdin.loop() }
-
func Render(msg *ice.Message, cmd string, args ...interface{}) {
defer func() { msg.Log_EXPORT(mdb.RENDER, cmd, kit.MDB_TEXT, args) }()
@@ -287,7 +233,6 @@ func (f *Frame) scan(m *ice.Message, h, line string, r io.Reader) *Frame {
f.ps2 = kit.Simple(m.Confv("prompt", "meta.PS2"))
ps := f.ps1
- f.count = 1
m.I, m.O = r, f.stdout
bio := bufio.NewScanner(r)
for f.prompt(m, ps...); bio.Scan() && !f.exit; f.prompt(m, ps...) {
@@ -295,6 +240,9 @@ func (f *Frame) scan(m *ice.Message, h, line string, r io.Reader) *Frame {
f.count++
if len(bio.Text()) == 0 {
+ if h == STDIO {
+ f.count--
+ }
continue // 空行
}
if strings.HasSuffix(bio.Text(), "\\") {
@@ -332,8 +280,7 @@ func (f *Frame) Start(m *ice.Message, arg ...string) bool {
var r io.Reader
switch m.Cap(ice.CTX_STREAM, f.source) {
case STDIO: // 终端交互
- // r, f.stdout = os.Stdin, os.Stdout
- r, f.stdout = stdin.get(), os.Stdout
+ r, f.stdout = os.Stdin, os.Stdout
m.Option("_option", ice.MSG_USERNAME)
m.Option(ice.MSG_USERNAME, cli.UserName)
@@ -359,7 +306,8 @@ func (f *Frame) Start(m *ice.Message, arg ...string) bool {
return true
}
- if f.source == STDIO {
+ if f.count = 1; f.source == STDIO {
+ f.count = kit.Int(m.Conf(SOURCE, "hash.stdio.meta.count")) + 1
f.scan(m, STDIO, "", r)
} else {
h := m.Cmdx(mdb.INSERT, SOURCE, "", mdb.HASH, kit.MDB_NAME, f.source)
diff --git a/base/ssh/service.go b/base/ssh/service.go
index f166acb8..54550141 100644
--- a/base/ssh/service.go
+++ b/base/ssh/service.go
@@ -201,11 +201,22 @@ func init() {
mdb.PRUNES: {Name: "prunes", Help: "清理", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(mdb.PRUNES, SERVICE, "", mdb.HASH, kit.MDB_STATUS, tcp.CLOSE)
}},
+ mdb.INVITE: {Name: "invite", Help: "邀请", Hand: func(m *ice.Message, arg ...string) {
+ u := kit.ParseURL(m.Option(ice.MSG_USERWEB))
+ m.Option("hostname", strings.Split(u.Host, ":")[0])
+
+ m.Option("_process", "_inner")
+ if buf, err := kit.Render(`
+ssh {{.Option "user.name"}}@{{.Option "hostname"}} -p {{.Option "port"}}
+`, m); err == nil {
+ m.Cmdy("web.wiki.spark", "shell", string(buf))
+ }
+ }},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
if len(arg) == 0 {
m.Option(mdb.FIELDS, "time,status,port,private,auth,count")
m.Cmdy(mdb.SELECT, SERVICE, "", mdb.HASH)
- m.PushAction("导入,添加,导出")
+ m.PushAction(mdb.IMPORT, mdb.INSERT, mdb.EXPORT, mdb.INVITE)
return
}
diff --git a/base/ssh/session.go b/base/ssh/session.go
index 4a6f3145..d0d6ef03 100644
--- a/base/ssh/session.go
+++ b/base/ssh/session.go
@@ -95,9 +95,8 @@ func init() {
value = kit.GetMeta(value)
input := value["input"].(io.Writer)
- stdin.read(func(buf []byte) {
+ _watch(m, os.Stdin, input, func(buf []byte) {
m.Debug("input %v", string(buf))
- input.Write(buf)
})
output := value["output"].(io.Reader)
diff --git a/base/web/serve.go b/base/web/serve.go
index 0007e5c3..d2a2b012 100644
--- a/base/web/serve.go
+++ b/base/web/serve.go
@@ -17,6 +17,10 @@ import (
)
const LOGIN = "_login"
+const (
+ SERVE_START = "serve.start"
+ SERVE_CLOSE = "serve.close"
+)
func _serve_login(msg *ice.Message, cmds []string, w http.ResponseWriter, r *http.Request) ([]string, bool) {
msg.Option(ice.MSG_USERNAME, "")
diff --git a/base/web/web.go b/base/web/web.go
index 9fbc5d2a..b897fde5 100644
--- a/base/web/web.go
+++ b/base/web/web.go
@@ -5,7 +5,6 @@ import (
"github.com/shylinux/icebergs/base/aaa"
"github.com/shylinux/icebergs/base/cli"
"github.com/shylinux/icebergs/base/ctx"
- "github.com/shylinux/icebergs/base/gdb"
"github.com/shylinux/icebergs/base/mdb"
"github.com/shylinux/icebergs/base/tcp"
kit "github.com/shylinux/toolkits"
@@ -78,9 +77,9 @@ func (web *Frame) Start(m *ice.Message, arg ...string) bool {
web.m, web.Server = m, &http.Server{Handler: web}
m.Option(tcp.LISTEN_CB, func(l net.Listener) {
- m.Event(gdb.SERVE_START, arg[0])
+ m.Event(SERVE_START, arg[0])
m.Warn(true, "listen %s", web.Server.Serve(l))
- m.Event(gdb.SERVE_CLOSE, arg[0])
+ m.Event(SERVE_CLOSE, arg[0])
})
ls := strings.Split(m.Cap(ice.CTX_STREAM, client["hostname"]), ":")
diff --git a/conf.go b/conf.go
index 0307df4e..c4b1027d 100644
--- a/conf.go
+++ b/conf.go
@@ -5,6 +5,7 @@ const ( //MOD
MOD_FILE = 0640
MOD_CHAN = 16
+ MOD_TICK = "1s"
MOD_BUF = 1024
MOD_DATE = "2006-01-02"
diff --git a/exec.go b/exec.go
index ef91ddbc..eda66af4 100644
--- a/exec.go
+++ b/exec.go
@@ -109,11 +109,11 @@ func (m *Message) Back(res *Message) *Message {
}
return m
}
-func (m *Message) Gos(msg *Message, cb interface{}) *Message {
- m.Cmd("gdb.routine", "create", "fileline", kit.FileLine(cb, 3))
-
- task.Put(nil, func(task *task.Task) error {
+func (m *Message) Gos(msg *Message, cb interface{}, args ...interface{}) *Message {
+ task.Put(m.Cmdx("gdb.routine", "create", "fileline", kit.FileLine(cb, 3), "status", "start"), func(task *task.Task) error {
+ msg.Optionv("task.hash", task.Arg)
msg.Optionv("_task", task)
+
msg.TryCatch(msg, true, func(msg *Message) {
switch cb := cb.(type) {
case func(*Message):
@@ -122,16 +122,17 @@ func (m *Message) Gos(msg *Message, cb interface{}) *Message {
cb()
}
})
+
+ msg.Option(kit.MDB_HASH, task.Arg)
+ msg.Cmdx("gdb.routine", "modify", "status", "stop")
return nil
})
return m
}
-func (m *Message) Go(cb interface{}) *Message {
+func (m *Message) Go(cb interface{}, args ...interface{}) *Message {
switch cb := cb.(type) {
case func(*Message):
- return m.Gos(m.Spawn(), cb)
- case func():
- return m.Gos(m, cb)
+ return m.Gos(m.Spawn(), cb, args...)
}
- return m.Gos(m, cb)
+ return m.Gos(m, cb, args...)
}
diff --git a/go.sum b/go.sum
index e69de29b..7fb84c40 100644
--- a/go.sum
+++ b/go.sum
@@ -0,0 +1,19 @@
+github.com/google/uuid v1.1.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
+github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
+github.com/kr/pty v1.1.1 h1:VkoXIwSboBpnk99O/KFauAEILuNHv5DVFKZMBN/gUgw=
+github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
+github.com/maruel/rs v0.0.0-20150922171536-2c81c4312fe4/go.mod h1:kcRFpEzolcEklV6rD7W95mG49/sbdX/PlFmd7ni3RvA=
+github.com/nareix/joy4 v0.0.0-20200507095837-05a4ffbb5369/go.mod h1:aFJ1ZwLjvHN4yEzE5Bkz8rD8/d8Vlj3UIuvz2yfET7I=
+github.com/shylinux/toolkits v0.1.8 h1:Lh5HkR1aRzhOOVu9eHwZ5y7dfW7hcFy29IR5tQ5qUeM=
+github.com/shylinux/toolkits v0.1.8/go.mod h1:Y68Ot6xOmo1bun67YvqC3chDGeU2gDxtsUnvVDGJm4g=
+github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e h1:MRM5ITcdelLK2j1vwZ3Je0FKVCfqOLp5zO6trqMLYs0=
+github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e/go.mod h1:XV66xRDqSt+GTGFMVlhk3ULuV0y9ZmzeVGR4mloJI3M=
+github.com/tuotoo/qrcode v0.0.0-20190222102259-ac9c44189bf2/go.mod h1:lPnW9HVS0vJdeYyQtOvIvlXgZPNhUAhwz+z5r8AJk0Y=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 h1:ObdrDkeb4kJdCP557AjRjq69pTHfNouLtWZG7j9rPN8=
+golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
diff --git a/misc.go b/misc.go
index 75e974d0..73ca9080 100644
--- a/misc.go
+++ b/misc.go
@@ -37,11 +37,11 @@ func (m *Message) Watch(key string, arg ...string) *Message {
if len(arg) == 0 {
arg = append(arg, m.Prefix("auto"))
}
- m.Cmd("gdb.event", "listen", key, arg)
+ m.Cmd("gdb.event", "listen", "event", key, "cmd", strings.Join(arg, " "))
return m
}
func (m *Message) Event(key string, arg ...string) *Message {
- m.Cmd("gdb.event", "action", key, arg)
+ m.Cmd("gdb.event", "action", "event", key, strings.Join(arg, " "))
return m
}
func (m *Message) Right(arg ...interface{}) bool {
@@ -75,10 +75,8 @@ func (m *Message) PushRender(key, view, name string, arg ...string) *Message {
case "button":
list := []string{}
for _, k := range kit.Split(name) {
- list = append(list, fmt.Sprintf(``, k))
- }
- for _, k := range arg {
- list = append(list, fmt.Sprintf(``, k))
+ list = append(list, fmt.Sprintf(``,
+ k, kit.Select(k, kit.Value(m.cmd.Meta, kit.Keys("trans", k)))))
}
m.Push(key, strings.Join(list, ""))
case "video":
@@ -105,6 +103,12 @@ func (m *Message) PushAction(list ...interface{}) {
func (m *Message) PushButton(key string, arg ...string) {
m.PushRender("action", "button", key, arg...)
}
+func (m *Message) PushPlugin(key string, arg ...string) *Message {
+ m.Option("_process", "_field")
+ m.Option("_prefix", arg)
+ m.Cmdy("command", key)
+ return m
+}
func (m *Message) PushDetail(value interface{}, arg ...interface{}) *Message {
return m.Push("detail", value, arg...)
}
diff --git a/misc/git/repos.go b/misc/git/repos.go
index f87a9dfe..af4d2029 100644
--- a/misc/git/repos.go
+++ b/misc/git/repos.go
@@ -5,7 +5,6 @@ import (
"github.com/shylinux/icebergs/base/cli"
"github.com/shylinux/icebergs/base/mdb"
"github.com/shylinux/icebergs/base/nfs"
- "github.com/shylinux/icebergs/base/web"
kit "github.com/shylinux/toolkits"
"os"
@@ -148,35 +147,37 @@ func init() {
}},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Richs(REPOS, nil, kit.Select(kit.MDB_FOREACH, arg, 0), func(key string, value map[string]interface{}) {
- if m.Option(cli.CMD_DIR, kit.Value(value, "meta.path")); len(arg) > 0 {
- // 更改详情
+ value = kit.GetMeta(value)
+
+ if m.Option(cli.CMD_DIR, value[kit.MDB_PATH]); len(arg) > 0 {
m.Echo(m.Cmdx(cli.SYSTEM, GIT, "diff"))
- return
+ return // 更改详情
}
// 更改列表
for _, v := range strings.Split(strings.TrimSpace(m.Cmdx(cli.SYSTEM, GIT, "status", "-sb")), "\n") {
vs := strings.SplitN(strings.TrimSpace(v), " ", 2)
- m.Push("name", kit.Value(value, "meta.name"))
+ m.Push("name", value[kit.MDB_NAME])
m.Push("tags", vs[0])
m.Push("file", vs[1])
+
list := []string{}
switch vs[0] {
case "##":
if strings.Contains(vs[1], "ahead") {
- list = append(list, m.Cmdx(mdb.RENDER, web.RENDER.Button, "上传"))
+ list = append(list, "上传")
}
default:
if strings.Contains(vs[0], "??") {
- list = append(list, m.Cmdx(mdb.RENDER, web.RENDER.Button, "添加"))
+ list = append(list, "添加")
} else {
- list = append(list, m.Cmdx(mdb.RENDER, web.RENDER.Button, "提交"))
+ list = append(list, "提交")
}
}
- m.Push("action", strings.Join(list, ""))
+ m.PushButton(strings.Join(list, ","))
}
})
- m.Sort("name")
+ m.Sort(kit.MDB_NAME)
}},
},
}, nil)
diff --git a/misc/tmux/tmux.go b/misc/tmux/tmux.go
index 0872984f..4f2135d0 100644
--- a/misc/tmux/tmux.go
+++ b/misc/tmux/tmux.go
@@ -86,22 +86,22 @@ var Index = &ice.Context{Name: TMUX, Help: "工作台",
}
}},
mdb.EXPORT: {Name: "export", Help: "导出", Hand: func(m *ice.Message, arg ...string) {
- m.Conf(BUFFER, mdb.LIST, "")
- m.Conf(BUFFER, kit.Keys(mdb.META, "count"), "0")
+ m.Conf(m.Prefix(BUFFER), mdb.LIST, "")
+ m.Conf(m.Prefix(BUFFER), kit.Keys(mdb.META, "count"), "0")
- m.Cmd(BUFFER).Table(func(index int, value map[string]string, head []string) {
- m.Grow(BUFFER, "", kit.Dict(
+ m.Cmd(m.Prefix(BUFFER)).Table(func(index int, value map[string]string, head []string) {
+ m.Grow(m.Prefix(BUFFER), "", kit.Dict(
"name", value[head[0]], "text", m.Cmdx(cli.SYSTEM, TMUX, "show-buffer", "-b", value[head[0]]),
))
})
m.Cmdy(mdb.EXPORT, m.Prefix(BUFFER), "", mdb.LIST)
}},
mdb.IMPORT: {Name: "import", Help: "导入", Hand: func(m *ice.Message, arg ...string) {
- m.Conf(BUFFER, mdb.LIST, "")
- m.Conf(BUFFER, kit.Keys(mdb.META, "count"), "0")
+ m.Conf(m.Prefix(BUFFER), mdb.LIST, "")
+ m.Conf(m.Prefix(BUFFER), kit.Keys(mdb.META, "count"), "0")
m.Cmdy(mdb.IMPORT, m.Prefix(BUFFER), "", mdb.LIST)
- m.Grows(BUFFER, "", "", "", func(index int, value map[string]interface{}) {
+ m.Grows(m.Prefix(BUFFER), "", "", "", func(index int, value map[string]interface{}) {
m.Cmd(cli.SYSTEM, TMUX, "set-buffer", "-b", value["name"], value["text"])
})
}},
@@ -145,7 +145,7 @@ var Index = &ice.Context{Name: TMUX, Help: "工作台",
m.Cmdy(mdb.IMPORT, m.Prefix(SCRIPT), "", mdb.HASH)
}},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
- if m.Option(mdb.FIELDS, m.Conf(SCRIPT, kit.META_FIELD)); len(arg) > 0 {
+ if m.Option(mdb.FIELDS, m.Conf(m.Prefix(SCRIPT), kit.META_FIELD)); len(arg) > 0 {
m.Option(mdb.FIELDS, mdb.DETAIL)
}
m.Cmdy(mdb.SELECT, m.Prefix(SCRIPT), "", mdb.HASH, kit.MDB_NAME, arg)
@@ -232,13 +232,13 @@ var Index = &ice.Context{Name: TMUX, Help: "工作台",
if len(arg) == 0 {
// 会话列表
- m.Split(m.Cmdx(cli.SYSTEM, TMUX, "list-session", "-F", m.Conf(cmd, "meta.format")), m.Conf(cmd, "meta.fields"), ",", "\n")
+ m.Split(m.Cmdx(cli.SYSTEM, TMUX, "list-session", "-F", m.Conf(m.Prefix(cmd), "meta.format")), m.Conf(m.Prefix(cmd), "meta.fields"), ",", "\n")
m.Table(func(index int, value map[string]string, head []string) {
switch value["tag"] {
case "1":
- m.PushRender("action", "button", "")
+ m.PushButton("")
default:
- m.PushRender("action", "button", "进入", "删除")
+ m.PushButton("进入", "删除")
}
})
return
@@ -260,11 +260,11 @@ var Index = &ice.Context{Name: TMUX, Help: "工作台",
}},
WINDOW: {Name: "windows", Help: "窗口", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Split(m.Cmdx(cli.SYSTEM, TMUX, "list-windows", "-t", kit.Select("", arg, 0),
- "-F", m.Conf(cmd, "meta.format")), m.Conf(cmd, "meta.fields"), ",", "\n")
+ "-F", m.Conf(m.Prefix(cmd), "meta.format")), m.Conf(m.Prefix(cmd), "meta.fields"), ",", "\n")
}},
PANE: {Name: "panes", Help: "终端", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Split(m.Cmdx(cli.SYSTEM, TMUX, "list-panes", "-t", kit.Select("", arg, 0),
- "-F", m.Conf(cmd, "meta.format")), m.Conf(cmd, "meta.fields"), ",", "\n")
+ "-F", m.Conf(m.Prefix(cmd), "meta.format")), m.Conf(m.Prefix(cmd), "meta.fields"), ",", "\n")
}},
VIEW: {Name: "view", Help: "终端", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Cmdy(cli.SYSTEM, TMUX, "capture-pane", "-pt", kit.Select("", arg, 0)).Set(ice.MSG_APPEND)
diff --git a/type.go b/type.go
index dc4150f1..720d5603 100644
--- a/type.go
+++ b/type.go
@@ -87,7 +87,7 @@ func (c *Context) _hand(m *Message, cmd *Command, key string, k string, h *Actio
for _, v := range h.List {
name := kit.Format(kit.Value(v, "name"))
value := kit.Format(kit.Value(v, "value"))
- m.Option(name, value)
+ m.Option(name, kit.Select("", value, !strings.HasPrefix(value, "@")))
}
for i := 0; i < len(arg)-1; i += 2 {
m.Option(arg[i], arg[i+1])
@@ -101,6 +101,7 @@ func (c *Context) cmd(m *Message, cmd *Command, key string, arg ...string) *Mess
return m
}
+ m.cmd = cmd
if m.Hand = true; len(arg) > 1 && arg[0] == "action" && cmd.Action != nil {
if h, ok := cmd.Action[arg[1]]; ok {
return c._hand(m, cmd, key, arg[1], h, arg[2:]...)
@@ -176,6 +177,7 @@ func (c *Context) Merge(s *Context, x Server) *Context {
}
for k, a := range v.Action {
+ kit.Value(v.Meta, kit.Keys("trans", k), a.Help)
if a.List == nil {
a.List = c._split(a.Name)
}
@@ -287,7 +289,13 @@ func (c *Context) Start(m *Message, arg ...string) bool {
m.Hold(1)
wait := make(chan bool)
- m.Gos(m, func(m *Message) {
+
+ var p interface{}
+ if c.server != nil {
+ p = c.server.Start
+ }
+
+ m.Go(func() {
m.Log(LOG_START, c.Cap(CTX_FOLLOW))
c.Cap(CTX_STATUS, CTX_START)
@@ -298,7 +306,7 @@ func (c *Context) Start(m *Message, arg ...string) bool {
if m.Done(); m.wait != nil {
m.wait <- true
}
- })
+ }, p)
<-wait
return true
}
@@ -327,6 +335,7 @@ type Message struct {
source *Context
target *Context
+ cmd *Command
cb func(*Message) *Message
W http.ResponseWriter