summaryrefslogtreecommitdiff
path: root/pkg/server/env
diff options
context:
space:
mode:
authorMikhail Osipov <mike.osipov@gmail.com>2020-12-16 15:27:48 +0300
committerMikhail Osipov <mike.osipov@gmail.com>2020-12-16 15:27:48 +0300
commit6fed9dd0dd62718f78eca11e30a71c2712636fbd (patch)
tree8d1f90b96efbe8ea8aea350c283325adc216ef9d /pkg/server/env
parent050ea053dd549f0dd01beddfcd74989858391fd7 (diff)
hook and socket args check fix, tests
Diffstat (limited to 'pkg/server/env')
-rw-r--r--pkg/server/env/env.go80
1 files changed, 76 insertions, 4 deletions
diff --git a/pkg/server/env/env.go b/pkg/server/env/env.go
index 2c97669..7aa93d2 100644
--- a/pkg/server/env/env.go
+++ b/pkg/server/env/env.go
@@ -4,12 +4,23 @@ import (
"errors"
"regexp"
"sort"
+ "strings"
"sync"
)
type env struct {
+ // vars
m map[string]string
+
+ // forks
+ c map[string]*env
+
+ // key in parent env's map
+ k string
+
sync.Mutex
+
+ // parent env
p *env
}
@@ -36,23 +47,84 @@ func (e Env) init() {
}
}
-func (e Env) Fork() Env {
+func (e Env) Fork(path ...string) Env {
t := New()
t.p = e.env
+
+ if len(path) > 0 {
+ k := strings.Join(path, ".")
+
+ e.Lock()
+ if e.c == nil {
+ e.c = make(map[string]*env)
+ } else if _, ok := e.c[k]; ok {
+ panic("env fork already exists: " + k)
+ }
+ e.c[k] = t.env
+ e.Unlock()
+
+ t.k = k
+ }
+
return t
}
-func (e *env) Find(key string) (string, bool) {
+func (e Env) Detach() {
+ if e.p != nil {
+ e.p.Lock()
+ delete(e.p.c, e.k)
+ e.p.Unlock()
+ }
+}
+
+func (e *env) find(key string) (string, bool, func() (string, bool)) {
e.Lock()
defer e.Unlock()
v, ok := e.m[key]
if ok {
- return v, ok
+ return v, ok, nil
+ }
+
+ if e.c != nil {
+ s := strings.Split(key, ".")
+
+ for k := ""; len(s) > 1; s = s[1:] {
+ if k == "" {
+ k = s[0]
+ } else {
+ k += "." + s[0]
+ }
+
+ if c, ok := e.c[k]; ok {
+ return "", false, func() (string, bool) {
+ return c.Find(strings.Join(s[1:], "."))
+ }
+ }
+ }
}
if e.p != nil {
- return e.p.Find(key)
+ return "", false, func() (string, bool) {
+ return e.p.Find(key)
+ }
+ }
+
+ return "", false, nil
+}
+
+func (e *env) Find(key string) (string, bool) {
+ if key == "" {
+ return "", false
+ }
+
+ v, ok, f := e.find(key)
+ if ok {
+ return v, ok
+ }
+
+ if f != nil {
+ return f()
}
return "", false