fix bug and optimize code

This commit is contained in:
xing 2024-01-21 21:29:36 +08:00
parent 65bfccdd48
commit 4842d53316
12 changed files with 231 additions and 115 deletions

View File

@ -3,7 +3,6 @@ package main
import ( import (
"flag" "flag"
"fmt" "fmt"
"github.com/fthvgb1/wp-go/app/cmd/route"
"github.com/fthvgb1/wp-go/app/mail" "github.com/fthvgb1/wp-go/app/mail"
"github.com/fthvgb1/wp-go/app/pkg/cache" "github.com/fthvgb1/wp-go/app/pkg/cache"
"github.com/fthvgb1/wp-go/app/pkg/config" "github.com/fthvgb1/wp-go/app/pkg/config"
@ -11,6 +10,7 @@ import (
"github.com/fthvgb1/wp-go/app/pkg/logs" "github.com/fthvgb1/wp-go/app/pkg/logs"
"github.com/fthvgb1/wp-go/app/plugins" "github.com/fthvgb1/wp-go/app/plugins"
"github.com/fthvgb1/wp-go/app/plugins/wphandle" "github.com/fthvgb1/wp-go/app/plugins/wphandle"
"github.com/fthvgb1/wp-go/app/route"
"github.com/fthvgb1/wp-go/app/theme" "github.com/fthvgb1/wp-go/app/theme"
"github.com/fthvgb1/wp-go/app/wpconfig" "github.com/fthvgb1/wp-go/app/wpconfig"
"github.com/fthvgb1/wp-go/cache/cachemanager" "github.com/fthvgb1/wp-go/cache/cachemanager"
@ -117,7 +117,7 @@ func reloads() {
err = wpconfig.InitTerms() err = wpconfig.InitTerms()
logs.IfError(err, "获取WpTerms表失败") logs.IfError(err, "获取WpTerms表失败")
wphandle.LoadPlugins() wphandle.LoadPlugins()
reload.Reload() reload.Reloads("themeArgAndConfig")
flushCache() flushCache()
log.Println("reload complete") log.Println("reload complete")
} }

111
app/cmd/sitetest/main.go Normal file
View File

@ -0,0 +1,111 @@
package main
import (
"flag"
"fmt"
"github.com/fthvgb1/wp-go/helper/httptool"
strings2 "github.com/fthvgb1/wp-go/helper/strings"
"github.com/fthvgb1/wp-go/safety"
"github.com/fthvgb1/wp-go/taskPools"
"net/http"
"os"
"regexp"
"strings"
"sync"
)
var reg = regexp.MustCompile(`<a.*href="([^"]+?)".*?>`)
var m = safety.NewMap[string, bool]()
var mut = sync.Mutex{}
func parseHtml(ss string) {
r := reg.FindAllStringSubmatch(ss, -1)
for _, href := range r {
if href[1] == "/" {
continue
}
if strings.ContainsAny(href[1], ".") {
continue
}
if string([]rune(href[1])[0:3]) == "http" {
continue
}
mut.Lock()
if _, ok := m.Load(href[1]); !ok {
m.Store(href[1], false)
}
mut.Unlock()
}
}
func siteFetch(c int, u string) {
u = strings.TrimRight(u, "/")
ss, code, err := httptool.GetString(u, nil)
if err != nil || code != http.StatusOK {
panic(err)
}
parseHtml(ss)
p := taskPools.NewPools(c)
for {
m.Range(func(key string, value bool) bool {
if value {
return true
}
u := strings2.Join(u, key)
p.Execute(func() {
ss, code, err := httptool.GetString(u, nil)
fmt.Println(u, code)
if err != nil || code != http.StatusOK {
panic(err)
return
}
parseHtml(ss)
m.Store(key, true)
})
return true
})
var x bool
m.Range(func(key string, value bool) bool {
if !value {
x = true
return false
}
return true
})
if !x {
break
}
}
p.Wait()
m.Flush()
}
var c int
var u string
var t int
func main() {
flag.IntVar(&c, "c", 10, "concurrency num")
flag.StringVar(&u, "url", "http://127.0.0.1:8081", "test url")
flag.IntVar(&t, "t", 1, "request full site times")
flag.Parse()
if u == "" {
fmt.Println("url can't emtpy")
os.Exit(2)
}
if c < 1 {
fmt.Println("concurrency num must >= 1")
os.Exit(2)
}
if t < 1 {
for {
siteFetch(c, u)
}
}
for i := 0; i < t; i++ {
siteFetch(c, u)
}
}

View File

@ -25,6 +25,9 @@ var comFn = template.FuncMap{
"exec": func(fn func() string) template.HTML { "exec": func(fn func() string) template.HTML {
return template.HTML(fn()) return template.HTML(fn())
}, },
"callFuncString": func(fn func(string) string, s string) template.HTML {
return template.HTML(fn(s))
},
} }
func postsFn(fn func(models.Posts) string, a models.Posts) string { func postsFn(fn func(models.Posts) string, a models.Posts) string {

View File

@ -3,11 +3,13 @@ package twentyfifteen
import ( import (
"github.com/fthvgb1/wp-go/app/pkg/constraints" "github.com/fthvgb1/wp-go/app/pkg/constraints"
"github.com/fthvgb1/wp-go/app/pkg/constraints/widgets" "github.com/fthvgb1/wp-go/app/pkg/constraints/widgets"
"github.com/fthvgb1/wp-go/app/pkg/models"
"github.com/fthvgb1/wp-go/app/plugins" "github.com/fthvgb1/wp-go/app/plugins"
"github.com/fthvgb1/wp-go/app/theme/wp" "github.com/fthvgb1/wp-go/app/theme/wp"
"github.com/fthvgb1/wp-go/app/theme/wp/components" "github.com/fthvgb1/wp-go/app/theme/wp/components"
"github.com/fthvgb1/wp-go/app/theme/wp/middleware" "github.com/fthvgb1/wp-go/app/theme/wp/middleware"
"github.com/fthvgb1/wp-go/app/wpconfig" "github.com/fthvgb1/wp-go/app/wpconfig"
"github.com/fthvgb1/wp-go/cache/reload"
"strings" "strings"
) )
@ -28,7 +30,7 @@ func configs(h *wp.Handle) {
h.PushCacheGroupHeadScript(constraints.AllScene, "colorSchemeCss", 10.0056, colorSchemeCss) h.PushCacheGroupHeadScript(constraints.AllScene, "colorSchemeCss", 10.0056, colorSchemeCss)
h.CommonComponents() h.CommonComponents()
components.WidgetArea(h) components.WidgetArea(h)
h.SetData("customHeader", customHeader(h)) h.PushRender(constraints.AllScene, wp.NewHandleFn(renderCustomHeader, 20.5, "renderCustomHeader"))
wp.PushIndexHandler(constraints.PipeRender, h, wp.NewHandleFn(wp.IndexRender, 50.005, "wp.IndexRender")) wp.PushIndexHandler(constraints.PipeRender, h, wp.NewHandleFn(wp.IndexRender, 50.005, "wp.IndexRender"))
h.PushRender(constraints.Detail, wp.NewHandleFn(wp.DetailRender, 50.005, "wp.DetailRender")) h.PushRender(constraints.Detail, wp.NewHandleFn(wp.DetailRender, 50.005, "wp.DetailRender"))
h.PushRender(constraints.Detail, wp.NewHandleFn(postThumb, 60.005, "postThumb")) h.PushRender(constraints.Detail, wp.NewHandleFn(postThumb, 60.005, "postThumb"))
@ -54,6 +56,16 @@ func setPaginationAndRender(h *wp.Handle) {
func postThumb(h *wp.Handle) { func postThumb(h *wp.Handle) {
d := h.GetDetailHandle() d := h.GetDetailHandle()
if d.Post.Thumbnail.Path != "" { if d.Post.Thumbnail.Path != "" {
d.Post.Thumbnail = wpconfig.Thumbnail(d.Post.Thumbnail.OriginAttachmentData, "post-thumbnail", "") d.Post.Thumbnail = getPostThumbs(d.Post.Id, d.Post)
} }
} }
var getPostThumbs = reload.BuildMapFn[uint64]("twentyFifteen-post-thumbnail", postThumbs)
func postThumbs(post models.Posts) models.PostThumbnail {
return wpconfig.Thumbnail(post.Thumbnail.OriginAttachmentData, "post-thumbnail", "")
}
func renderCustomHeader(h *wp.Handle) {
h.SetData("customHeader", customHeader(h))
}

View File

@ -112,13 +112,19 @@ func errorsHandle(h *wp.Handle) {
func postThumb(h *wp.Handle) { func postThumb(h *wp.Handle) {
d := h.GetDetailHandle() d := h.GetDetailHandle()
if d.Post.Thumbnail.Path != "" { if d.Post.Thumbnail.Path != "" {
img := wpconfig.Thumbnail(d.Post.Thumbnail.OriginAttachmentData, "full", "", "thumbnail", "post-thumbnail") d.Post.Thumbnail = getPostThumbs(d.Post.Id, d.Post)
img.Sizes = "100vw"
img.Srcset = fmt.Sprintf("%s %dw, %s", img.Path, img.Width, img.Srcset)
d.Post.Thumbnail = img
} }
} }
var getPostThumbs = reload.BuildMapFn[uint64]("post-thumbnail", postThumbs)
func postThumbs(post models.Posts) models.PostThumbnail {
img := wpconfig.Thumbnail(post.Thumbnail.OriginAttachmentData, "full", "", "thumbnail", "post-thumbnail")
img.Sizes = "100vw"
img.Srcset = fmt.Sprintf("%s %dw, %s", img.Path, img.Width, img.Srcset)
return img
}
var commentFormat = comment{} var commentFormat = comment{}
type comment struct { type comment struct {

View File

@ -11,52 +11,59 @@ import (
) )
var handleComponents = safety.NewMap[string, map[string][]Components[string]]() var handleComponents = safety.NewMap[string, map[string][]Components[string]]()
var handleComponentHook = safety.NewMap[string, []func(Components[string]) (Components[string], bool)]() var handleComponentHook = safety.NewMap[string, map[string][]func(Components[string]) (Components[string], bool)]()
var componentsArgs = safety.NewMap[string, any]() var componentsArgs = safety.NewMap[string, any]()
var componentFilterFns = safety.NewMap[string, []func(*Handle, string, ...any) string]() var componentFilterFns = safety.NewMap[string, []func(*Handle, string, ...any) string]()
func (h *Handle) DeleteComponents(scene, name string) { func (h *Handle) DeleteComponents(scene, componentKey, componentName string) {
v, _ := handleComponentHook.Load(scene) v, ok := handleComponentHook.Load(scene)
v = append(v, func(c Components[string]) (Components[string], bool) { if !ok {
return c, c.Name != name v = make(map[string][]func(Components[string]) (Components[string], bool))
}
v[componentKey] = append(v[componentKey], func(c Components[string]) (Components[string], bool) {
return c, c.Name != componentName
}) })
handleComponentHook.Store(scene, v) handleComponentHook.Store(scene, v)
} }
func (h *Handle) ReplaceComponents(scene, name string, components Components[string]) { func (h *Handle) ReplaceComponents(scene, componentKey, componentName string, components Components[string]) {
v, _ := handleComponentHook.Load(scene) v, ok := handleComponentHook.Load(scene)
v = append(v, func(c Components[string]) (Components[string], bool) { if !ok {
if c.Name == name { v = make(map[string][]func(Components[string]) (Components[string], bool))
}
v[componentKey] = append(v[componentKey], func(c Components[string]) (Components[string], bool) {
if c.Name == componentName {
c = components c = components
} }
return c, true return c, true
}) })
handleComponentHook.Store(scene, v) handleComponentHook.Store(scene, v)
} }
func (h *Handle) HookComponents(scene string, fn func(Components[string]) (Components[string], bool)) { func (h *Handle) PushComponentHooks(scene, componentKey string, fn func(Components[string]) (Components[string], bool)) {
v, _ := handleComponentHook.Load(scene) v, ok := handleComponentHook.Load(scene)
v = append(v, fn) if !ok {
v = make(map[string][]func(Components[string]) (Components[string], bool))
}
v[componentKey] = append(v[componentKey], fn)
handleComponentHook.Store(scene, v) handleComponentHook.Store(scene, v)
} }
var GetComponents = reload.BuildMapFn[string]("scene-components", getComponent) var GetAndHookComponents = reload.BuildMapFnWithAnyParams[string]("calComponents", HookComponent)
var HookComponents = reload.BuildMapFnWithAnyParams[string]("calComponents", hookComponent)
func hookComponent(a ...any) []Components[string] { func HookComponent(a ...any) []Components[string] {
k := a[0].(string) componentKey := a[0].(string)
components := a[1].([]Components[string]) scene := a[1].(string)
mut := reload.GetGlobeMutex() mut := reload.GetGlobeMutex()
mut.Lock() mut.Lock()
allHooks := slice.FilterAndToMap(components, func(t Components[string], _ int) (string, []func(Components[string]) (Components[string], bool), bool) { defer mut.Unlock()
fn, ok := handleComponentHook.Load(k) components := GetComponents(scene, componentKey)
return k, fn, ok
})
mut.Unlock()
r := slice.FilterAndMap(components, func(component Components[string]) (Components[string], bool) { r := slice.FilterAndMap(components, func(component Components[string]) (Components[string], bool) {
hooks, ok := allHooks[k] keyHooks, ok := handleComponentHook.Load(scene)
if !ok { if !ok {
return component, true return component, true
} }
hooks := keyHooks[componentKey]
for _, fn := range hooks { for _, fn := range hooks {
hookedComponent, ok := fn(component) hookedComponent, ok := fn(component)
if !ok { // DeleteComponents fn if !ok { // DeleteComponents fn
@ -72,35 +79,23 @@ func hookComponent(a ...any) []Components[string] {
return r return r
} }
func getComponent(h *Handle) map[string][]Components[string] { func GetComponents(scene, key string) (r []Components[string]) {
mut := reload.GetGlobeMutex() sceneComponents, _ := handleComponents.Load(scene)
mut.Lock()
sceneComponents, _ := handleComponents.Load(h.scene)
allSceneComponents, _ := handleComponents.Load(constraints.AllScene) allSceneComponents, _ := handleComponents.Load(constraints.AllScene)
r = append(sceneComponents[key], allSceneComponents[key]...)
mut.Unlock() return
return maps.MergeBy(func(k string, c1, c2 []Components[string]) ([]Components[string], bool) {
vv := append(c1, c2...)
return vv, vv != nil
}, nil, sceneComponents, allSceneComponents)
} }
type cacheComponentParm[T any] struct { var CacheComponent = reload.BuildMapFnWithAnyParams[string]("cacheComponents", cacheComponentFn)
Components[T]
h *Handle func cacheComponentFn(a ...any) string {
return a[0].(Components[string]).Fn(a[1].(*Handle))
} }
var cacheComponentsFn = reload.BuildMapFn[string]("cacheComponents", cacheComponentFn) func CalComponent(h *Handle) func(string) string {
return func(componentKey string) string {
func cacheComponentFn(a cacheComponentParm[string]) string { cacheKey := str.Join("get-hook-Components-", h.scene, "-", componentKey)
return a.Fn(a.h) hookedComponents := GetAndHookComponents(cacheKey, componentKey, h.scene)
}
func CalComponents(h *Handle) {
allComponents := GetComponents(str.Join("allScene-", h.scene), h)
for k, components := range allComponents {
key := str.Join("calComponents-", h.theme, "-", h.scene, "-", k)
hookedComponents := HookComponents(key, k, components)
var s = make([]string, 0, len(hookedComponents)) var s = make([]string, 0, len(hookedComponents))
for _, component := range hookedComponents { for _, component := range hookedComponents {
if component.Val != "" { if component.Val != "" {
@ -110,7 +105,8 @@ func CalComponents(h *Handle) {
if component.Fn != nil { if component.Fn != nil {
v := "" v := ""
if component.Cached { if component.Cached {
v = cacheComponentsFn(component.Name, cacheComponentParm[string]{component, h}) key := str.Join(h.scene, "-", componentKey, "-", component.Name)
v = CacheComponent(key, component, h)
} else { } else {
v = component.Fn(h) v = component.Fn(h)
} }
@ -119,7 +115,7 @@ func CalComponents(h *Handle) {
} }
} }
} }
h.ginH[k] = strings.Join(s, "\n") return strings.Join(s, "\n")
} }
} }

View File

@ -41,7 +41,7 @@ var archivesConfig = map[any]any{
} }
var GetArchiveConf = BuildconfigFn(archivesConfig, "widget_archives", int64(2)) var GetArchiveConf = BuildconfigFn(archivesConfig, "widget_archives", int64(2))
var GetArchiveArgs = reload.BuildValFnWithAnyParams("", archiveArgsFn) var GetArchiveArgs = reload.BuildValFnWithAnyParams("widget_archive-args", archiveArgsFn)
func archiveArgsFn(a ...any) map[string]string { func archiveArgsFn(a ...any) map[string]string {
h := a[0].(*wp.Handle) h := a[0].(*wp.Handle)

View File

@ -1,8 +1,6 @@
{{define "common/head"}} {{define "common/head"}}
{{if .headScript}} {{ callFuncString .calComponent "headScript"}}
{{.headScript|unescaped}}
{{end}}
{{if .externHead}} {{if .externHead}}
{{.externHead|unescaped}} {{.externHead|unescaped}}
@ -10,9 +8,7 @@
{{end}} {{end}}
{{define "common/footer"}} {{define "common/footer"}}
{{if .footerScript}} {{ callFuncString .calComponent "footerScript"}}
{{.footerScript|unescaped}}
{{end}}
{{if .externFooter}} {{if .externFooter}}
{{.externFooter|unescaped}} {{.externFooter|unescaped}}
{{end}} {{end}}
@ -20,9 +16,7 @@
{{define "common/sidebarWidget"}} {{define "common/sidebarWidget"}}
{{if .sidebarsWidgets}} {{ callFuncString .calComponent "sidebarsWidgets"}}
{{.sidebarsWidgets|unescaped}}
{{end}}
{{end}} {{end}}
{{define "common/colophon"}} {{define "common/colophon"}}

View File

@ -56,7 +56,7 @@ func (h *Handle) Components() *safety.Map[string, map[string][]Components[string
return handleComponents return handleComponents
} }
func (h *Handle) ComponentHook() *safety.Map[string, []func(Components[string]) (Components[string], bool)] { func (h *Handle) ComponentHook() *safety.Map[string, map[string][]func(Components[string]) (Components[string], bool)] {
return handleComponentHook return handleComponentHook
} }
@ -99,9 +99,6 @@ func SetConfigHandle(a ...any) Handle {
configFn := a[0].(func(*Handle)) configFn := a[0].(func(*Handle))
hh := a[1].(*Handle) hh := a[1].(*Handle)
h := &Handle{} h := &Handle{}
mut := reload.GetGlobeMutex()
mut.Lock()
defer mut.Unlock()
handleComponents.Flush() handleComponents.Flush()
componentsArgs.Flush() componentsArgs.Flush()
handleComponentHook.Flush() handleComponentHook.Flush()
@ -120,10 +117,11 @@ func SetConfigHandle(a ...any) Handle {
if ok { if ok {
pluginFn(h) pluginFn(h)
} }
reload.Reload()
return *h return *h
} }
var GetInitHandleFn = reload.BuildValFnWithAnyParams("themeArgAndConfig", SetConfigHandle, 100.01) var GetInitHandleFn = reload.BuildValFnWithAnyParams("themeArgAndConfig", SetConfigHandle, false)
type ConfigParm struct { type ConfigParm struct {
ConfigFn func(*Handle) ConfigFn func(*Handle)
@ -136,6 +134,7 @@ func InitHandle(configFn func(*Handle), h *Handle) {
h.ginH["calPostClass"] = postClass(h) h.ginH["calPostClass"] = postClass(h)
h.ginH["calBodyClass"] = bodyClass(h) h.ginH["calBodyClass"] = bodyClass(h)
h.ginH["customLogo"] = customLogo(h) h.ginH["customLogo"] = customLogo(h)
h.ginH["calComponent"] = CalComponent(h)
h.isInited = true h.isInited = true
} }
@ -246,7 +245,6 @@ func (h *Handle) PushHandlers(pipeScene string, call HandleCall, statsOrScene ..
func (h *Handle) CommonComponents() { func (h *Handle) CommonComponents() {
h.PushCacheGroupHeadScript(constraints.AllScene, "siteIconAndCustomCss", 0, CalSiteIcon, CalCustomCss) h.PushCacheGroupHeadScript(constraints.AllScene, "siteIconAndCustomCss", 0, CalSiteIcon, CalCustomCss)
h.PushRender(constraints.AllStats, NewHandleFn(CalComponents, 10.001, "wp.CalComponents"))
h.PushRender(constraints.AllStats, NewHandleFn(PreRenderTemplate, 0, "wp.PreRenderTemplate")) h.PushRender(constraints.AllStats, NewHandleFn(PreRenderTemplate, 0, "wp.PreRenderTemplate"))
ReplyCommentJs(h) ReplyCommentJs(h)
AdditionScript(h) AdditionScript(h)

View File

@ -61,7 +61,9 @@ func DeleteMapVal[T any](namespace string, key ...T) {
fn(key) fn(key)
} }
func Specifies(namespaces ...string) { func Reloads(namespaces ...string) {
mut.Lock()
defer mut.Unlock()
for _, namespace := range namespaces { for _, namespace := range namespaces {
fn, ok := callMap.Load(namespace) fn, ok := callMap.Load(namespace)
if !ok { if !ok {
@ -93,7 +95,7 @@ func BuildMapFnWithConfirm[K comparable, V, A any](namespace string, fn func(A)
} }
} }
// BuildMapFn build given fn with a new fn which returned value can be saved and flushed when called Reload or Specifies // BuildMapFn build given fn with a new fn which returned value can be saved and flushed when called Reload or Reloads
// with namespace // with namespace
// //
// if give a float then can be reloaded early or lately, more bigger more earlier // if give a float then can be reloaded early or lately, more bigger more earlier
@ -153,8 +155,7 @@ func BuildSafetyMap[K comparable, V, A any](namespace string, args ...any) *Safe
return m return m
} }
m = &SafetyMap[K, V, A]{safety.NewMap[K, V](), sync.Mutex{}} m = &SafetyMap[K, V, A]{safety.NewMap[K, V](), sync.Mutex{}}
ord, _ := parseArgs(args...) args = append(args, namespace)
autoFlush := helper.ParseArgs(true, args...)
deleteMapFn.Store(namespace, func(a any) { deleteMapFn.Store(namespace, func(a any) {
k, ok := a.([]K) k, ok := a.([]K)
if !ok && len(k) > 0 { if !ok && len(k) > 0 {
@ -164,13 +165,8 @@ func BuildSafetyMap[K comparable, V, A any](namespace string, args ...any) *Safe
m.Val.Delete(key) m.Val.Delete(key)
} }
}) })
if autoFlush { Push(m.Val.Flush, args...)
Push(func() {
m.Val.Flush()
}, ord, namespace)
}
safetyMaps.Store(namespace, m) safetyMaps.Store(namespace, m)
return m return m
} }
@ -198,22 +194,19 @@ func BuildAnyVal[T, A any](namespace string, counter bool, args ...any) *SafetyV
vvv, ok := safetyMaps.Load(namespace) vvv, ok := safetyMaps.Load(namespace)
if ok { if ok {
vv = vvv.(*SafetyVar[T, A]) vv = vvv.(*SafetyVar[T, A])
} else {
safetyMapLock.Lock()
defer safetyMapLock.Unlock()
vvv, ok = safetyMaps.Load(namespace)
if ok {
vv = vvv.(*SafetyVar[T, A])
} else {
v := Val[T]{}
vv = &SafetyVar[T, A]{safety.NewVar(v), sync.Mutex{}}
ord, _ := parseArgs(args...)
Push(func() {
vv.Val.Flush()
}, ord, namespace)
safetyMaps.Store(namespace, vv)
}
} }
safetyMapLock.Lock()
defer safetyMapLock.Unlock()
vvv, ok = safetyMaps.Load(namespace)
if ok {
vv = vvv.(*SafetyVar[T, A])
return vv
}
v := Val[T]{}
vv = &SafetyVar[T, A]{safety.NewVar(v), sync.Mutex{}}
args = append(args, namespace)
Push(vv.Val.Flush, args...)
safetyMaps.Store(namespace, vv)
return vv return vv
} }
@ -272,14 +265,14 @@ func BuildValFnWithConfirm[T, A any](namespace string, fn func(A) (T, bool), arg
} }
} }
// BuildValFn build given fn a new fn which return value can be saved and flushed when called Reload or Specifies // BuildValFn build given fn a new fn which return value can be saved and flushed when called Reload or Reloads
// with namespace. // with namespace.
// //
// note: namespace should be not same as BuildMapFn and related fn, they stored same safety.Map[string,any]. // note: namespace should be not same as BuildMapFn and related fn, they stored same safety.Map[string,any].
// //
// if give a float then can be reloaded early or lately, more bigger more earlier // if give a float then can be reloaded early or lately, more bigger more earlier
// //
// if give a bool false will not flushed when called Reload, then can called GetValMap to flush manually // if give a bool false will not flushed when called Reload, but can call GetValMap or Reloads to flush manually
func BuildValFn[T, A any](namespace string, fn func(A) T, args ...any) func(A) T { func BuildValFn[T, A any](namespace string, fn func(A) T, args ...any) func(A) T {
var vv = BuildAnyVal[T, A](namespace, false, args...) var vv = BuildAnyVal[T, A](namespace, false, args...)
return func(a A) T { return func(a A) T {
@ -325,15 +318,17 @@ func BuildValFnWithAnyParams[T any](namespace string, fn func(...any) T, args ..
// //
// args same as Push // args same as Push
// //
// if give a name, then can be flushed by calls Specifies // if give a name, then can be flushed by calls Reloads
// //
// if give a float then can be reloaded early or lately, more bigger more earlier // if give a float then can be reloaded early or lately, more bigger more earlier
//
// if give a bool false will not flushed when called Reload, but can call GetValMap or Reloads to flush manually
func Vars[T any](defaults T, args ...any) *safety.Var[T] { func Vars[T any](defaults T, args ...any) *safety.Var[T] {
ss := safety.NewVar(defaults) ss := safety.NewVar(defaults)
ord, name := parseArgs(args...)
Push(func() { Push(func() {
ss.Store(defaults) ss.Store(defaults)
}, ord, name) }, args...)
return ss return ss
} }
@ -356,13 +351,12 @@ func parseArgs(a ...any) (ord float64, name string) {
// VarsBy // VarsBy
// //
// args same as Push // args same as Push
// if give a name, then can be flushed by calls Specifies // if give a name, then can be flushed by calls Reloads
func VarsBy[T any](fn func() T, args ...any) *safety.Var[T] { func VarsBy[T any](fn func() T, args ...any) *safety.Var[T] {
ss := safety.NewVar(fn()) ss := safety.NewVar(fn())
ord, name := parseArgs(args...)
Push(func() { Push(func() {
ss.Store(fn()) ss.Store(fn())
}, ord, name) }, args...)
return ss return ss
} }
func MapBy[K comparable, T any](fn func(*safety.Map[K, T]), args ...any) *safety.Map[K, T] { func MapBy[K comparable, T any](fn func(*safety.Map[K, T]), args ...any) *safety.Map[K, T] {
@ -370,32 +364,35 @@ func MapBy[K comparable, T any](fn func(*safety.Map[K, T]), args ...any) *safety
if fn != nil { if fn != nil {
fn(m) fn(m)
} }
ord, name := parseArgs(args...)
Push(func() { Push(func() {
m.Flush() m.Flush()
if fn != nil { if fn != nil {
fn(m) fn(m)
} }
}, ord, name) }, args...)
return m return m
} }
func SafeMap[K comparable, T any](args ...any) *safety.Map[K, T] { func SafeMap[K comparable, T any](args ...any) *safety.Map[K, T] {
m := safety.NewMap[K, T]() m := safety.NewMap[K, T]()
ord, name := parseArgs(args...) Push(m.Flush, args...)
Push(func() {
m.Flush()
}, ord, name)
return m return m
} }
// Push the func that will be called whenever Reload called // Push the func that will be called whenever Reload called
// //
// if give a name, then can be called by called Specifies // if give a name, then can be called by called Reloads
// //
// if give a float then can be called early or lately when called Reload, more bigger more earlier // if give a float then can be called early or lately when called Reload, more bigger more earlier
//
// if give a bool false will not flushed when called Reload, then can called GetValMap to flush manually
func Push(fn func(), a ...any) { func Push(fn func(), a ...any) {
ord, name := parseArgs(a...) ord, name := parseArgs(a...)
auto := helper.ParseArgs(true, a...)
if name != "" && !auto {
callMap.Store(name, fn)
return
}
waitReloadCalls.Append(queue{fn, ord, name}) waitReloadCalls.Append(queue{fn, ord, name})
if name != "" { if name != "" {
callMap.Store(name, fn) callMap.Store(name, fn)
@ -405,7 +402,6 @@ func Push(fn func(), a ...any) {
func Reload() { func Reload() {
mut.Lock() mut.Lock()
defer mut.Unlock() defer mut.Unlock()
callMap.Flush()
deleteMapFn.Flush() deleteMapFn.Flush()
reloadCalls := waitReloadCalls.Load() reloadCalls := waitReloadCalls.Load()
slice.SimpleSort(reloadCalls, slice.DESC, func(t queue) float64 { slice.SimpleSort(reloadCalls, slice.DESC, func(t queue) float64 {

View File

@ -20,7 +20,7 @@ func TestFlushMapVal(t *testing.T) {
return 33, true return 33, true
}) })
fmt.Println(v) fmt.Println(v)
Specifies("key") Reloads("key")
v = GetAnyValMapBy[int, int, struct{}]("key", 2, struct{}{}, func(a struct{}) (int, bool) { v = GetAnyValMapBy[int, int, struct{}]("key", 2, struct{}{}, func(a struct{}) (int, bool) {
fmt.Println("yyyy") fmt.Println("yyyy")
return 33, true return 33, true