1
0
forked from x/icebergs

add hash.lock

This commit is contained in:
harveyshao 2022-07-24 19:57:11 +08:00
parent e829036e17
commit ab05ddc76d
6 changed files with 152 additions and 48 deletions

View File

@ -14,6 +14,8 @@ func _hash_fields(m *ice.Message) []string {
return kit.Split(kit.Select("time,hash,type,name,text", m.OptionFields())) return kit.Split(kit.Select("time,hash,type,name,text", m.OptionFields()))
} }
func _hash_inputs(m *ice.Message, prefix, chain string, field, value string) { func _hash_inputs(m *ice.Message, prefix, chain string, field, value string) {
defer m.RLock(prefix, chain)()
list := map[string]int{} list := map[string]int{}
m.Richs(prefix, chain, FOREACH, func(key string, val ice.Map) { m.Richs(prefix, chain, FOREACH, func(key string, val ice.Map) {
if val = kit.GetMeta(val); kit.Format(val[COUNT]) != "" { if val = kit.GetMeta(val); kit.Format(val[COUNT]) != "" {
@ -29,6 +31,8 @@ func _hash_inputs(m *ice.Message, prefix, chain string, field, value string) {
m.SortIntR(COUNT) m.SortIntR(COUNT)
} }
func _hash_insert(m *ice.Message, prefix, chain string, arg ...string) { func _hash_insert(m *ice.Message, prefix, chain string, arg ...string) {
defer m.Lock(prefix, chain)()
if m.Option(ice.MSG_DOMAIN) != "" { if m.Option(ice.MSG_DOMAIN) != "" {
m.Conf(prefix, kit.Keys(chain, kit.Keym(SHORT)), m.Conf(prefix, kit.Keym(SHORT))) m.Conf(prefix, kit.Keys(chain, kit.Keym(SHORT)), m.Conf(prefix, kit.Keym(SHORT)))
} }
@ -40,6 +44,8 @@ func _hash_insert(m *ice.Message, prefix, chain string, arg ...string) {
m.Echo(m.Rich(prefix, chain, kit.Data(arg))) m.Echo(m.Rich(prefix, chain, kit.Data(arg)))
} }
func _hash_delete(m *ice.Message, prefix, chain, field, value string) { func _hash_delete(m *ice.Message, prefix, chain, field, value string) {
defer m.Lock(prefix, chain)()
if field != HASH { if field != HASH {
field, value = HASH, kit.Select(kit.Hashs(value), m.Option(HASH)) field, value = HASH, kit.Select(kit.Hashs(value), m.Option(HASH))
} }
@ -49,6 +55,8 @@ func _hash_delete(m *ice.Message, prefix, chain, field, value string) {
}) })
} }
func _hash_modify(m *ice.Message, prefix, chain string, field, value string, arg ...string) { func _hash_modify(m *ice.Message, prefix, chain string, field, value string, arg ...string) {
defer m.Lock(prefix, chain)()
m.Richs(prefix, chain, value, func(key string, val ice.Map) { m.Richs(prefix, chain, value, func(key string, val ice.Map) {
val = kit.GetMeta(val) val = kit.GetMeta(val)
m.Log_MODIFY(KEY, path.Join(prefix, chain), field, value, arg) m.Log_MODIFY(KEY, path.Join(prefix, chain), field, value, arg)
@ -61,6 +69,8 @@ func _hash_modify(m *ice.Message, prefix, chain string, field, value string, arg
}) })
} }
func _hash_select(m *ice.Message, prefix, chain, field, value string) { func _hash_select(m *ice.Message, prefix, chain, field, value string) {
defer m.RLock(prefix, chain)()
if field == HASH && value == RANDOM { if field == HASH && value == RANDOM {
value = RANDOMS value = RANDOMS
} }
@ -83,7 +93,29 @@ func _hash_select(m *ice.Message, prefix, chain, field, value string) {
m.SortTimeR(TIME) m.SortTimeR(TIME)
} }
} }
func _hash_prunes(m *ice.Message, prefix, chain string, arg ...string) {
defer m.RLock(prefix, chain)()
fields := _hash_fields(m)
m.Richs(prefix, chain, FOREACH, func(key string, val ice.Map) {
switch val = kit.GetMeta(val); cb := m.OptionCB(PRUNES).(type) {
case func(string, ice.Map) bool:
if !cb(key, val) {
return
}
default:
for i := 0; i < len(arg)-1; i += 2 {
if val[arg[i]] != arg[i+1] && kit.Value(val, arg[i]) != arg[i+1] {
return
}
}
}
m.Push(key, val, fields)
})
}
func _hash_export(m *ice.Message, prefix, chain, file string) { func _hash_export(m *ice.Message, prefix, chain, file string) {
defer m.Lock(prefix, chain)()
f, p, e := kit.Create(kit.Keys(file, JSON)) f, p, e := kit.Create(kit.Keys(file, JSON))
m.Assert(e) m.Assert(e)
defer f.Close() defer f.Close()
@ -97,6 +129,8 @@ func _hash_export(m *ice.Message, prefix, chain, file string) {
m.Echo(p) m.Echo(p)
} }
func _hash_import(m *ice.Message, prefix, chain, file string) { func _hash_import(m *ice.Message, prefix, chain, file string) {
defer m.Lock(prefix, chain)()
f, e := os.Open(kit.Keys(file, JSON)) f, e := os.Open(kit.Keys(file, JSON))
if m.Warn(e) { if m.Warn(e) {
return return
@ -122,27 +156,6 @@ func _hash_import(m *ice.Message, prefix, chain, file string) {
m.Log_IMPORT(KEY, path.Join(prefix, chain), COUNT, count) m.Log_IMPORT(KEY, path.Join(prefix, chain), COUNT, count)
m.Echo("%d", count) m.Echo("%d", count)
} }
func _hash_prunes(m *ice.Message, prefix, chain string, arg ...string) {
fields := _hash_fields(m)
m.Richs(prefix, chain, FOREACH, func(key string, val ice.Map) {
switch val = kit.GetMeta(val); cb := m.OptionCB(PRUNES).(type) {
case func(string, ice.Map) bool:
if !cb(key, val) {
return
}
default:
for i := 0; i < len(arg)-1; i += 2 {
if val[arg[i]] != arg[i+1] && kit.Value(val, arg[i]) != arg[i+1] {
return
}
}
}
m.Push(key, val, fields)
})
m.Table(func(index int, value ice.Maps, head []string) {
_hash_delete(m, prefix, chain, HASH, value[HASH])
})
}
const HASH = "hash" const HASH = "hash"
@ -209,6 +222,12 @@ func HashAction(args ...ice.Any) ice.Actions {
} }
m.Cmdy(MODIFY, m.PrefixKey(), "", HASH, m.OptionSimple(_key(m)), arg) m.Cmdy(MODIFY, m.PrefixKey(), "", HASH, m.OptionSimple(_key(m)), arg)
}}, }},
SELECT: &ice.Action{Name: "select hash auto", Help: "列表", Hand: func(m *ice.Message, arg ...string) {
HashSelect(m, arg...)
}},
PRUNES: &ice.Action{Name: "prunes before@date", Help: "清理", Hand: func(m *ice.Message, arg ...string) {
HashPrunes(m, nil)
}},
EXPORT: {Name: "export", Help: "导出", Hand: func(m *ice.Message, arg ...string) { EXPORT: {Name: "export", Help: "导出", Hand: func(m *ice.Message, arg ...string) {
m.OptionFields(m.Config(FIELD)) m.OptionFields(m.Config(FIELD))
m.Cmdy(EXPORT, m.PrefixKey(), "", HASH, arg) m.Cmdy(EXPORT, m.PrefixKey(), "", HASH, arg)
@ -216,12 +235,6 @@ func HashAction(args ...ice.Any) ice.Actions {
IMPORT: {Name: "import", Help: "导入", Hand: func(m *ice.Message, arg ...string) { IMPORT: {Name: "import", Help: "导入", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(IMPORT, m.PrefixKey(), "", HASH, arg) m.Cmdy(IMPORT, m.PrefixKey(), "", HASH, arg)
}}, }},
PRUNES: &ice.Action{Name: "prunes before@date", Help: "清理", Hand: func(m *ice.Message, arg ...string) {
HashPrunes(m, nil)
}},
SELECT: &ice.Action{Name: "select hash auto", Help: "列表", Hand: func(m *ice.Message, arg ...string) {
HashSelect(m, arg...)
}},
} }
} }
func HashActionStatus(args ...ice.Any) ice.Actions { func HashActionStatus(args ...ice.Any) ice.Actions {
@ -233,12 +246,19 @@ func HashActionStatus(args ...ice.Any) ice.Actions {
}} }}
return list return list
} }
func HashInputs(m *ice.Message, arg ...ice.Any) *ice.Message {
return m.Cmd(INPUTS, m.PrefixKey(), "", HASH, kit.Simple(arg...))
}
func HashCreate(m *ice.Message, arg ...ice.Any) *ice.Message { func HashCreate(m *ice.Message, arg ...ice.Any) *ice.Message {
return m.Cmd(INSERT, m.PrefixKey(), "", HASH, kit.Simple(arg...)) return m.Cmd(INSERT, m.PrefixKey(), "", HASH, kit.Simple(arg...))
} }
func HashRemove(m *ice.Message, arg ...ice.Any) *ice.Message { func HashRemove(m *ice.Message, arg ...ice.Any) *ice.Message {
return m.Cmd(DELETE, m.PrefixKey(), "", HASH, kit.Simple(arg...)) return m.Cmd(DELETE, m.PrefixKey(), "", HASH, kit.Simple(arg...))
} }
func HashModify(m *ice.Message, arg ...ice.Any) *ice.Message {
return m.Cmd(MODIFY, m.PrefixKey(), "", HASH, kit.Simple(arg...))
}
func HashSelect(m *ice.Message, arg ...string) *ice.Message { func HashSelect(m *ice.Message, arg ...string) *ice.Message {
m.Fields(len(arg), m.Config(FIELD)) m.Fields(len(arg), m.Config(FIELD))
m.Cmdy(SELECT, m.PrefixKey(), "", HASH, m.Config(SHORT), arg) m.Cmdy(SELECT, m.PrefixKey(), "", HASH, m.Config(SHORT), arg)
@ -266,3 +286,9 @@ func HashPrunes(m *ice.Message, cb func(ice.Maps) bool) *ice.Message {
}) })
return m return m
} }
func HashExport(m *ice.Message, arg ...ice.Any) *ice.Message {
return m.Cmd(EXPORT, m.PrefixKey(), "", HASH, kit.Simple(arg...))
}
func HashImport(m *ice.Message, arg ...ice.Any) *ice.Message {
return m.Cmd(IMPORT, m.PrefixKey(), "", HASH, kit.Simple(arg...))
}

