1
0
forked from x/icebergs

add space

This commit is contained in:
shaoying 2020-06-03 19:12:01 +08:00
parent 4971e6989f
commit 7300877d62
6 changed files with 120 additions and 200 deletions

View File

@ -14,6 +14,54 @@ import (
"strings"
)
func _system_run(m *ice.Message, cmd *exec.Cmd) {
out := bytes.NewBuffer(make([]byte, 0, 1024))
err := bytes.NewBuffer(make([]byte, 0, 1024))
cmd.Stdout = out
cmd.Stderr = err
if e := cmd.Run(); e != nil {
m.Warn(e != nil, "%v run: %s", nil, kit.Select(e.Error(), err.String()))
} else {
m.Cost("%v exit: %v", nil, cmd.ProcessState.ExitCode())
}
m.Push("code", int(cmd.ProcessState.ExitCode()))
m.Echo(out.String())
}
func _daemon_run(m *ice.Message, cmd *exec.Cmd, out, err string) {
if out != "" {
if f, p, e := kit.Create(out); m.Assert(e) {
m.Log_EXPORT("stdout", p)
cmd.Stdout = f
cmd.Stderr = f
}
}
if err != "" {
if f, p, e := kit.Create(err); m.Assert(e) {
m.Log_EXPORT("stderr", p)
cmd.Stderr = f
}
}
cmd.Env = append(cmd.Env, fmt.Sprintf("PATH=%s", os.Getenv("PATH")))
if e := cmd.Start(); m.Warn(e != nil, "%v start: %s", cmd.Args, e) {
return
}
m.Rich("daemon", nil, kit.Dict(kit.MDB_NAME, cmd.Process.Pid, "status", "running"))
m.Echo("%d", cmd.Process.Pid)
m.Gos(m, func(m *ice.Message) {
if e := cmd.Wait(); e != nil {
m.Warn(e != nil, "%v wait: %s", cmd.Args, e)
} else {
m.Cost("%v exit: %v", cmd.Args, cmd.ProcessState.ExitCode())
m.Rich("daemon", nil, func(key string, value map[string]interface{}) {
value["status"] = "exited"
})
}
})
}
var Index = &ice.Context{Name: "cli", Help: "命令模块",
Caches: map[string]*ice.Cache{},
Configs: map[string]*ice.Config{
@ -91,56 +139,12 @@ var Index = &ice.Context{Name: "cli", Help: "命令模块",
if len(cmd.Env) > 0 {
m.Info("env: %s", cmd.Env)
}
if m.Option("cmd_stdout") != "" {
if f, p, e := kit.Create(m.Option("cmd_stdout")); m.Assert(e) {
m.Info("stdout: %s", p)
cmd.Stdout = f
cmd.Stderr = f
}
}
if m.Option("cmd_stderr") != "" {
if f, p, e := kit.Create(m.Option("cmd_stderr")); m.Assert(e) {
m.Info("stderr: %s", p)
cmd.Stderr = f
}
}
switch m.Option("cmd_type") {
case "daemon":
// 守护进程
cmd.Env = append(cmd.Env, fmt.Sprintf("PATH=%s", os.Getenv("PATH")))
if e := cmd.Start(); e != nil {
m.Warn(e != nil, "%v start: %s", arg, e)
return
}
m.Rich("daemon", nil, kit.Dict(kit.MDB_NAME, cmd.Process.Pid, "status", "running"))
m.Echo("%d", cmd.Process.Pid)
m.Gos(m, func(m *ice.Message) {
if e := cmd.Wait(); e != nil {
m.Warn(e != nil, "%v wait: %s", arg, e)
} else {
m.Cost("%v exit: %v", arg, cmd.ProcessState.ExitCode())
m.Rich("daemon", nil, func(key string, value map[string]interface{}) {
value["status"] = "exited"
})
}
})
_daemon_run(m, cmd, m.Option("cmd_stdout"), m.Option("cmd_stderr"))
default:
// 系统命令
out := bytes.NewBuffer(make([]byte, 0, 1024))
err := bytes.NewBuffer(make([]byte, 0, 1024))
cmd.Stdout = out
cmd.Stderr = err
if e := cmd.Run(); e != nil {
m.Warn(e != nil, "%v run: %s", arg, kit.Select(e.Error(), err.String()))
} else {
m.Cost("%v exit: %v", arg, cmd.ProcessState.ExitCode())
}
m.Push("code", int(cmd.ProcessState.ExitCode()))
m.Echo(out.String())
_system_run(m, cmd)
}
}},
ice.CLI_DAEMON: {Name: "daemon", Help: "守护进程", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {

View File

@ -9,6 +9,59 @@ import (
"os"
)
var FAVOR = ice.Name("favor", Index)
func _favor_list(m *ice.Message, favor, id string, fields ...string) {
if favor == "" {
m.Richs(FAVOR, nil, "*", func(key string, value map[string]interface{}) {
m.Push(key, value["meta"], []string{"time", "count"})
m.Push("render", kit.Select("spide", kit.Value(value, "meta.render")))
m.Push(FAVOR, kit.Value(value, "meta.name"))
})
m.Sort(FAVOR)
return
}
m.Richs(ice.WEB_FAVOR, nil, favor, func(key string, value map[string]interface{}) {
if id == "" {
m.Grows(ice.WEB_FAVOR, kit.Keys(kit.MDB_HASH, key), "", "", func(index int, value map[string]interface{}) {
m.Push("", value, fields)
})
return
}
m.Grows(ice.WEB_FAVOR, kit.Keys(kit.MDB_HASH, key), "id", id, func(index int, value map[string]interface{}) {
m.Push("detail", value)
m.Optionv("value", value)
m.Push("key", "render")
m.Push("value", m.Cmdx(m.Conf(ice.WEB_FAVOR, kit.Keys("meta.render", value["type"]))))
})
})
}
func _favor_create(m *ice.Message, name string) string {
favor := m.Rich(ice.WEB_FAVOR, nil, kit.Data(kit.MDB_NAME, name))
m.Log_CREATE("favor", favor, "name", favor)
return favor
}
func _favor_insert(m *ice.Message, favor, kind, name, text string, extra ...string) {
index := m.Grow(ice.WEB_FAVOR, kit.Keys(kit.MDB_HASH, favor), kit.Dict(
kit.MDB_TYPE, kind, kit.MDB_NAME, name, kit.MDB_TEXT, text,
"extra", kit.Dict(extra),
))
m.Richs(ice.WEB_FAVOR, nil, favor, func(key string, value map[string]interface{}) {
kit.Value(value, "meta.time", m.Time())
})
m.Log_INSERT("favor", favor, "index", index, "name", name, "text", text)
m.Echo("%d", index)
}
func FavorInsert(m *ice.Message, favor, kind, name, text string, extra ...string) {
_favor_insert(m, favor, kind, name, text, extra...)
}
func FavorList(m *ice.Message, favor, id string, fields ...string) {
_favor_list(m, favor, id, fields...)
}
func init() {
Index.Merge(&ice.Context{
Configs: map[string]*ice.Config{
@ -78,13 +131,7 @@ func init() {
}
if len(arg) == 0 {
// 收藏门类
m.Richs(ice.WEB_FAVOR, nil, "*", func(key string, value map[string]interface{}) {
m.Push(key, value["meta"], []string{"time", "count"})
m.Push("render", kit.Select("spide", kit.Value(value, "meta.render")))
m.Push("favor", kit.Value(value, "meta.name"))
})
m.Sort("favor")
_favor_list(m, "", "")
return
}
@ -162,27 +209,13 @@ func init() {
}
m.Option("favor", arg[0])
fields := []string{kit.MDB_TIME, kit.MDB_ID, kit.MDB_TYPE, kit.MDB_NAME, kit.MDB_TEXT}
if len(arg) > 1 && arg[1] == "extra" {
fields, arg = append(fields, arg[2:]...), arg[:1]
}
if len(arg) < 3 {
m.Richs(ice.WEB_FAVOR, nil, arg[0], func(key string, value map[string]interface{}) {
if len(arg) < 2 {
// 收藏列表
m.Grows(ice.WEB_FAVOR, kit.Keys(kit.MDB_HASH, key), "", "", func(index int, value map[string]interface{}) {
m.Push("", value, fields)
})
return
}
// 收藏详情
m.Grows(ice.WEB_FAVOR, kit.Keys(kit.MDB_HASH, key), "id", arg[1], func(index int, value map[string]interface{}) {
m.Push("detail", value)
m.Optionv("value", value)
m.Push("key", "render")
m.Push("value", m.Cmdx(m.Conf(ice.WEB_FAVOR, kit.Keys("meta.render", value["type"]))))
})
})
// 收藏列表
fields := []string{kit.MDB_TIME, kit.MDB_ID, kit.MDB_TYPE, kit.MDB_NAME, kit.MDB_TEXT}
if len(arg) > 1 && arg[1] == "extra" {
fields, arg = append(fields, arg[2:]...), arg[:1]
}
_favor_list(m, arg[0], kit.Select("", arg, 1), fields...)
return
}
@ -191,24 +224,13 @@ func init() {
favor = key
}) == nil {
// 创建收藏
favor = m.Rich(ice.WEB_FAVOR, nil, kit.Data(kit.MDB_NAME, arg[0]))
m.Log(ice.LOG_CREATE, "favor: %s name: %s", favor, arg[0])
favor = _favor_create(m, arg[0])
}
if len(arg) == 3 {
arg = append(arg, "")
}
// 添加收藏
index := m.Grow(ice.WEB_FAVOR, kit.Keys(kit.MDB_HASH, favor), kit.Dict(
kit.MDB_TYPE, arg[1], kit.MDB_NAME, arg[2], kit.MDB_TEXT, arg[3],
"extra", kit.Dict(arg[4:]),
))
m.Richs(ice.WEB_FAVOR, nil, favor, func(key string, value map[string]interface{}) {
kit.Value(value, "meta.time", m.Time())
})
m.Log(ice.LOG_INSERT, "favor: %s index: %d name: %s text: %s", arg[0], index, arg[2], arg[3])
m.Echo("%d", index)
_favor_insert(m, favor, arg[1], arg[2], arg[3], arg[4:]...)
// 分发数据
if p := kit.Select(m.Conf(ice.WEB_FAVOR, "meta.proxy"), m.Option("you")); p != "" {

View File

@ -100,6 +100,7 @@ func _space_send(m *ice.Message, space string, arg ...string) {
m.Target().Server().(*Frame).send[id] = m
socket.WriteMessage(1, []byte(m.Format("meta")))
m.Option("timeout", m.Conf(SPACE, "meta.timeout.c"))
m.Call(m.Option("_async") == "", func(res *ice.Message) *ice.Message {
if res != nil && m != nil {
// 返回结果
@ -137,9 +138,7 @@ func init() {
})
case "connect":
dev := kit.Select("dev", arg, 1)
name := kit.Select(m.Conf(ice.CLI_RUNTIME, "node.name"), arg, 2)
_space_dial(m, dev, name)
_space_dial(m, kit.Select("dev", arg, 1), kit.Select(m.Conf(ice.CLI_RUNTIME, "node.name"), arg, 2))
default:
if len(arg) == 1 {
@ -168,7 +167,6 @@ func init() {
if m.Richs(ice.WEB_SHARE, nil, share, nil) == nil {
share = m.Cmdx(ice.WEB_SHARE, "add", m.Option("node"), m.Option("name"), m.Option("user"))
}
// m.Cmd(ice.WEB_GROUP, m.Option("group"), "add", m.Option("name"))
// 添加节点
h := m.Rich(ice.WEB_SPACE, nil, kit.Dict(

View File

@ -175,6 +175,8 @@ func (web *Frame) HandleWSS(m *ice.Message, safe bool, c *websocket.Conn, name s
// 本地执行
m.Option("_dev", name)
msg = msg.Cmd()
msg.Set("_option")
msg.Set("_option")
}
if source, target = []string{}, kit.Revert(source)[1:]; msg.Detail() == "exit" {
// 重启进程

View File

@ -94,6 +94,7 @@ func _inner_show(m *ice.Message, name string) {
if ls := kit.Simple(m.Confv(INNER, kit.Keys("meta.show", p))); len(ls) > 0 {
m.Cmdy(ice.CLI_SYSTEM, ls, name)
m.Set(ice.MSG_APPEND)
m.Cmd(web.FAVOR, "inner.run", "shell", name, m.Result())
return
}
@ -170,6 +171,9 @@ func init() {
"run": {Name: "run path name", Help: "运行", Hand: func(m *ice.Message, arg ...string) {
_inner_show(m, path.Join("./", arg[0], arg[1]))
}},
"log": {Name: "log path name", Help: "日志", Hand: func(m *ice.Message, arg ...string) {
web.FavorList(m, "inner.run", "", "time", "id", "type", "name", "text")
}},
"plug": {Name: "plug path name", Help: "插件", Hand: func(m *ice.Message, arg ...string) {
_inner_plug(m, path.Join("./", arg[0], arg[1]))
}},

110
type.go
View File

@ -9,7 +9,6 @@ import (
kit "github.com/shylinux/toolkits"
"encoding/json"
"errors"
"fmt"
"io"
"net/http"
@ -387,115 +386,6 @@ func (m *Message) Spawn(arg ...interface{}) *Message {
return msg
}
func (m *Message) TryCatch(msg *Message, safe bool, hand ...func(msg *Message)) *Message {
defer func() {
switch e := recover(); e {
case io.EOF:
case nil:
default:
_, file, line, _ := runtime.Caller(3)
if list := strings.Split(file, "/"); len(list) > 2 {
file = strings.Join(list[len(list)-2:], "/")
}
m.Log(LOG_WARN, "catch: %s %s:%d", e, file, line)
m.Log(LOG_INFO, "chain: %s", msg.Format("chain"))
m.Log(LOG_WARN, "catch: %s %s:%d", e, file, line)
m.Log(LOG_INFO, "stack: %s", msg.Format("stack"))
if m.Log(LOG_WARN, "catch: %s %s:%d", e, file, line); len(hand) > 1 {
// 捕获异常
m.TryCatch(msg, safe, hand[1:]...)
} else if !safe {
// 抛出异常
m.Assert(e)
}
}
}()
if len(hand) > 0 {
// 运行函数
hand[0](msg)
}
return m
}
func (m *Message) Assert(arg interface{}) bool {
switch arg := arg.(type) {
case nil:
return true
case bool:
if arg == true {
return true
}
}
// 抛出异常
panic(errors.New(fmt.Sprintf("error %v", arg)))
}
func (m *Message) Sleep(arg string) *Message {
time.Sleep(kit.Duration(arg))
return m
}
func (m *Message) Hold(n int) *Message {
ctx := m.target.root
if c := m.target; c.context != nil && c.context.wg != nil {
ctx = c.context
}
ctx.wg.Add(n)
m.Log(LOG_TRACE, "%s wait %s %v", ctx.Name, m.target.Name, ctx.wg)
return m
}
func (m *Message) Done() bool {
defer func() { recover() }()
ctx := m.target.root
if c := m.target; c.context != nil && c.context.wg != nil {
ctx = c.context
}
m.Log(LOG_TRACE, "%s done %s %v", ctx.Name, m.target.Name, ctx.wg)
ctx.wg.Done()
return true
}
func (m *Message) Call(sync bool, cb func(*Message) *Message) *Message {
wait := make(chan bool, 2)
t := time.AfterFunc(kit.Duration("10s"), func() {
m.Log(LOG_WARN, "timeout")
m.Back(nil)
wait <- false
})
m.cb = func(sub *Message) *Message {
if sync {
t.Stop()
wait <- true
}
return cb(sub)
}
if sync {
<-wait
} else {
t.Stop()
}
return m
}
func (m *Message) Back(res *Message) *Message {
if m.cb != nil {
// if res != nil {
// m.Info("back %v", res.Format("prefix"))
// } else {
// m.Info("back %v", nil)
// }
if sub := m.cb(res); m.message != nil {
m.message.Back(sub)
}
}
return m
}
func (m *Message) Gos(msg *Message, cb func(*Message)) *Message {
go func() { msg.TryCatch(msg, true, func(msg *Message) { cb(msg) }) }()
return m
}
func (m *Message) Run(arg ...string) *Message {
m.target.server.Start(m, arg...)
return m