From 5057111878c1ca59d8bf431eb2610640ba695097 Mon Sep 17 00:00:00 2001 From: "pzrr@qq.com" Date: Tue, 23 Jan 2018 18:40:22 +0800 Subject: [PATCH 1/5] =?UTF-8?q?####=20Version=201.4.8=20*=20=E8=B0=83?= =?UTF-8?q?=E6=95=B4=EF=BC=9ADotweb.AppContext=E5=8F=98=E6=9B=B4=E4=B8=BAD?= =?UTF-8?q?otweb.Items=20*=20=E8=B0=83=E6=95=B4=EF=BC=9AHttpContext.AppCon?= =?UTF-8?q?text=E5=8F=98=E6=9B=B4=E4=B8=BAHttpContext.AppItems=20*=20?= =?UTF-8?q?=E6=96=B0=E5=A2=9Econfig.ConfigSet\config.ParseConfigSetXML\Par?= =?UTF-8?q?seConfigSetJSON\ParseConfigSetYaml=EF=BC=8C=E7=94=A8=E4=BA=8E?= =?UTF-8?q?=E8=A7=A3=E6=9E=90=E5=B8=B8=E8=A7=84Key\Value=E6=A0=BC=E5=BC=8F?= =?UTF-8?q?=E7=9A=84=E9=85=8D=E7=BD=AE=E6=96=87=E4=BB=B6=20*=20=E6=96=B0?= =?UTF-8?q?=E5=A2=9EDotweb.IncludeConfigSetXML\IncludeConfigSetJSON\Includ?= =?UTF-8?q?eConfigSetYaml=EF=BC=8C=E8=A7=A3=E6=9E=90=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E5=90=8E=E7=BD=AE=E5=85=A5Dotweb.Items=EF=BC=8C=E5=8F=AF?= =?UTF-8?q?=E9=80=9A=E8=BF=87HttpContext.AppItems().Get()=E8=8E=B7?= =?UTF-8?q?=E5=8F=96=20*=20Include\ParseConfigSetXML:=E6=94=AF=E6=8C=81xml?= =?UTF-8?q?=E6=A0=BC=E5=BC=8F=E6=96=87=E4=BB=B6=E8=A7=A3=E6=9E=90=20*=20In?= =?UTF-8?q?clude\ParseConfigSetJSON:=E6=94=AF=E6=8C=81json=E6=A0=BC?= =?UTF-8?q?=E5=BC=8F=E6=96=87=E4=BB=B6=E8=A7=A3=E6=9E=90=20*=20Include\Par?= =?UTF-8?q?seConfigSetYaml:=E6=94=AF=E6=8C=81yaml=E6=A0=BC=E5=BC=8F?= =?UTF-8?q?=E6=96=87=E4=BB=B6=E8=A7=A3=E6=9E=90=20*=20=E5=85=B7=E4=BD=93?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=96=87=E4=BB=B6=E6=A0=BC=E5=BC=8F=E5=8F=AF?= =?UTF-8?q?=E5=8F=82=E8=80=83example/configset=20*=20=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E7=A4=BA=E4=BE=8B=E4=BB=A3=E7=A0=81=20example/configset=20*=20?= =?UTF-8?q?2018-01-23=2019:00?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/configs.go | 12 +++---- config/configset.go | 63 ++++++++++++++++++++++++++++++++++ const/const.go | 2 +- context.go | 6 ++-- dotweb.go | 45 ++++++++++++++++++++++-- example/appcontext/main.go | 59 ------------------------------- example/configset/main.go | 49 ++++++++++++++++++++++++++ example/configset/userconf.xml | 7 ++++ example/main.go | 4 +-- version.MD | 12 +++++++ 10 files changed, 186 insertions(+), 73 deletions(-) create mode 100644 config/configset.go delete mode 100644 example/appcontext/main.go create mode 100644 example/configset/main.go create mode 100644 example/configset/userconf.xml diff --git a/config/configs.go b/config/configs.go index 129c69b..a13e36b 100644 --- a/config/configs.go +++ b/config/configs.go @@ -86,8 +86,8 @@ type ( ) const ( - ConfigType_Xml = "xml" - ConfigType_Json = "json" + ConfigType_XML = "xml" + ConfigType_JSON = "json" ConfigType_Yaml = "yaml" ) @@ -151,15 +151,15 @@ func InitConfig(configFile string, confType ...interface{}) (config *Config, err } } - cType := ConfigType_Xml - if len(confType) > 0 && confType[0] == ConfigType_Json { - cType = ConfigType_Json + cType := ConfigType_XML + if len(confType) > 0 && confType[0] == ConfigType_JSON { + cType = ConfigType_JSON } if len(confType) > 0 && confType[0] == ConfigType_Yaml { cType = ConfigType_Yaml } - if cType == ConfigType_Xml { + if cType == ConfigType_XML { config, err = initConfig(realFile, cType, UnmarshalXML) } else if cType == ConfigType_Yaml { config, err = initConfig(realFile, cType, UnmarshalYaml) diff --git a/config/configset.go b/config/configset.go new file mode 100644 index 0000000..92215ed --- /dev/null +++ b/config/configset.go @@ -0,0 +1,63 @@ +package config + +import ( + "encoding/xml" + "github.com/devfeel/dotweb/core" + "io/ioutil" + "errors" +) + +type( + //单元配置节点 + ConfigSetNode struct{ + Key string `xml:"key,attr"` + Value string `xml:"value,attr"` + } + + //单元配置组,包含一系列单元配置节点 + ConfigSet struct{ + XMLName xml.Name `xml:"config" json:"-" yaml:"-"` + Name string `xml:"name,attr"` + ConfigSetNodes []*ConfigSetNode `xml:"set"` + } +) + +// ParseConfigSetXML include ConfigSet xml file +func ParseConfigSetXML(configFile string) (*core.ItemContext, error){ + return parseConfigSetFile(configFile, ConfigType_XML) +} + +// ParseConfigSetJSON include ConfigSet json file +func ParseConfigSetJSON(configFile string) (*core.ItemContext, error){ + return parseConfigSetFile(configFile, ConfigType_JSON) +} + +// ParseConfigSetYaml include ConfigSet yaml file +func ParseConfigSetYaml(configFile string) (*core.ItemContext, error){ + return parseConfigSetFile(configFile, ConfigType_Yaml) +} + +func parseConfigSetFile(configFile string, confType string) (*core.ItemContext, error){ + content, err := ioutil.ReadFile(configFile) + if err != nil { + return nil, errors.New("DotWeb:Config:parseConfigSetFile 配置文件[" + configFile + ", "+confType+"]无法解析 - " + err.Error()) + } + set :=new(ConfigSet) + if confType == ConfigType_XML { + err = UnmarshalXML(content, set) + } + if confType == ConfigType_JSON{ + err = UnmarshalJSON(content, set) + } + if confType == ConfigType_Yaml{ + err = UnmarshalYaml(content, set) + } + if err!=nil{ + return nil, errors.New("DotWeb:Config:parseConfigSetFile 配置文件[" + configFile + ", "+confType+"]无法解析 - " + err.Error()) + } + item := core.NewItemContext() + for _,s:=range set.ConfigSetNodes{ + item.Set(s.Key, s.Value) + } + return item, nil +} \ No newline at end of file diff --git a/const/const.go b/const/const.go index 338a9de..9b6834e 100644 --- a/const/const.go +++ b/const/const.go @@ -2,5 +2,5 @@ package _const //dotweb const const ( - Version = "1.4.7" + Version = "1.4.8" ) diff --git a/context.go b/context.go index 0f5b443..7eff493 100644 --- a/context.go +++ b/context.go @@ -39,7 +39,7 @@ type ( RouterNode() RouterNode RouterParams() Params Handler() HttpHandle - AppContext() *core.ItemContext + AppItems() *core.ItemContext Cache() cache.Cache Items() *core.ItemContext AppSetConfig() *core.ItemContext @@ -225,9 +225,9 @@ func (ctx *HttpContext) Features() *xFeatureTools { // AppContext get application's global appcontext // issue #3 -func (ctx *HttpContext) AppContext() *core.ItemContext { +func (ctx *HttpContext) AppItems() *core.ItemContext { if ctx.HttpServer != nil { - return ctx.httpServer.DotApp.AppContext + return ctx.httpServer.DotApp.Items } else { return core.NewItemContext() } diff --git a/dotweb.go b/dotweb.go index 46556d0..adce062 100644 --- a/dotweb.go +++ b/dotweb.go @@ -33,7 +33,7 @@ type ( ExceptionHandler ExceptionHandle NotFoundHandler StandardHandle // NotFoundHandler 支持自定义404处理代码能力 MethodNotAllowedHandler StandardHandle // MethodNotAllowedHandler fixed for #64 增加MethodNotAllowed自定义处理 - AppContext *core.ItemContext + Items *core.ItemContext middlewareMap map[string]MiddlewareFunc middlewareMutex *sync.RWMutex StartMode string @@ -52,6 +52,7 @@ type ( const ( DefaultHTTPPort = 8080 //DefaultHTTPPort default http port; fixed for #70 UPDATE default http port 80 to 8080 + DefaultConfigSetGroupName = "default" RunMode_Development = "development" RunMode_Production = "production" @@ -65,7 +66,7 @@ func New() *DotWeb { HttpServer: NewHttpServer(), OfflineServer: servers.NewOfflineServer(), Middlewares: make([]Middleware, 0), - AppContext: core.NewItemContext(), + Items: core.NewItemContext(), Config: config.NewConfig(), middlewareMap: make(map[string]MiddlewareFunc), middlewareMutex: new(sync.RWMutex), @@ -122,6 +123,46 @@ func (app *DotWeb) SetCache(ca cache.Cache) { app.cache = ca } +// IncludeConfigSetXML include ConfigSet xml file to Dotweb.Items +// same key will cover oldest value +func (app *DotWeb) IncludeConfigSetXML(configFile string) error{ + item, err:=config.ParseConfigSetXML(configFile) + if err!= nil{ + return err + } + for k,v:=range item.GetCurrentMap(){ + app.Items.Set(k, v) + } + return nil +} + +// IncludeConfigSetJSON include ConfigSet json file to Dotweb.Items +// same key will cover oldest value +func (app *DotWeb) IncludeConfigSetJSON(configFile string) error{ + item, err:=config.ParseConfigSetXML(configFile) + if err!= nil{ + return err + } + for k,v:=range item.GetCurrentMap(){ + app.Items.Set(k, v) + } + return nil +} + +// IncludeConfigSetYaml include ConfigSet ymal file to Dotweb.Items +// same key will cover oldest value +func (app *DotWeb) IncludeConfigSetYaml(configFile string) error{ + item, err:=config.ParseConfigSetXML(configFile) + if err!= nil{ + return err + } + for k,v:=range item.GetCurrentMap(){ + app.Items.Set(k, v) + } + return nil +} + + // RunMode current app run mode, if not set, default set RunMode_Development func (app *DotWeb) RunMode() string { if app.Config.App.RunMode != RunMode_Development && app.Config.App.RunMode != RunMode_Production { diff --git a/example/appcontext/main.go b/example/appcontext/main.go deleted file mode 100644 index 1d063e9..0000000 --- a/example/appcontext/main.go +++ /dev/null @@ -1,59 +0,0 @@ -package main - -import ( - "fmt" - "github.com/devfeel/dotweb" - "github.com/devfeel/dotweb/framework/file" - "strconv" -) - -func main() { - //初始化DotServer - app := dotweb.New() - - //设置dotserver日志目录 - app.SetLogPath(file.GetCurrentDirectory()) - - //设置路由 - InitRoute(app.HttpServer) - - //启动 监控服务 - //app.SetPProfConfig(true, 8081) - - //全局容器 - app.AppContext.Set("gstring", "gvalue") - app.AppContext.Set("gint", 1) - - // 开始服务 - port := 8080 - fmt.Println("dotweb.StartServer => " + strconv.Itoa(port)) - err := app.StartServer(port) - fmt.Println("dotweb.StartServer error => ", err) -} - -type TestContext struct { - UserName string - Sex int -} - -//you can curl http://127.0.0.1:8080/ -func Index(ctx dotweb.Context) error { - gstring := ctx.AppContext().GetString("gstring") - gint := ctx.AppContext().GetInt("gint") - ctx.AppContext().Set("index", "index-v") - ctx.AppContext().Set("user", "user-v") - return ctx.WriteString("index -> " + gstring + ";" + strconv.Itoa(gint)) -} - -//you can curl http://127.0.0.1:8080/2 -func Index2(ctx dotweb.Context) error { - gindex := ctx.AppContext().GetString("index") - ctx.AppContext().Remove("index") - user, _ := ctx.AppContext().Once("user") - return ctx.WriteString("index -> " + gindex + ";" + fmt.Sprint(user)) -} - -func InitRoute(server *dotweb.HttpServer) { - server.Router().GET("/", Index) - server.Router().GET("/2", Index2) -} diff --git a/example/configset/main.go b/example/configset/main.go new file mode 100644 index 0000000..501f715 --- /dev/null +++ b/example/configset/main.go @@ -0,0 +1,49 @@ +package main + +import ( + "fmt" + "github.com/devfeel/dotweb" + "github.com/devfeel/dotweb/framework/file" + "strconv" +) + +func main() { + //初始化DotServer + app := dotweb.New() + + //设置dotserver日志目录 + app.SetLogPath(file.GetCurrentDirectory()) + + app.SetDevelopmentMode() + + app.HttpServer.SetEnabledIgnoreFavicon(true) + + + //引入自定义ConfigSet + err := app.IncludeConfigSetXML("d:/gotmp/userconf.xml") + if err!=nil{ + fmt.Println(err.Error()) + return + } + + //设置路由 + InitRoute(app.HttpServer) + + // 开始服务 + port := 8080 + fmt.Println("dotweb.StartServer => " + strconv.Itoa(port)) + err = app.StartServer(port) + fmt.Println("dotweb.StartServer error => ", err) +} + +func ConfigSet(ctx dotweb.Context) error { + vkey1 := ctx.AppItems().GetString("set1") + vkey2 := ctx.AppItems().GetString("set2") + ctx.WriteString(ctx.Request().Path(), "key1=", vkey1, "key2=", vkey2) + return ctx.WriteString("\r\n") +} + + +func InitRoute(server *dotweb.HttpServer) { + server.GET("/c", ConfigSet) +} \ No newline at end of file diff --git a/example/configset/userconf.xml b/example/configset/userconf.xml new file mode 100644 index 0000000..f5fb674 --- /dev/null +++ b/example/configset/userconf.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/example/main.go b/example/main.go index b1f79b6..19a1424 100644 --- a/example/main.go +++ b/example/main.go @@ -65,8 +65,8 @@ func main() { app.SetPProfConfig(true, 8081) //全局容器 - app.AppContext.Set("gstring", "gvalue") - app.AppContext.Set("gint", 1) + app.Items.Set("gstring", "gvalue") + app.Items.Set("gint", 1) // 开始服务 port := 8080 diff --git a/version.MD b/version.MD index 31cce20..f5e4687 100644 --- a/version.MD +++ b/version.MD @@ -1,5 +1,17 @@ ## dotweb版本记录: +#### Version 1.4.8 +* 调整:Dotweb.AppContext变更为Dotweb.Items +* 调整:HttpContext.AppContext变更为HttpContext.AppItems +* 新增config.ConfigSet\config.ParseConfigSetXML\ParseConfigSetJSON\ParseConfigSetYaml,用于解析常规Key\Value格式的配置文件 +* 新增Dotweb.IncludeConfigSetXML\IncludeConfigSetJSON\IncludeConfigSetYaml,解析配置后置入Dotweb.Items,可通过HttpContext.AppItems().Get()获取 +* Include\ParseConfigSetXML:支持xml格式文件解析 +* Include\ParseConfigSetJSON:支持json格式文件解析 +* Include\ParseConfigSetYaml:支持yaml格式文件解析 +* 具体配置文件格式可参考example/configset +* 新增示例代码 example/configset +* 2018-01-23 19:00 + #### Version 1.4.7 * BUG Fixed: 修复Middleware特定场景下无效问题 * 新增dotweb.IncludeDotwebGroup,用于自动集成dotweb相关路由 From bbf8023fdd1d45ba52f3e2f27f08009543cfdf09 Mon Sep 17 00:00:00 2001 From: "pzrr@qq.com" Date: Wed, 24 Jan 2018 22:29:29 +0800 Subject: [PATCH 2/5] =?UTF-8?q?####=20Version=201.4.8=20*=20=E8=B0=83?= =?UTF-8?q?=E6=95=B4=EF=BC=9AItemContext=E6=9B=B4=E5=90=8D=E4=B8=BAItemMap?= =?UTF-8?q?=EF=BC=8C=E6=96=B0=E5=A2=9EConcurrenceMap=E3=80=81ReadonlyMap?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3=20*=20=E8=B0=83=E6=95=B4=EF=BC=9ADotweb.AppC?= =?UTF-8?q?ontext=E5=8F=98=E6=9B=B4=E4=B8=BADotweb.Items=20*=20=E8=B0=83?= =?UTF-8?q?=E6=95=B4=EF=BC=9AHttpContext.AppContext=E5=8F=98=E6=9B=B4?= =?UTF-8?q?=E4=B8=BAHttpContext.AppItems=20*=20=E8=B0=83=E6=95=B4=EF=BC=9A?= =?UTF-8?q?HttpContext.AppSetConfig=E5=8F=98=E6=9B=B4=E4=B8=BAHttpContext.?= =?UTF-8?q?ConfigSet=20*=20=E8=B0=83=E6=95=B4=EF=BC=9Aconfig.AppSet?= =?UTF-8?q?=E5=8F=98=E6=9B=B4=E4=B8=BAconfig.ConfigSet=20*=20=E6=96=B0?= =?UTF-8?q?=E5=A2=9E:=20config.ParseConfigSetXML\ParseConfigSetJSON\ParseC?= =?UTF-8?q?onfigSetYaml=EF=BC=8C=E7=94=A8=E4=BA=8E=E8=A7=A3=E6=9E=90?= =?UTF-8?q?=E5=B8=B8=E8=A7=84Key\Value=E6=A0=BC=E5=BC=8F=E7=9A=84=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=E6=96=87=E4=BB=B6=20*=20=E6=96=B0=E5=A2=9E=EF=BC=9Aco?= =?UTF-8?q?nfig.Config.IncludeConfigSet=EF=BC=8C=E7=94=A8=E4=BA=8E?= =?UTF-8?q?=E5=90=91config.ConfigSet=E4=B8=AD=E5=AF=BC=E5=85=A5Key\Value?= =?UTF-8?q?=E6=A0=BC=E5=BC=8F=E7=9A=84=E9=85=8D=E7=BD=AE=E6=96=87=E4=BB=B6?= =?UTF-8?q?=EF=BC=8C=E9=80=9A=E8=BF=87HttpContext.ConfigSet=E8=8E=B7?= =?UTF-8?q?=E5=8F=96=E7=9B=B8=E5=85=B3=E8=AE=BE=E7=BD=AE=E4=BF=A1=E6=81=AF?= =?UTF-8?q?=20*=20ParseConfigSetXML:=E6=94=AF=E6=8C=81xml=E6=A0=BC?= =?UTF-8?q?=E5=BC=8F=E6=96=87=E4=BB=B6=E8=A7=A3=E6=9E=90=EF=BC=8C=E8=BF=94?= =?UTF-8?q?=E5=9B=9Ecore.ConcurrenceMap=20*=20ParseConfigSetJSON:=E6=94=AF?= =?UTF-8?q?=E6=8C=81json=E6=A0=BC=E5=BC=8F=E6=96=87=E4=BB=B6=E8=A7=A3?= =?UTF-8?q?=E6=9E=90=EF=BC=8C=E8=BF=94=E5=9B=9Ecore.ConcurrenceMap=20*=20P?= =?UTF-8?q?arseConfigSetYaml:=E6=94=AF=E6=8C=81yaml=E6=A0=BC=E5=BC=8F?= =?UTF-8?q?=E6=96=87=E4=BB=B6=E8=A7=A3=E6=9E=90=EF=BC=8C=E8=BF=94=E5=9B=9E?= =?UTF-8?q?core.ConcurrenceMap=20*=20=E5=85=B7=E4=BD=93=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E6=96=87=E4=BB=B6=E6=A0=BC=E5=BC=8F=E5=8F=AF=E5=8F=82=E8=80=83?= =?UTF-8?q?example/configset=20*=20=E6=96=B0=E5=A2=9E=E7=A4=BA=E4=BE=8B?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=20example/configset=20*=202018-01-24=2022:00?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/configs.go | 71 ++++++--- config/configset.go | 48 +++--- context.go | 49 +++--- core/concurrenceMap.go | 145 ++++++++++++++++++ ...context_test.go => concurrenceMap_test.go} | 51 +++--- core/context.go | 108 ------------- core/state.go | 26 ++-- dotweb.go | 58 ++----- example/configset/main.go | 9 +- version.MD | 15 +- 10 files changed, 300 insertions(+), 280 deletions(-) create mode 100644 core/concurrenceMap.go rename core/{context_test.go => concurrenceMap_test.go} (64%) delete mode 100644 core/context.go diff --git a/config/configs.go b/config/configs.go index a13e36b..5d6a89b 100644 --- a/config/configs.go +++ b/config/configs.go @@ -10,16 +10,16 @@ import ( type ( Config struct { - XMLName xml.Name `xml:"config" json:"-" yaml:"-"` - App *AppNode `xml:"app"` - AppSets []*AppSetNode `xml:"appset>set"` - Offline *OfflineNode `xml:"offline"` - Server *ServerNode `xml:"server"` - Session *SessionNode `xml:"session"` - Routers []*RouterNode `xml:"routers>router"` - Groups []*GroupNode `xml:"groups>group"` - Middlewares []*MiddlewareNode `xml:"middlewares>middleware"` - AppSetConfig *core.ItemContext `json:"-" yaml:"-"` + XMLName xml.Name `xml:"config" json:"-" yaml:"-"` + App *AppNode `xml:"app"` + ConfigSetNodes []*ConfigSetNode `xml:"configset>set"` + Offline *OfflineNode `xml:"offline"` + Server *ServerNode `xml:"server"` + Session *SessionNode `xml:"session"` + Routers []*RouterNode `xml:"routers>router"` + Groups []*GroupNode `xml:"groups>group"` + Middlewares []*MiddlewareNode `xml:"middlewares>middleware"` + ConfigSet core.ReadonlyMap `json:"-" yaml:"-"` } OfflineNode struct { Offline bool `xml:"offline,attr"` //是否维护,默认false @@ -33,11 +33,6 @@ type ( PProfPort int `xml:"pprofport,attr"` //pprof-server 端口,不能与主Server端口相同 EnabledPProf bool `xml:"enabledpprof,attr"` //是否启用pprof server,默认不启用 } - //update for issue #16 配置文件 - AppSetNode struct { - Key string `xml:"key,attr"` - Value string `xml:"value,attr"` - } ServerNode struct { EnabledListDir bool `xml:"enabledlistdir,attr"` //设置是否启用目录浏览,仅对Router.ServerFile有效,若设置该项,则可以浏览目录文件,默认不开启 @@ -93,12 +88,40 @@ const ( func NewConfig() *Config { return &Config{ - App: NewAppNode(), - Offline: NewOfflineNode(), - Server: NewServerNode(), - Session: NewSessionNode(), - AppSetConfig: core.NewItemContext(), + App: NewAppNode(), + Offline: NewOfflineNode(), + Server: NewServerNode(), + Session: NewSessionNode(), + ConfigSet: core.NewReadonlyMap(), + } +} + +// IncludeConfigSetXML include ConfigSet file to Dotweb.Items +// same key will cover oldest value +// support xml\json\yaml +func (conf *Config) IncludeConfigSet(configFile string, confType string) error { + var parseItem core.ConcurrenceMap + var err error + if confType == ConfigType_XML { + parseItem, err = ParseConfigSetXML(configFile) + } + if confType == ConfigType_JSON { + parseItem, err = ParseConfigSetJSON(configFile) + } + if confType == ConfigType_Yaml { + parseItem, err = ParseConfigSetYaml(configFile) + } + if err != nil { + return err + } + items := conf.ConfigSet.(*core.ItemMap) + if items == nil { + return errors.New("init config items error") + } + for k, v := range parseItem.GetCurrentMap() { + items.Set(k, v) } + return nil } func NewAppNode() *AppNode { @@ -187,11 +210,11 @@ func InitConfig(configFile string, confType ...interface{}) (config *Config, err config.Offline = NewOfflineNode() } - tmpAppSetMap := core.NewItemContext() - for _, v := range config.AppSets { - tmpAppSetMap.Set(v.Key, v.Value) + tmpConfigSetMap := core.NewConcurrenceMap() + for _, v := range config.ConfigSetNodes { + tmpConfigSetMap.Set(v.Key, v.Value) } - config.AppSetConfig = tmpAppSetMap + config.ConfigSet = tmpConfigSetMap //deal config default value dealConfigDefaultSet(config) diff --git a/config/configset.go b/config/configset.go index 92215ed..c2fb71d 100644 --- a/config/configset.go +++ b/config/configset.go @@ -2,62 +2,62 @@ package config import ( "encoding/xml" + "errors" "github.com/devfeel/dotweb/core" "io/ioutil" - "errors" ) -type( - //单元配置节点 - ConfigSetNode struct{ - Key string `xml:"key,attr"` - Value string `xml:"value,attr"` - } - +type ( //单元配置组,包含一系列单元配置节点 - ConfigSet struct{ - XMLName xml.Name `xml:"config" json:"-" yaml:"-"` - Name string `xml:"name,attr"` + ConfigSet struct { + XMLName xml.Name `xml:"config" json:"-" yaml:"-"` + Name string `xml:"name,attr"` ConfigSetNodes []*ConfigSetNode `xml:"set"` } + + //update for issue #16 配置文件 + ConfigSetNode struct { + Key string `xml:"key,attr"` + Value string `xml:"value,attr"` + } ) // ParseConfigSetXML include ConfigSet xml file -func ParseConfigSetXML(configFile string) (*core.ItemContext, error){ +func ParseConfigSetXML(configFile string) (core.ConcurrenceMap, error) { return parseConfigSetFile(configFile, ConfigType_XML) } // ParseConfigSetJSON include ConfigSet json file -func ParseConfigSetJSON(configFile string) (*core.ItemContext, error){ +func ParseConfigSetJSON(configFile string) (core.ConcurrenceMap, error) { return parseConfigSetFile(configFile, ConfigType_JSON) } // ParseConfigSetYaml include ConfigSet yaml file -func ParseConfigSetYaml(configFile string) (*core.ItemContext, error){ +func ParseConfigSetYaml(configFile string) (core.ConcurrenceMap, error) { return parseConfigSetFile(configFile, ConfigType_Yaml) } -func parseConfigSetFile(configFile string, confType string) (*core.ItemContext, error){ +func parseConfigSetFile(configFile string, confType string) (core.ConcurrenceMap, error) { content, err := ioutil.ReadFile(configFile) if err != nil { - return nil, errors.New("DotWeb:Config:parseConfigSetFile 配置文件[" + configFile + ", "+confType+"]无法解析 - " + err.Error()) + return nil, errors.New("DotWeb:Config:parseConfigSetFile 配置文件[" + configFile + ", " + confType + "]无法解析 - " + err.Error()) } - set :=new(ConfigSet) + set := new(ConfigSet) if confType == ConfigType_XML { err = UnmarshalXML(content, set) } - if confType == ConfigType_JSON{ + if confType == ConfigType_JSON { err = UnmarshalJSON(content, set) } - if confType == ConfigType_Yaml{ + if confType == ConfigType_Yaml { err = UnmarshalYaml(content, set) } - if err!=nil{ - return nil, errors.New("DotWeb:Config:parseConfigSetFile 配置文件[" + configFile + ", "+confType+"]无法解析 - " + err.Error()) + if err != nil { + return nil, errors.New("DotWeb:Config:parseConfigSetFile 配置文件[" + configFile + ", " + confType + "]无法解析 - " + err.Error()) } - item := core.NewItemContext() - for _,s:=range set.ConfigSetNodes{ + item := core.NewConcurrenceMap() + for _, s := range set.ConfigSetNodes { item.Set(s.Key, s.Value) } return item, nil -} \ No newline at end of file +} diff --git a/context.go b/context.go index 7eff493..bc53811 100644 --- a/context.go +++ b/context.go @@ -13,8 +13,8 @@ import ( "github.com/devfeel/dotweb/session" "os" "path/filepath" - "time" "strconv" + "time" ) const ( @@ -39,11 +39,11 @@ type ( RouterNode() RouterNode RouterParams() Params Handler() HttpHandle - AppItems() *core.ItemContext + AppItems() core.ConcurrenceMap Cache() cache.Cache - Items() *core.ItemContext - AppSetConfig() *core.ItemContext - ViewData() *core.ItemContext + Items() core.ConcurrenceMap + ConfigSet() core.ReadonlyMap + ViewData() core.ConcurrenceMap SessionID() string Session() (state *session.SessionState) Hijack() (*HijackConn, error) @@ -103,9 +103,9 @@ type ( isEnd bool //表示当前处理流程是否需要终止 httpServer *HttpServer sessionID string - innerItems *core.ItemContext - items *core.ItemContext - viewData *core.ItemContext + innerItems core.ConcurrenceMap + items core.ConcurrenceMap + viewData core.ConcurrenceMap features *xFeatureTools handler HttpHandle startTime time.Time @@ -225,11 +225,11 @@ func (ctx *HttpContext) Features() *xFeatureTools { // AppContext get application's global appcontext // issue #3 -func (ctx *HttpContext) AppItems() *core.ItemContext { +func (ctx *HttpContext) AppItems() core.ConcurrenceMap { if ctx.HttpServer != nil { return ctx.httpServer.DotApp.Items } else { - return core.NewItemContext() + return core.NewConcurrenceMap() } } @@ -240,33 +240,33 @@ func (ctx *HttpContext) Cache() cache.Cache { // getInnerItems get request's inner item context // lazy init when first use -func (ctx *HttpContext) getInnerItems() *core.ItemContext { +func (ctx *HttpContext) getInnerItems() core.ConcurrenceMap { if ctx.innerItems == nil { - ctx.innerItems = core.NewItemContext() + ctx.innerItems = core.NewConcurrenceMap() } return ctx.innerItems } // Items get request's item context // lazy init when first use -func (ctx *HttpContext) Items() *core.ItemContext { +func (ctx *HttpContext) Items() core.ConcurrenceMap { if ctx.items == nil { - ctx.items = core.NewItemContext() + ctx.items = core.NewConcurrenceMap() } return ctx.items } // AppSetConfig get appset from config file // update for issue #16 配置文件 -func (ctx *HttpContext) AppSetConfig() *core.ItemContext { - return ctx.HttpServer().DotApp.Config.AppSetConfig +func (ctx *HttpContext) ConfigSet() core.ReadonlyMap { + return ctx.HttpServer().DotApp.Config.ConfigSet } // ViewData get view data context // lazy init when first use -func (ctx *HttpContext) ViewData() *core.ItemContext { +func (ctx *HttpContext) ViewData() core.ConcurrenceMap { if ctx.viewData == nil { - ctx.viewData = core.NewItemContext() + ctx.viewData = core.NewConcurrenceMap() } return ctx.viewData } @@ -330,8 +330,8 @@ func (ctx *HttpContext) QueryInt(key string) int { if param == "" { return 0 } - val, err:=strconv.Atoi(param) - if err != nil{ + val, err := strconv.Atoi(param) + if err != nil { return 0 } return val @@ -344,14 +344,13 @@ func (ctx *HttpContext) QueryInt64(key string) int64 { if param == "" { return 0 } - val, err:=strconv.ParseInt(param, 10, 64) - if err != nil{ + val, err := strconv.ParseInt(param, 10, 64) + if err != nil { return 0 } return val } - /* * 根据指定key获取包括在post、put和get内的值 */ @@ -551,7 +550,7 @@ func (ctx *HttpContext) WriteBlobC(code int, contentType string, b []byte) error _, err := ctx.hijackConn.WriteBlob(b) return err } else { - _, err := ctx.response.Write(code, b) + _, err := ctx.response.Write(code, b) return err } } @@ -564,7 +563,7 @@ func (ctx *HttpContext) WriteJson(i interface{}) error { // WriteJsonC write (httpCode, json string) to response // auto convert interface{} to json string -func (ctx *HttpContext) WriteJsonC(code int, i interface{}) error{ +func (ctx *HttpContext) WriteJsonC(code int, i interface{}) error { b, err := json.Marshal(i) if err != nil { return err diff --git a/core/concurrenceMap.go b/core/concurrenceMap.go new file mode 100644 index 0000000..030bfea --- /dev/null +++ b/core/concurrenceMap.go @@ -0,0 +1,145 @@ +package core + +import ( + "fmt" + "sync" +) + +type ( + ReadonlyMap interface { + Get(key string) (value interface{}, exists bool) + GetString(key string) string + GetInt(key string) int + GetUInt64(key string) uint64 + Exists(key string) bool + Len() int + } + ConcurrenceMap interface { + Get(key string) (value interface{}, exists bool) + GetString(key string) string + GetInt(key string) int + GetUInt64(key string) uint64 + Exists(key string) bool + GetCurrentMap() map[string]interface{} + Len() int + Set(key string, value interface{}) error + Remove(key string) + Once(key string) (value interface{}, exists bool) + } +) + +//自带锁,并发安全的Map +type ItemMap struct { + innerMap map[string]interface{} + *sync.RWMutex +} + +func NewItemMap() *ItemMap { + return &ItemMap{ + innerMap: make(map[string]interface{}), + RWMutex: new(sync.RWMutex), + } +} + +func NewConcurrenceMap() ConcurrenceMap { + return &ItemMap{ + innerMap: make(map[string]interface{}), + RWMutex: new(sync.RWMutex), + } +} + +func NewReadonlyMap() ReadonlyMap { + return &ItemMap{ + innerMap: make(map[string]interface{}), + RWMutex: new(sync.RWMutex), + } +} + +/* +* 以key、value置入AppContext + */ +func (ctx *ItemMap) Set(key string, value interface{}) error { + ctx.Lock() + ctx.innerMap[key] = value + ctx.Unlock() + return nil +} + +/* +* 读取指定key在AppContext中的内容 + */ +func (ctx *ItemMap) Get(key string) (value interface{}, exists bool) { + ctx.RLock() + value, exists = ctx.innerMap[key] + ctx.RUnlock() + return value, exists +} + +//remove item by gived key +//if not exists key, do nothing... +func (ctx *ItemMap) Remove(key string) { + ctx.Lock() + delete(ctx.innerMap, key) + ctx.Unlock() +} + +//get item by gived key, and remove it +//only can be read once, it will be locked +func (ctx *ItemMap) Once(key string) (value interface{}, exists bool) { + ctx.Lock() + defer ctx.Unlock() + value, exists = ctx.innerMap[key] + if exists { + delete(ctx.innerMap, key) + } + return value, exists +} + +/* +* 读取指定key在AppContext中的内容,以string格式输出 + */ +func (ctx *ItemMap) GetString(key string) string { + value, exists := ctx.Get(key) + if !exists { + return "" + } + return fmt.Sprint(value) +} + +/* +* 读取指定key在AppContext中的内容,以int格式输出 + */ +func (ctx *ItemMap) GetInt(key string) int { + value, exists := ctx.Get(key) + if !exists { + return 0 + } + return value.(int) +} + +/* +* 读取指定key在AppContext中的内容,以int格式输出 + */ +func (ctx *ItemMap) GetUInt64(key string) uint64 { + value, exists := ctx.Get(key) + if !exists { + return 0 + } + return value.(uint64) +} + +//check exists key +func (ctx *ItemMap) Exists(key string) bool { + _, exists := ctx.innerMap[key] + return exists +} + +//get current map, returns map[string]interface{} +func (ctx *ItemMap) GetCurrentMap() map[string]interface{} { + return ctx.innerMap +} + +//get context length +func (ctx *ItemMap) Len() int { + return len(ctx.innerMap) +} diff --git a/core/context_test.go b/core/concurrenceMap_test.go similarity index 64% rename from core/context_test.go rename to core/concurrenceMap_test.go index 38f6896..c25c7d2 100644 --- a/core/context_test.go +++ b/core/concurrenceMap_test.go @@ -1,27 +1,28 @@ package core import ( - "testing" "fmt" + "strconv" "sync" + "testing" "time" - "strconv" ) -var ic *ItemContext +var ic ConcurrenceMap var keys []string + func init() { - ic = NewItemContext() - for i := 0; i < 10000000 ; i++ { + ic = NewConcurrenceMap() + for i := 0; i < 10000000; i++ { keys = append(keys, time.Now().String()) } - fmt.Println("len of keys ",len(keys)) + fmt.Println("len of keys ", len(keys)) } func TestItemContext_Get_Set(t *testing.T) { - t.Log(ic.Set("foo","bar")) + t.Log(ic.Set("foo", "bar")) t.Log(ic.Get("foo")) t.Log(ic.Exists("foo")) @@ -30,16 +31,16 @@ func TestItemContext_Get_Set(t *testing.T) { } func TestItemContext_Get_Once(t *testing.T) { - ic.Set("foo","bar") + ic.Set("foo", "bar") t.Log(ic.Once("foo")) t.Log(ic.Get("foo")) } func TestItemContext_Remove(t *testing.T) { - ic.Set("foo","bar") - ic.Set("foo1","bar1") - t.Log(len(ic.contextMap)) + ic.Set("foo", "bar") + ic.Set("foo1", "bar1") + t.Log(len(ic.GetCurrentMap())) ic.Remove("foo") t.Log(ic.GetString("foo")) } @@ -47,22 +48,21 @@ func TestItemContext_Remove(t *testing.T) { func TestItemContext_Current(t *testing.T) { lock := &sync.Mutex{} j := 0 - for i := 0; i < 9;i++ { + for i := 0; i < 9; i++ { go func() { lock.Lock() - fmt.Println("go",j) + fmt.Println("go", j) j++ v := "bar" + strconv.Itoa(j) fmt.Println(v) - ic.Set(strconv.Itoa(j),v) + ic.Set(strconv.Itoa(j), v) lock.Unlock() }() } - time.Sleep(3*time.Second) - - t.Log(ic.contextMap) + time.Sleep(3 * time.Second) + t.Log(ic.GetCurrentMap()) } @@ -72,36 +72,35 @@ func TestItemContext_Current(t *testing.T) { func BenchmarkItemContext_Set_1(b *testing.B) { var num uint64 = 1 for i := 0; i < b.N; i++ { - ic.Set(string(num),num) + ic.Set(string(num), num) } } //并发效率 func BenchmarkItemContext_Set_Parallel(b *testing.B) { - b.RunParallel(func (pb *testing.PB){ + b.RunParallel(func(pb *testing.PB) { var num uint64 = 1 - for pb.Next(){ - ic.Set(string(num),num) + for pb.Next() { + ic.Set(string(num), num) } }) } //基准测试 func BenchmarkItemContext_Get_1(b *testing.B) { - ic.Set("foo","bar") - for i := 0; i < b.N; i++{ + ic.Set("foo", "bar") + for i := 0; i < b.N; i++ { ic.Get("foo") } } //并发效率 func BenchmarkItemContext_Get_Parallel(b *testing.B) { - ic.Set("foo","bar") - b.RunParallel(func (pb *testing.PB){ + ic.Set("foo", "bar") + b.RunParallel(func(pb *testing.PB) { for pb.Next() { ic.Get("foo") } }) } - diff --git a/core/context.go b/core/context.go deleted file mode 100644 index 2d79545..0000000 --- a/core/context.go +++ /dev/null @@ -1,108 +0,0 @@ -package core - -import ( - "fmt" - "sync" -) - -//自带锁,并发安全的Map -type ItemContext struct { - contextMap map[string]interface{} - *sync.RWMutex -} - -func NewItemContext() *ItemContext { - return &ItemContext{ - contextMap: make(map[string]interface{}), - RWMutex: new(sync.RWMutex), - } -} - -/* -* 以key、value置入AppContext - */ -func (ctx *ItemContext) Set(key string, value interface{}) error { - ctx.Lock() - ctx.contextMap[key] = value - ctx.Unlock() - return nil -} - -/* -* 读取指定key在AppContext中的内容 - */ -func (ctx *ItemContext) Get(key string) (value interface{}, exists bool) { - ctx.RLock() - value, exists = ctx.contextMap[key] - ctx.RUnlock() - return value, exists -} - -//remove item by gived key -//if not exists key, do nothing... -func (ctx *ItemContext) Remove(key string) { - ctx.Lock() - delete(ctx.contextMap, key) - ctx.Unlock() -} - -//get item by gived key, and remove it -//only can be read once, it will be locked -func (ctx *ItemContext) Once(key string) (value interface{}, exists bool) { - ctx.Lock() - defer ctx.Unlock() - value, exists = ctx.contextMap[key] - if exists { - delete(ctx.contextMap, key) - } - return value, exists -} - -/* -* 读取指定key在AppContext中的内容,以string格式输出 - */ -func (ctx *ItemContext) GetString(key string) string { - value, exists := ctx.Get(key) - if !exists { - return "" - } - return fmt.Sprint(value) -} - -/* -* 读取指定key在AppContext中的内容,以int格式输出 - */ -func (ctx *ItemContext) GetInt(key string) int { - value, exists := ctx.Get(key) - if !exists { - return 0 - } - return value.(int) -} - -/* -* 读取指定key在AppContext中的内容,以int格式输出 - */ -func (ctx *ItemContext) GetUInt64(key string) uint64 { - value, exists := ctx.Get(key) - if !exists { - return 0 - } - return value.(uint64) -} - -//check exists key -func (ctx *ItemContext) Exists(key string) bool { - _, exists := ctx.contextMap[key] - return exists -} - -//get current map, returns map[string]interface{} -func (ctx *ItemContext) GetCurrentMap() map[string]interface{} { - return ctx.contextMap -} - -//get context length -func (ctx *ItemContext) Len() int { - return len(ctx.contextMap) -} diff --git a/core/state.go b/core/state.go index d42060e..162aea8 100644 --- a/core/state.go +++ b/core/state.go @@ -1,6 +1,7 @@ package core import ( + "github.com/devfeel/dotweb/const" "github.com/devfeel/dotweb/framework/json" "net/http" "strconv" @@ -8,7 +9,6 @@ import ( "sync" "sync/atomic" "time" - "github.com/devfeel/dotweb/const" ) var GlobalState *ServerStateInfo @@ -25,12 +25,12 @@ func init() { ServerStartTime: time.Now(), TotalRequestCount: 0, TotalErrorCount: 0, - IntervalRequestData: NewItemContext(), - DetailRequestURLData: NewItemContext(), - IntervalErrorData: NewItemContext(), - DetailErrorPageData: NewItemContext(), - DetailErrorData: NewItemContext(), - DetailHTTPCodeData: NewItemContext(), + IntervalRequestData: NewItemMap(), + DetailRequestURLData: NewItemMap(), + IntervalErrorData: NewItemMap(), + DetailErrorPageData: NewItemMap(), + DetailErrorData: NewItemMap(), + DetailHTTPCodeData: NewItemMap(), dataChan_Request: make(chan *RequestInfo, 1000), dataChan_Error: make(chan *ErrorInfo, 1000), dataChan_HttpCode: make(chan *HttpCodeInfo, 1000), @@ -93,19 +93,19 @@ type ServerStateInfo struct { //该运行期间总访问次数 TotalRequestCount uint64 //单位时间内请求数据 - 按分钟为单位 - IntervalRequestData *ItemContext + IntervalRequestData *ItemMap //明细请求页面数据 - 以不带参数的访问url为key - DetailRequestURLData *ItemContext + DetailRequestURLData *ItemMap //该运行期间异常次数 TotalErrorCount uint64 //单位时间内异常次数 - 按分钟为单位 - IntervalErrorData *ItemContext + IntervalErrorData *ItemMap //明细异常页面数据 - 以不带参数的访问url为key - DetailErrorPageData *ItemContext + DetailErrorPageData *ItemMap //明细异常数据 - 以不带参数的访问url为key - DetailErrorData *ItemContext + DetailErrorData *ItemMap //明细Http状态码数据 - 以HttpCode为key,例如200、500等 - DetailHTTPCodeData *ItemContext + DetailHTTPCodeData *ItemMap dataChan_Request chan *RequestInfo dataChan_Error chan *ErrorInfo diff --git a/dotweb.go b/dotweb.go index adce062..02c0741 100644 --- a/dotweb.go +++ b/dotweb.go @@ -33,7 +33,7 @@ type ( ExceptionHandler ExceptionHandle NotFoundHandler StandardHandle // NotFoundHandler 支持自定义404处理代码能力 MethodNotAllowedHandler StandardHandle // MethodNotAllowedHandler fixed for #64 增加MethodNotAllowed自定义处理 - Items *core.ItemContext + Items core.ConcurrenceMap middlewareMap map[string]MiddlewareFunc middlewareMutex *sync.RWMutex StartMode string @@ -51,10 +51,10 @@ type ( ) const ( - DefaultHTTPPort = 8080 //DefaultHTTPPort default http port; fixed for #70 UPDATE default http port 80 to 8080 + DefaultHTTPPort = 8080 //DefaultHTTPPort default http port; fixed for #70 UPDATE default http port 80 to 8080 DefaultConfigSetGroupName = "default" - RunMode_Development = "development" - RunMode_Production = "production" + RunMode_Development = "development" + RunMode_Production = "production" StartMode_New = "New" StartMode_Classic = "Classic" @@ -66,7 +66,7 @@ func New() *DotWeb { HttpServer: NewHttpServer(), OfflineServer: servers.NewOfflineServer(), Middlewares: make([]Middleware, 0), - Items: core.NewItemContext(), + Items: core.NewConcurrenceMap(), Config: config.NewConfig(), middlewareMap: make(map[string]MiddlewareFunc), middlewareMutex: new(sync.RWMutex), @@ -123,46 +123,6 @@ func (app *DotWeb) SetCache(ca cache.Cache) { app.cache = ca } -// IncludeConfigSetXML include ConfigSet xml file to Dotweb.Items -// same key will cover oldest value -func (app *DotWeb) IncludeConfigSetXML(configFile string) error{ - item, err:=config.ParseConfigSetXML(configFile) - if err!= nil{ - return err - } - for k,v:=range item.GetCurrentMap(){ - app.Items.Set(k, v) - } - return nil -} - -// IncludeConfigSetJSON include ConfigSet json file to Dotweb.Items -// same key will cover oldest value -func (app *DotWeb) IncludeConfigSetJSON(configFile string) error{ - item, err:=config.ParseConfigSetXML(configFile) - if err!= nil{ - return err - } - for k,v:=range item.GetCurrentMap(){ - app.Items.Set(k, v) - } - return nil -} - -// IncludeConfigSetYaml include ConfigSet ymal file to Dotweb.Items -// same key will cover oldest value -func (app *DotWeb) IncludeConfigSetYaml(configFile string) error{ - item, err:=config.ParseConfigSetXML(configFile) - if err!= nil{ - return err - } - for k,v:=range item.GetCurrentMap(){ - app.Items.Set(k, v) - } - return nil -} - - // RunMode current app run mode, if not set, default set RunMode_Development func (app *DotWeb) RunMode() string { if app.Config.App.RunMode != RunMode_Development && app.Config.App.RunMode != RunMode_Production { @@ -446,11 +406,11 @@ func (app *DotWeb) initBindMiddleware() { //bind app middlewares for fullExpress, _ := range router.allRouterExpress { expresses := strings.Split(fullExpress, "_") - if len(expresses) < 2{ + if len(expresses) < 2 { continue } node := router.getNode(expresses[0], expresses[1]) - if node == nil{ + if node == nil { continue } @@ -463,7 +423,7 @@ func (app *DotWeb) initBindMiddleware() { logger.Logger().Debug("DotWeb initBindMiddleware [app] "+fullExpress+" "+reflect.TypeOf(m).String()+" match", LogTarget_HttpServer) } } - if len(node.middlewares) > 0{ + if len(node.middlewares) > 0 { firstMiddleware := &xMiddleware{} firstMiddleware.SetNext(node.middlewares[0]) node.middlewares = append([]Middleware{firstMiddleware}, node.middlewares...) @@ -475,7 +435,7 @@ func (app *DotWeb) initBindMiddleware() { xg := g.(*xGroup) if len(xg.middlewares) <= 0 { continue - }else{ + } else { firstMiddleware := &xMiddleware{} firstMiddleware.SetNext(xg.middlewares[0]) xg.middlewares = append([]Middleware{firstMiddleware}, xg.middlewares...) diff --git a/example/configset/main.go b/example/configset/main.go index 501f715..b35ba85 100644 --- a/example/configset/main.go +++ b/example/configset/main.go @@ -3,6 +3,7 @@ package main import ( "fmt" "github.com/devfeel/dotweb" + "github.com/devfeel/dotweb/config" "github.com/devfeel/dotweb/framework/file" "strconv" ) @@ -18,10 +19,9 @@ func main() { app.HttpServer.SetEnabledIgnoreFavicon(true) - //引入自定义ConfigSet - err := app.IncludeConfigSetXML("d:/gotmp/userconf.xml") - if err!=nil{ + err := app.Config.IncludeConfigSet("d:/gotmp/userconf.xml", config.ConfigType_XML) + if err != nil { fmt.Println(err.Error()) return } @@ -43,7 +43,6 @@ func ConfigSet(ctx dotweb.Context) error { return ctx.WriteString("\r\n") } - func InitRoute(server *dotweb.HttpServer) { server.GET("/c", ConfigSet) -} \ No newline at end of file +} diff --git a/version.MD b/version.MD index f5e4687..bfa6831 100644 --- a/version.MD +++ b/version.MD @@ -1,16 +1,19 @@ ## dotweb版本记录: #### Version 1.4.8 +* 调整:ItemContext更名为ItemMap,新增ConcurrenceMap、ReadonlyMap接口 * 调整:Dotweb.AppContext变更为Dotweb.Items * 调整:HttpContext.AppContext变更为HttpContext.AppItems -* 新增config.ConfigSet\config.ParseConfigSetXML\ParseConfigSetJSON\ParseConfigSetYaml,用于解析常规Key\Value格式的配置文件 -* 新增Dotweb.IncludeConfigSetXML\IncludeConfigSetJSON\IncludeConfigSetYaml,解析配置后置入Dotweb.Items,可通过HttpContext.AppItems().Get()获取 -* Include\ParseConfigSetXML:支持xml格式文件解析 -* Include\ParseConfigSetJSON:支持json格式文件解析 -* Include\ParseConfigSetYaml:支持yaml格式文件解析 +* 调整:HttpContext.AppSetConfig变更为HttpContext.ConfigSet +* 调整:config.AppSet变更为config.ConfigSet +* 新增: config.ParseConfigSetXML\ParseConfigSetJSON\ParseConfigSetYaml,用于解析常规Key\Value格式的配置文件 +* 新增:config.Config.IncludeConfigSet,用于向config.ConfigSet中导入Key\Value格式的配置文件,通过HttpContext.ConfigSet获取相关设置信息 +* ParseConfigSetXML:支持xml格式文件解析,返回core.ConcurrenceMap +* ParseConfigSetJSON:支持json格式文件解析,返回core.ConcurrenceMap +* ParseConfigSetYaml:支持yaml格式文件解析,返回core.ConcurrenceMap * 具体配置文件格式可参考example/configset * 新增示例代码 example/configset -* 2018-01-23 19:00 +* 2018-01-24 22:00 #### Version 1.4.7 * BUG Fixed: 修复Middleware特定场景下无效问题 From fafeb45c597b6f7c42556091ec4cc64d4f7db74e Mon Sep 17 00:00:00 2001 From: "pzrr@qq.com" Date: Thu, 25 Jan 2018 23:16:27 +0800 Subject: [PATCH 3/5] =?UTF-8?q?####=20Version=201.4.8=20*=20=E8=B0=83?= =?UTF-8?q?=E6=95=B4=EF=BC=9AItemContext=E6=9B=B4=E5=90=8D=E4=B8=BAItemMap?= =?UTF-8?q?=EF=BC=8C=E6=96=B0=E5=A2=9EConcurrenceMap=E3=80=81ReadonlyMap?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3=20*=20=E8=B0=83=E6=95=B4=EF=BC=9ADotweb.AppC?= =?UTF-8?q?ontext=E5=8F=98=E6=9B=B4=E4=B8=BADotweb.Items=20*=20=E8=B0=83?= =?UTF-8?q?=E6=95=B4=EF=BC=9AHttpContext.AppContext=E5=8F=98=E6=9B=B4?= =?UTF-8?q?=E4=B8=BAHttpContext.AppItems=20*=20=E8=B0=83=E6=95=B4=EF=BC=9A?= =?UTF-8?q?HttpContext.AppSetConfig=E5=8F=98=E6=9B=B4=E4=B8=BAHttpContext.?= =?UTF-8?q?ConfigSet=20*=20=E8=B0=83=E6=95=B4=EF=BC=9Aconfig.AppSet?= =?UTF-8?q?=E5=8F=98=E6=9B=B4=E4=B8=BAconfig.ConfigSet=20*=20=E6=96=B0?= =?UTF-8?q?=E5=A2=9E:=20config.ParseConfigSetXML\ParseConfigSetJSON\ParseC?= =?UTF-8?q?onfigSetYaml=EF=BC=8C=E7=94=A8=E4=BA=8E=E8=A7=A3=E6=9E=90?= =?UTF-8?q?=E5=B8=B8=E8=A7=84Key\Value=E6=A0=BC=E5=BC=8F=E7=9A=84=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=E6=96=87=E4=BB=B6=20*=20=E6=96=B0=E5=A2=9E=EF=BC=9Aco?= =?UTF-8?q?nfig.Config.IncludeConfigSet=EF=BC=8C=E7=94=A8=E4=BA=8E?= =?UTF-8?q?=E5=90=91config.ConfigSet=E4=B8=AD=E5=AF=BC=E5=85=A5Key\Value?= =?UTF-8?q?=E6=A0=BC=E5=BC=8F=E7=9A=84=E9=85=8D=E7=BD=AE=E6=96=87=E4=BB=B6?= =?UTF-8?q?=EF=BC=8C=E9=80=9A=E8=BF=87HttpContext.ConfigSet=E8=8E=B7?= =?UTF-8?q?=E5=8F=96=E7=9B=B8=E5=85=B3=E8=AE=BE=E7=BD=AE=E4=BF=A1=E6=81=AF?= =?UTF-8?q?=20*=20ParseConfigSetXML:=E6=94=AF=E6=8C=81xml=E6=A0=BC?= =?UTF-8?q?=E5=BC=8F=E6=96=87=E4=BB=B6=E8=A7=A3=E6=9E=90=EF=BC=8C=E8=BF=94?= =?UTF-8?q?=E5=9B=9Ecore.ConcurrenceMap=20*=20ParseConfigSetJSON:=E6=94=AF?= =?UTF-8?q?=E6=8C=81json=E6=A0=BC=E5=BC=8F=E6=96=87=E4=BB=B6=E8=A7=A3?= =?UTF-8?q?=E6=9E=90=EF=BC=8C=E8=BF=94=E5=9B=9Ecore.ConcurrenceMap=20*=20P?= =?UTF-8?q?arseConfigSetYaml:=E6=94=AF=E6=8C=81yaml=E6=A0=BC=E5=BC=8F?= =?UTF-8?q?=E6=96=87=E4=BB=B6=E8=A7=A3=E6=9E=90=EF=BC=8C=E8=BF=94=E5=9B=9E?= =?UTF-8?q?core.ConcurrenceMap=20*=20=E5=85=B7=E4=BD=93=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E6=96=87=E4=BB=B6=E6=A0=BC=E5=BC=8F=E5=8F=AF=E5=8F=82=E8=80=83?= =?UTF-8?q?example/configset=20*=20=E6=96=B0=E5=A2=9E=E7=A4=BA=E4=BE=8B?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=20example/configset=20*=202018-01-24=2022:00?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- example/configset/main.go | 4 +- example/httpmodule/main.go | 107 ------------------------------------- example/middleware/main.go | 4 -- 3 files changed, 2 insertions(+), 113 deletions(-) delete mode 100644 example/httpmodule/main.go diff --git a/example/configset/main.go b/example/configset/main.go index b35ba85..b14c319 100644 --- a/example/configset/main.go +++ b/example/configset/main.go @@ -37,8 +37,8 @@ func main() { } func ConfigSet(ctx dotweb.Context) error { - vkey1 := ctx.AppItems().GetString("set1") - vkey2 := ctx.AppItems().GetString("set2") + vkey1 := ctx.ConfigSet().GetString("set1") + vkey2 := ctx.ConfigSet().GetString("set2") ctx.WriteString(ctx.Request().Path(), "key1=", vkey1, "key2=", vkey2) return ctx.WriteString("\r\n") } diff --git a/example/httpmodule/main.go b/example/httpmodule/main.go deleted file mode 100644 index ffc8d8a..0000000 --- a/example/httpmodule/main.go +++ /dev/null @@ -1,107 +0,0 @@ -package main - -import ( - "fmt" - "github.com/devfeel/dotweb" - "github.com/devfeel/dotweb/framework/file" - "github.com/devfeel/dotweb/session" - "strconv" -) - -func main() { - //初始化DotServer - app := dotweb.New() - - //设置dotserver日志目录 - app.SetLogPath(file.GetCurrentDirectory()) - - //设置gzip开关 - //app.HttpServer.SetEnabledGzip(true) - - app.SetDevelopmentMode() - - //设置Session开关 - app.HttpServer.SetEnabledSession(true) - - app.HttpServer.SetEnabledIgnoreFavicon(true) - - //设置Session配置 - //runtime mode - app.HttpServer.SetSessionConfig(session.NewDefaultRuntimeConfig()) - //redis mode - //app.SetSessionConfig(session.NewDefaultRedisConfig("192.168.8.175:6379", "")) - - //设置路由 - InitRoute(app.HttpServer) - - //设置HttpModule - InitModule(app.HttpServer) - - //启动 监控服务 - //app.SetPProfConfig(true, 8081) - - //全局容器 - app.AppContext.Set("gstring", "gvalue") - app.AppContext.Set("gint", 1) - - // 开始服务 - port := 8080 - fmt.Println("dotweb.StartServer => " + strconv.Itoa(port)) - err := app.StartServer(port) - fmt.Println("dotweb.StartServer error => ", err) -} - -func Index(ctx dotweb.Context) error { - ctx.Items().Set("count", 2) - ctx.WriteString(ctx.Request().Path() + ":Items.Count=> " + ctx.Items().GetString("count")) - return ctx.WriteString("\r\n") -} - -func WHtml(ctx dotweb.Context) error { - ctx.WriteHtml("this is html response!") - return nil -} - -func InitRoute(server *dotweb.HttpServer) { - server.GET("/", Index) - server.GET("/m", Index) - server.GET("/h", WHtml) -} - -func InitModule(dotserver *dotweb.HttpServer) { - dotserver.RegisterModule(&dotweb.HttpModule{ - Name: "test change route", - OnBeginRequest: func(ctx dotweb.Context) { - if ctx.IsEnd() { - return - } - if ctx.Request().Path() == "/" && ctx.QueryString("change") == "1" { - //change route - ctx.WriteString("变更访问路由测试") - ctx.WriteString("\r\n") - ctx.Request().URL.Path = "/m" - } - - if ctx.Request().Path() == "/" { - ctx.Items().Set("count", 1) - ctx.WriteString("OnBeginRequest:Items.Count => ", ctx.Items().GetString("count")) - ctx.WriteString("\r\n") - } - if ctx.QueryString("skip") == "1" { - ctx.End() - } - }, - OnEndRequest: func(ctx dotweb.Context) { - if ctx.IsEnd() { - return - } - if ctx.Request().Path() == "/" { - if ctx.Items().Exists("count") { - ctx.WriteString("OnEndRequest:Items.Count => ", ctx.Items().GetString("count")) - } else { - ctx.WriteString("OnEndRequest:Items.Len => ", ctx.Items().Len()) - } - } - }, - }) -} diff --git a/example/middleware/main.go b/example/middleware/main.go index eee3e2a..ed18c45 100644 --- a/example/middleware/main.go +++ b/example/middleware/main.go @@ -34,10 +34,6 @@ func main() { //启动 监控服务 app.SetPProfConfig(true, 8081) - //全局容器 - app.AppContext.Set("gstring", "gvalue") - app.AppContext.Set("gint", 1) - // 开始服务 port := 8080 fmt.Println("dotweb.StartServer => " + strconv.Itoa(port)) From 65fb6a6ba5cf6b000c1994c37f0e8d3a3b9edc60 Mon Sep 17 00:00:00 2001 From: "pzrr@qq.com" Date: Fri, 26 Jan 2018 10:45:05 +0800 Subject: [PATCH 4/5] =?UTF-8?q?####=20Version=201.4.8=20*=20=E8=B0=83?= =?UTF-8?q?=E6=95=B4=EF=BC=9AItemContext=E6=9B=B4=E5=90=8D=E4=B8=BAItemMap?= =?UTF-8?q?=EF=BC=8C=E6=96=B0=E5=A2=9EConcurrenceMap=E3=80=81ReadonlyMap?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3=20*=20=E8=B0=83=E6=95=B4=EF=BC=9ADotweb.AppC?= =?UTF-8?q?ontext=E5=8F=98=E6=9B=B4=E4=B8=BADotweb.Items=20*=20=E8=B0=83?= =?UTF-8?q?=E6=95=B4=EF=BC=9AHttpContext.AppContext=E5=8F=98=E6=9B=B4?= =?UTF-8?q?=E4=B8=BAHttpContext.AppItems=20*=20=E8=B0=83=E6=95=B4=EF=BC=9A?= =?UTF-8?q?HttpContext.AppSetConfig=E5=8F=98=E6=9B=B4=E4=B8=BAHttpContext.?= =?UTF-8?q?ConfigSet=20*=20=E8=B0=83=E6=95=B4=EF=BC=9Aconfig.AppSet?= =?UTF-8?q?=E5=8F=98=E6=9B=B4=E4=B8=BAconfig.ConfigSet=20*=20=E6=96=B0?= =?UTF-8?q?=E5=A2=9E:=20config.ParseConfigSetXML\ParseConfigSetJSON\ParseC?= =?UTF-8?q?onfigSetYaml=EF=BC=8C=E7=94=A8=E4=BA=8E=E8=A7=A3=E6=9E=90?= =?UTF-8?q?=E5=B8=B8=E8=A7=84Key\Value=E6=A0=BC=E5=BC=8F=E7=9A=84=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=E6=96=87=E4=BB=B6=20*=20=E6=96=B0=E5=A2=9E=EF=BC=9Aco?= =?UTF-8?q?nfig.Config.IncludeConfigSet=EF=BC=8C=E7=94=A8=E4=BA=8E?= =?UTF-8?q?=E5=90=91config.ConfigSet=E4=B8=AD=E5=AF=BC=E5=85=A5Key\Value?= =?UTF-8?q?=E6=A0=BC=E5=BC=8F=E7=9A=84=E9=85=8D=E7=BD=AE=E6=96=87=E4=BB=B6?= =?UTF-8?q?=EF=BC=8C=E9=80=9A=E8=BF=87HttpContext.ConfigSet=E8=8E=B7?= =?UTF-8?q?=E5=8F=96=E7=9B=B8=E5=85=B3=E8=AE=BE=E7=BD=AE=E4=BF=A1=E6=81=AF?= =?UTF-8?q?=20*=20ParseConfigSetXML:=E6=94=AF=E6=8C=81xml=E6=A0=BC?= =?UTF-8?q?=E5=BC=8F=E6=96=87=E4=BB=B6=E8=A7=A3=E6=9E=90=EF=BC=8C=E8=BF=94?= =?UTF-8?q?=E5=9B=9Ecore.ConcurrenceMap=20*=20ParseConfigSetJSON:=E6=94=AF?= =?UTF-8?q?=E6=8C=81json=E6=A0=BC=E5=BC=8F=E6=96=87=E4=BB=B6=E8=A7=A3?= =?UTF-8?q?=E6=9E=90=EF=BC=8C=E8=BF=94=E5=9B=9Ecore.ConcurrenceMap=20*=20P?= =?UTF-8?q?arseConfigSetYaml:=E6=94=AF=E6=8C=81yaml=E6=A0=BC=E5=BC=8F?= =?UTF-8?q?=E6=96=87=E4=BB=B6=E8=A7=A3=E6=9E=90=EF=BC=8C=E8=BF=94=E5=9B=9E?= =?UTF-8?q?core.ConcurrenceMap=20*=20=E5=85=B7=E4=BD=93=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E6=96=87=E4=BB=B6=E6=A0=BC=E5=BC=8F=E5=8F=AF=E5=8F=82=E8=80=83?= =?UTF-8?q?example/configset=20*=20=E6=96=B0=E5=A2=9E=E7=A4=BA=E4=BE=8B?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=20example/configset=20*=202018-01-24=2022:00?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/configs.go | 17 ++++++++++++++- config/configs_test.go | 8 +++---- config/configset.go | 4 ++-- context_test.go | 6 +++--- core/concurrenceMap.go | 44 +++++++++++++++++++-------------------- dotweb.go | 9 ++++++-- example/configset/main.go | 2 ++ 7 files changed, 55 insertions(+), 35 deletions(-) diff --git a/config/configs.go b/config/configs.go index 5d6a89b..2a35eea 100644 --- a/config/configs.go +++ b/config/configs.go @@ -9,6 +9,8 @@ import ( ) type ( + + // Config dotweb app config define Config struct { XMLName xml.Name `xml:"config" json:"-" yaml:"-"` App *AppNode `xml:"app"` @@ -21,11 +23,15 @@ type ( Middlewares []*MiddlewareNode `xml:"middlewares>middleware"` ConfigSet core.ReadonlyMap `json:"-" yaml:"-"` } + + // OfflineNode dotweb app offline config OfflineNode struct { Offline bool `xml:"offline,attr"` //是否维护,默认false OfflineText string `xml:"offlinetext,attr"` //当设置为维护,默认显示内容,如果设置url,优先url OfflineUrl string `xml:"offlineurl,attr"` //当设置为维护,默认维护页地址,如果设置url,优先url } + + // AppNode dotweb app global config AppNode struct { LogPath string `xml:"logpath,attr"` //文件方式日志目录,如果为空,默认当前目录 EnabledLog bool `xml:"enabledlog,attr"` //是否启用日志记录 @@ -34,6 +40,7 @@ type ( EnabledPProf bool `xml:"enabledpprof,attr"` //是否启用pprof server,默认不启用 } + // ServerNode dotweb app's httpserver config ServerNode struct { EnabledListDir bool `xml:"enabledlistdir,attr"` //设置是否启用目录浏览,仅对Router.ServerFile有效,若设置该项,则可以浏览目录文件,默认不开启 EnabledRequestID bool `xml:"enabledrequestid,attr"` //设置是否启用唯一请求ID,默认不开启,开启后使用32位UUID @@ -50,6 +57,7 @@ type ( EnabledDetailRequestData bool `xml:"enableddetailrequestdata,attr"` //设置状态数据是否启用详细页面统计,默认不启用,请特别对待,如果站点url过多,会导致数据量过大 } + // SessionNode dotweb app's session config SessionNode struct { EnabledSession bool `xml:"enabled,attr"` //启用Session SessionMode string `xml:"mode,attr"` //session模式,目前支持runtime、redis @@ -59,6 +67,7 @@ type ( Password string `xml:"password,attr"` //远程session password } + // RouterNode dotweb app's router config RouterNode struct { Method string `xml:"method,attr"` Path string `xml:"path,attr"` @@ -67,6 +76,7 @@ type ( IsUse bool `xml:"isuse,attr"` //是否启用,默认false } + // GroupNode dotweb app's group router config GroupNode struct { Path string `xml:"path,attr"` Routers []*RouterNode `xml:"router"` @@ -74,6 +84,7 @@ type ( IsUse bool `xml:"isuse,attr"` //是否启用,默认false } + // MiddlewareNode dotweb app's middleware config MiddlewareNode struct { Name string `xml:"name,attr"` IsUse bool `xml:"isuse,attr"` //是否启用,默认false @@ -81,11 +92,15 @@ type ( ) const ( + // ConfigType_XML xml config file ConfigType_XML = "xml" + // ConfigType_JSON json config file ConfigType_JSON = "json" + // ConfigType_Yaml yaml config file ConfigType_Yaml = "yaml" ) +// NewConfig create new config func NewConfig() *Config { return &Config{ App: NewAppNode(), @@ -96,7 +111,7 @@ func NewConfig() *Config { } } -// IncludeConfigSetXML include ConfigSet file to Dotweb.Items +// IncludeConfigSet include ConfigSet file to Dotweb.Config.ConfigSet, can use ctx.ConfigSet to use your data // same key will cover oldest value // support xml\json\yaml func (conf *Config) IncludeConfigSet(configFile string, confType string) error { diff --git a/config/configs_test.go b/config/configs_test.go index b88e4b5..c35fe66 100644 --- a/config/configs_test.go +++ b/config/configs_test.go @@ -15,8 +15,8 @@ func TestInitConfig(t *testing.T) { test.NotNil(t,conf) test.NotNil(t,conf.App) test.NotNil(t,conf.App.LogPath) - test.NotNil(t,conf.AppSets) - test.Equal(t,4, len(conf.AppSets)) + test.NotNil(t,conf.ConfigSet) + test.Equal(t,4, conf.ConfigSet.Len()) } //该测试方法报错... @@ -28,6 +28,6 @@ func TestInitConfigWithXml(t *testing.T) { test.NotNil(t,conf) test.NotNil(t,conf.App) test.NotNil(t,conf.App.LogPath) - test.NotNil(t,conf.AppSets) - test.Equal(t,4, len(conf.AppSets)) + test.NotNil(t,conf.ConfigSet) + test.Equal(t,4, conf.ConfigSet.Len()) } \ No newline at end of file diff --git a/config/configset.go b/config/configset.go index c2fb71d..50dc1d6 100644 --- a/config/configset.go +++ b/config/configset.go @@ -8,14 +8,14 @@ import ( ) type ( - //单元配置组,包含一系列单元配置节点 + // ConfigSet 单元配置组,包含一系列单元配置节点 ConfigSet struct { XMLName xml.Name `xml:"config" json:"-" yaml:"-"` Name string `xml:"name,attr"` ConfigSetNodes []*ConfigSetNode `xml:"set"` } - //update for issue #16 配置文件 + // ConfigSetNode update for issue #16 配置文件 ConfigSetNode struct { Key string `xml:"key,attr"` Value string `xml:"value,attr"` diff --git a/context_test.go b/context_test.go index cc10e47..e81a360 100644 --- a/context_test.go +++ b/context_test.go @@ -74,7 +74,7 @@ func TestWriteString(t *testing.T) { //call function //这里是一个interface数组,用例需要小心. - _,contextErr:=context.WriteString(string(animalJson)) + contextErr:=context.WriteString(string(animalJson)) test.Nil(t,contextErr) //header @@ -111,7 +111,7 @@ func TestWriteJson(t *testing.T) { test.Nil(t,err) //call function - _,contextErr:=context.WriteJson(exceptedObject) + contextErr:=context.WriteJson(exceptedObject) test.Nil(t,contextErr) //header @@ -146,7 +146,7 @@ func TestWriteJsonp(t *testing.T) { callback:="jsonCallBack" //call function - _,err:=context.WriteJsonp(callback,exceptedObject) + err:=context.WriteJsonp(callback,exceptedObject) test.Nil(t,err) //check result diff --git a/core/concurrenceMap.go b/core/concurrenceMap.go index 030bfea..542afc3 100644 --- a/core/concurrenceMap.go +++ b/core/concurrenceMap.go @@ -6,6 +6,7 @@ import ( ) type ( + // ReadonlyMap only support readonly method for map ReadonlyMap interface { Get(key string) (value interface{}, exists bool) GetString(key string) string @@ -14,6 +15,8 @@ type ( Exists(key string) bool Len() int } + + // ReadonlyMap support concurrence for map ConcurrenceMap interface { Get(key string) (value interface{}, exists bool) GetString(key string) string @@ -28,12 +31,13 @@ type ( } ) -//自带锁,并发安全的Map +// ItemMap concurrence map type ItemMap struct { innerMap map[string]interface{} *sync.RWMutex } +// NewItemMap create new ItemMap func NewItemMap() *ItemMap { return &ItemMap{ innerMap: make(map[string]interface{}), @@ -41,6 +45,7 @@ func NewItemMap() *ItemMap { } } +// NewConcurrenceMap create new ConcurrenceMap func NewConcurrenceMap() ConcurrenceMap { return &ItemMap{ innerMap: make(map[string]interface{}), @@ -48,6 +53,7 @@ func NewConcurrenceMap() ConcurrenceMap { } } +// NewReadonlyMap create new ReadonlyMap func NewReadonlyMap() ReadonlyMap { return &ItemMap{ innerMap: make(map[string]interface{}), @@ -55,9 +61,7 @@ func NewReadonlyMap() ReadonlyMap { } } -/* -* 以key、value置入AppContext - */ +// Set 以key、value置入ItemMap func (ctx *ItemMap) Set(key string, value interface{}) error { ctx.Lock() ctx.innerMap[key] = value @@ -65,9 +69,7 @@ func (ctx *ItemMap) Set(key string, value interface{}) error { return nil } -/* -* 读取指定key在AppContext中的内容 - */ +// Get 读取指定key在ItemMap中的内容 func (ctx *ItemMap) Get(key string) (value interface{}, exists bool) { ctx.RLock() value, exists = ctx.innerMap[key] @@ -75,16 +77,16 @@ func (ctx *ItemMap) Get(key string) (value interface{}, exists bool) { return value, exists } -//remove item by gived key -//if not exists key, do nothing... +// Remove remove item by gived key +// if not exists key, do nothing... func (ctx *ItemMap) Remove(key string) { ctx.Lock() delete(ctx.innerMap, key) ctx.Unlock() } -//get item by gived key, and remove it -//only can be read once, it will be locked +// Once get item by gived key, and remove it +// only can be read once, it will be locked func (ctx *ItemMap) Once(key string) (value interface{}, exists bool) { ctx.Lock() defer ctx.Unlock() @@ -95,9 +97,8 @@ func (ctx *ItemMap) Once(key string) (value interface{}, exists bool) { return value, exists } -/* -* 读取指定key在AppContext中的内容,以string格式输出 - */ + +// GetString 读取指定key在AppContext中的内容,以string格式输出 func (ctx *ItemMap) GetString(key string) string { value, exists := ctx.Get(key) if !exists { @@ -106,9 +107,8 @@ func (ctx *ItemMap) GetString(key string) string { return fmt.Sprint(value) } -/* -* 读取指定key在AppContext中的内容,以int格式输出 - */ + +// GetInt 读取指定key在AppContext中的内容,以int格式输出 func (ctx *ItemMap) GetInt(key string) int { value, exists := ctx.Get(key) if !exists { @@ -117,9 +117,7 @@ func (ctx *ItemMap) GetInt(key string) int { return value.(int) } -/* -* 读取指定key在AppContext中的内容,以int格式输出 - */ +// GetUInt64 读取指定key在AppContext中的内容,以int格式输出 func (ctx *ItemMap) GetUInt64(key string) uint64 { value, exists := ctx.Get(key) if !exists { @@ -128,18 +126,18 @@ func (ctx *ItemMap) GetUInt64(key string) uint64 { return value.(uint64) } -//check exists key +// Exists check exists key func (ctx *ItemMap) Exists(key string) bool { _, exists := ctx.innerMap[key] return exists } -//get current map, returns map[string]interface{} +// GetCurrentMap get current map, returns map[string]interface{} func (ctx *ItemMap) GetCurrentMap() map[string]interface{} { return ctx.innerMap } -//get context length +// Len get context length func (ctx *ItemMap) Len() int { return len(ctx.innerMap) } diff --git a/dotweb.go b/dotweb.go index 02c0741..f069b09 100644 --- a/dotweb.go +++ b/dotweb.go @@ -51,12 +51,17 @@ type ( ) const ( - DefaultHTTPPort = 8080 //DefaultHTTPPort default http port; fixed for #70 UPDATE default http port 80 to 8080 - DefaultConfigSetGroupName = "default" + // DefaultHTTPPort default http port; fixed for #70 UPDATE default http port 80 to 8080 + DefaultHTTPPort = 8080 + + // RunMode_Development app runmode in development mode RunMode_Development = "development" + // RunMode_Production app runmode in production mode RunMode_Production = "production" + //StartMode_New app startmode in New mode StartMode_New = "New" + //StartMode_Classic app startmode in Classic mode StartMode_Classic = "Classic" ) diff --git a/example/configset/main.go b/example/configset/main.go index b14c319..009079a 100644 --- a/example/configset/main.go +++ b/example/configset/main.go @@ -36,6 +36,7 @@ func main() { fmt.Println("dotweb.StartServer error => ", err) } +// ConfigSet func ConfigSet(ctx dotweb.Context) error { vkey1 := ctx.ConfigSet().GetString("set1") vkey2 := ctx.ConfigSet().GetString("set2") @@ -43,6 +44,7 @@ func ConfigSet(ctx dotweb.Context) error { return ctx.WriteString("\r\n") } +// InitRoute func InitRoute(server *dotweb.HttpServer) { server.GET("/c", ConfigSet) } From 4e2718623b47ee3586abdc22b41d87ee046d5f00 Mon Sep 17 00:00:00 2001 From: "pzrr@qq.com" Date: Fri, 26 Jan 2018 10:51:45 +0800 Subject: [PATCH 5/5] =?UTF-8?q?####=20Version=201.4.8=20*=20=E8=B0=83?= =?UTF-8?q?=E6=95=B4=EF=BC=9AItemContext=E6=9B=B4=E5=90=8D=E4=B8=BAItemMap?= =?UTF-8?q?=EF=BC=8C=E6=96=B0=E5=A2=9EConcurrenceMap=E3=80=81ReadonlyMap?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3=20*=20=E8=B0=83=E6=95=B4=EF=BC=9ADotweb.AppC?= =?UTF-8?q?ontext=E5=8F=98=E6=9B=B4=E4=B8=BADotweb.Items=20*=20=E8=B0=83?= =?UTF-8?q?=E6=95=B4=EF=BC=9AHttpContext.AppContext=E5=8F=98=E6=9B=B4?= =?UTF-8?q?=E4=B8=BAHttpContext.AppItems=20*=20=E8=B0=83=E6=95=B4=EF=BC=9A?= =?UTF-8?q?HttpContext.AppSetConfig=E5=8F=98=E6=9B=B4=E4=B8=BAHttpContext.?= =?UTF-8?q?ConfigSet=20*=20=E8=B0=83=E6=95=B4=EF=BC=9Aconfig.AppSet?= =?UTF-8?q?=E5=8F=98=E6=9B=B4=E4=B8=BAconfig.ConfigSet=20*=20=E6=96=B0?= =?UTF-8?q?=E5=A2=9E:=20config.ParseConfigSetXML\ParseConfigSetJSON\ParseC?= =?UTF-8?q?onfigSetYaml=EF=BC=8C=E7=94=A8=E4=BA=8E=E8=A7=A3=E6=9E=90?= =?UTF-8?q?=E5=B8=B8=E8=A7=84Key\Value=E6=A0=BC=E5=BC=8F=E7=9A=84=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=E6=96=87=E4=BB=B6=20*=20=E6=96=B0=E5=A2=9E=EF=BC=9Aco?= =?UTF-8?q?nfig.Config.IncludeConfigSet=EF=BC=8C=E7=94=A8=E4=BA=8E?= =?UTF-8?q?=E5=90=91config.ConfigSet=E4=B8=AD=E5=AF=BC=E5=85=A5Key\Value?= =?UTF-8?q?=E6=A0=BC=E5=BC=8F=E7=9A=84=E9=85=8D=E7=BD=AE=E6=96=87=E4=BB=B6?= =?UTF-8?q?=EF=BC=8C=E9=80=9A=E8=BF=87HttpContext.ConfigSet=E8=8E=B7?= =?UTF-8?q?=E5=8F=96=E7=9B=B8=E5=85=B3=E8=AE=BE=E7=BD=AE=E4=BF=A1=E6=81=AF?= =?UTF-8?q?=20*=20ParseConfigSetXML:=E6=94=AF=E6=8C=81xml=E6=A0=BC?= =?UTF-8?q?=E5=BC=8F=E6=96=87=E4=BB=B6=E8=A7=A3=E6=9E=90=EF=BC=8C=E8=BF=94?= =?UTF-8?q?=E5=9B=9Ecore.ConcurrenceMap=20*=20ParseConfigSetJSON:=E6=94=AF?= =?UTF-8?q?=E6=8C=81json=E6=A0=BC=E5=BC=8F=E6=96=87=E4=BB=B6=E8=A7=A3?= =?UTF-8?q?=E6=9E=90=EF=BC=8C=E8=BF=94=E5=9B=9Ecore.ConcurrenceMap=20*=20P?= =?UTF-8?q?arseConfigSetYaml:=E6=94=AF=E6=8C=81yaml=E6=A0=BC=E5=BC=8F?= =?UTF-8?q?=E6=96=87=E4=BB=B6=E8=A7=A3=E6=9E=90=EF=BC=8C=E8=BF=94=E5=9B=9E?= =?UTF-8?q?core.ConcurrenceMap=20*=20=E5=85=B7=E4=BD=93=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E6=96=87=E4=BB=B6=E6=A0=BC=E5=BC=8F=E5=8F=AF=E5=8F=82=E8=80=83?= =?UTF-8?q?example/configset=20*=20=E6=96=B0=E5=A2=9E=E7=A4=BA=E4=BE=8B?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=20example/configset=20*=202018-01-24=2022:00?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- example/config/main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example/config/main.go b/example/config/main.go index 7f24e0f..bc1b2c9 100644 --- a/example/config/main.go +++ b/example/config/main.go @@ -49,7 +49,7 @@ func Index(ctx dotweb.Context) error { func GetAppSet(ctx dotweb.Context) error { key := ctx.QueryString("key") - return ctx.WriteString(ctx.Request().Url(), " => key = ", ctx.AppSetConfig().GetString(key)) + return ctx.WriteString(ctx.Request().Url(), " => key = ", ctx.ConfigSet().GetString(key)) } func DefaultPanic(ctx dotweb.Context) error {