View File

@ -211,6 +211,9 @@ var Index = &ice.Context{Name: MDB, Help: "数据模块", Commands: ice.Commands
_list_prunes(m, arg[0], _domain_chain(m, kit.Keys(arg[1], kit.KeyHash(arg[3]))), arg[4:]...) _list_prunes(m, arg[0], _domain_chain(m, kit.Keys(arg[1], kit.KeyHash(arg[3]))), arg[4:]...)
case HASH: case HASH:
_hash_prunes(m, arg[0], _domain_chain(m, arg[1]), arg[3:]...) _hash_prunes(m, arg[0], _domain_chain(m, arg[1]), arg[3:]...)
m.Tables(func(value ice.Maps) {
_hash_delete(m, arg[0], _domain_chain(m, arg[1]), HASH, value[HASH])
})
case LIST: case LIST:
_list_prunes(m, arg[0], _domain_chain(m, arg[1]), arg[3:]...) _list_prunes(m, arg[0], _domain_chain(m, arg[1]), arg[3:]...)
} }

View File

@ -393,7 +393,9 @@ func init() {
}}, }},
"/require/node_modules/": {Name: "/require/node_modules/", Help: "依赖库", Hand: func(m *ice.Message, arg ...string) { "/require/node_modules/": {Name: "/require/node_modules/", Help: "依赖库", Hand: func(m *ice.Message, arg ...string) {
p := path.Join(ice.USR_VOLCANOS, "node_modules", path.Join(arg...)) p := path.Join(ice.USR_VOLCANOS, "node_modules", path.Join(arg...))
if _, e := os.Stat(p); e != nil { if b, ok := ice.Info.Pack[p]; ok && len(b) > 0 {
} else if _, e := os.Stat(p); e != nil {
m.Cmd(cli.SYSTEM, "npm", "install", arg[0], kit.Dict(cli.CMD_DIR, ice.USR_VOLCANOS)) m.Cmd(cli.SYSTEM, "npm", "install", arg[0], kit.Dict(cli.CMD_DIR, ice.USR_VOLCANOS))
} }
m.RenderDownload(p) m.RenderDownload(p)

View File

@ -4,11 +4,13 @@ import (
"encoding/base64" "encoding/base64"
"os" "os"
"os/exec" "os/exec"
"strings"
"sync" "sync"
"time" "time"
pty "shylinux.com/x/creackpty" pty "shylinux.com/x/creackpty"
ice "shylinux.com/x/icebergs" ice "shylinux.com/x/icebergs"
"shylinux.com/x/icebergs/base/ctx"
"shylinux.com/x/icebergs/base/mdb" "shylinux.com/x/icebergs/base/mdb"
kit "shylinux.com/x/toolkits" kit "shylinux.com/x/toolkits"
) )
@ -18,8 +20,9 @@ const XTERM = "xterm"
func init() { func init() {
cache := sync.Map{} cache := sync.Map{}
add := func(m *ice.Message, key string) string { add := func(m *ice.Message, key string) string {
cmd := exec.Command("/bin/sh") cmd := exec.Command(kit.Select("/bin/sh", m.Option(mdb.TYPE)))
cmd.Env = append(os.Environ(), "TERM=xterm") cmd.Env = append(os.Environ(), "TERM=xterm")
tty, err := pty.Start(cmd) tty, err := pty.Start(cmd)
m.Assert(err) m.Assert(err)
cache.Store(key, tty) cache.Store(key, tty)
@ -27,11 +30,11 @@ func init() {
m.Go(func() { m.Go(func() {
defer m.Cmd(m.PrefixKey(), mdb.PRUNES) defer m.Cmd(m.PrefixKey(), mdb.PRUNES)
defer cache.Delete(key) defer cache.Delete(key)
buf := make([]byte, 1024) buf := make([]byte, ice.MOD_BUFS)
for { for {
if n, e := tty.Read(buf); !m.Warn(e) { if n, e := tty.Read(buf); !m.Warn(e) {
m.Optionv(ice.MSG_OPTS, kit.Simple("hash"))
m.Option(mdb.HASH, key) m.Option(mdb.HASH, key)
m.Optionv(ice.MSG_OPTS, kit.Simple(mdb.HASH))
m.Option(ice.MSG_DAEMON, m.Conf(m.PrefixKey(), kit.Keys(mdb.HASH, key, mdb.META, mdb.TEXT))) m.Option(ice.MSG_DAEMON, m.Conf(m.PrefixKey(), kit.Keys(mdb.HASH, key, mdb.META, mdb.TEXT)))
m.PushNoticeGrow(kit.Format(kit.Dict(mdb.TYPE, "data", mdb.TEXT, base64.StdEncoding.EncodeToString(buf[:n])))) m.PushNoticeGrow(kit.Format(kit.Dict(mdb.TYPE, "data", mdb.TEXT, base64.StdEncoding.EncodeToString(buf[:n]))))
} else { } else {
@ -58,34 +61,55 @@ func init() {
} }
Index.MergeCommands(ice.Commands{ Index.MergeCommands(ice.Commands{
XTERM: {Name: "xterm hash id auto prunes", Help: "终端", Actions: ice.MergeAction(ice.Actions{ XTERM: {Name: "xterm hash id auto", Help: "终端", Actions: ice.MergeAction(ice.Actions{
mdb.INPUTS: {Name: "inputs", Help: "补全", Hand: func(m *ice.Message, arg ...string) {
if mdb.HashInputs(m, arg); arg[0] == mdb.TYPE {
m.Push(mdb.TYPE, "/usr/bin/python")
m.Push(mdb.TYPE, "/usr/bin/node")
m.Push(mdb.TYPE, "/bin/bash")
m.Push(mdb.TYPE, "/bin/sh")
}
}},
mdb.CREATE: {Name: "create type name", Help: "创建", Hand: func(m *ice.Message, arg ...string) { mdb.CREATE: {Name: "create type name", Help: "创建", Hand: func(m *ice.Message, arg ...string) {
if m.Option(mdb.TEXT, m.Option(ice.MSG_DAEMON)) != "" { if m.Option(mdb.TEXT, m.Option(ice.MSG_DAEMON)) != "" {
m.Echo(add(m, m.Cmdx(mdb.INSERT, m.PrefixKey(), "", mdb.HASH, m.OptionSimple("type,name,text")))) m.Echo(add(m, mdb.HashCreate(m, m.OptionSimple("type,name,text")).Result()))
} }
}}, }},
mdb.REMOVE: {Name: "remove", Help: "删除", Hand: func(m *ice.Message, arg ...string) {
if w, ok := cache.Load(m.Option(mdb.HASH)); ok {
if w, ok := w.(*os.File); ok {
w.Close()
}
cache.Delete(m.Option(mdb.HASH))
}
mdb.HashRemove(m, m.OptionSimple(mdb.HASH))
}},
mdb.MODIFY: {Name: "modify", Help: "编辑", Hand: func(m *ice.Message, arg ...string) {
mdb.HashModify(m, m.OptionSimple(mdb.HASH), arg)
}},
mdb.PRUNES: {Name: "prunes", Help: "清理", Hand: func(m *ice.Message, arg ...string) {
mdb.HashSelect(m).Tables(func(value ice.Maps) {
if _, ok := cache.Load(value[mdb.HASH]); !ok || kit.Time(m.Time())-kit.Time(value[mdb.TIME]) > int64(time.Hour) {
m.Cmd(m.PrefixKey(), mdb.REMOVE, kit.Dict(value))
}
})
}},
"resize": {Name: "resize", Help: "大小", Hand: func(m *ice.Message, arg ...string) { "resize": {Name: "resize", Help: "大小", Hand: func(m *ice.Message, arg ...string) {
pty.Setsize(get(m, m.Option(mdb.HASH)), &pty.Winsize{Rows: uint16(kit.Int(m.Option("rows"))), Cols: uint16(kit.Int(m.Option("cols")))}) pty.Setsize(get(m, m.Option(mdb.HASH)), &pty.Winsize{Rows: uint16(kit.Int(m.Option("rows"))), Cols: uint16(kit.Int(m.Option("cols")))})
}}, }},
"rename": {Name: "rename", Help: "重命名", Hand: func(m *ice.Message, arg ...string) {
mdb.HashModify(m, m.OptionSimple(mdb.HASH), arg)
}},
"select": {Name: "select", Help: "连接", Hand: func(m *ice.Message, arg ...string) { "select": {Name: "select", Help: "连接", Hand: func(m *ice.Message, arg ...string) {
m.Cmd(mdb.MODIFY, m.PrefixKey(), "", mdb.HASH, m.OptionSimple(mdb.HASH), mdb.TEXT, m.Option(ice.MSG_DAEMON)) mdb.HashModify(m, m.OptionSimple(mdb.HASH), mdb.TEXT, m.Option(ice.MSG_DAEMON))
m.Cmd(m.PrefixKey(), "input", arg)
}}, }},
"input": {Name: "input", Help: "输入", Hand: func(m *ice.Message, arg ...string) { "input": {Name: "input", Help: "输入", Hand: func(m *ice.Message, arg ...string) {
m.Cmd(mdb.MODIFY, m.PrefixKey(), "", mdb.HASH, m.OptionSimple(mdb.HASH), mdb.TIME, m.Time()) mdb.HashModify(m, m.OptionSimple(mdb.HASH), mdb.TIME, m.Time())
get(m, m.Option(mdb.HASH)).Write([]byte(arg[0])) get(m, m.Option(mdb.HASH)).Write([]byte(strings.Join(arg, "")))
}}, }},
mdb.PRUNES: {Name: "prunes", Help: "清理", Hand: func(m *ice.Message, arg ...string) { }, mdb.HashAction(mdb.FIELD, "time,hash,type,name,text,extra"), ctx.CmdAction()), Hand: func(m *ice.Message, arg ...string) {
m.Cmd(m.CommandKey()).Tables(func(value ice.Maps) { mdb.HashSelect(m, kit.Slice(arg, 0, 1)...)
if _, ok := cache.Load(value[mdb.HASH]); !ok || kit.Time(m.Time())-kit.Time(value[mdb.TIME]) > int64(time.Hour) {
m.Cmdy(mdb.DELETE, m.PrefixKey(), "", mdb.HASH, mdb.HASH, value[mdb.HASH])
}
})
}},
}, mdb.ZoneAction(mdb.FIELD, "time,id,type,name,text")), Hand: func(m *ice.Message, arg ...string) {
if len(arg) == 0 {
m.OptionFields("time,hash,type,name,text")
}
mdb.ZoneSelect(m, kit.Slice(arg, 0, 2)...)
m.DisplayLocal("") m.DisplayLocal("")
}}, }},
}) })

7
core/code/xterm.shy Normal file
View File

@ -0,0 +1,7 @@
section "xterm.js"
refer `
官网 https://xtermjs.org/
源码 https://github.com/xtermjs/xterm.js
文档 https://xtermjs.org/docs/api/terminal/classes/terminal/
接口 https://github.com/xtermjs/xterm.js/blob/4.14.1/typings/xterm.d.ts#L619
`

42
lock.go Normal file
View File

@ -0,0 +1,42 @@
package ice
import (
"sync"
kit "shylinux.com/x/toolkits"
)
var lock = map[string]*sync.RWMutex{}
var _lock = sync.Mutex{}
func _get_lock(key string) (*sync.RWMutex, string) {
_lock.Lock()
defer _lock.Unlock()
l, ok := lock[key]
if !ok {
l = &sync.RWMutex{}
lock[key] = l
}
return l, key
}
func (m *Message) Lock(arg ...Any) func() {
l, key := _get_lock(kit.Keys(arg...))
m.Debug("before lock %v", key)
l.Lock()
m.Debug("success lock %v", key)
return func() {
l.Unlock()
m.Debug("success unlock %v", key)
}
}
func (m *Message) RLock(arg ...Any) func() {
l, key := _get_lock(kit.Keys(arg...))
m.Debug("before rlock %v", key)
l.RLock()
m.Debug("success rlock %v", key)
return func() {
l.RUnlock()
m.Debug("success runlock %v", key)
}
}