diff --git a/g/container/gqueue/gqueue.go b/g/container/gqueue/gqueue.go index 544e2549e..fa6cf25a9 100644 --- a/g/container/gqueue/gqueue.go +++ b/g/container/gqueue/gqueue.go @@ -35,7 +35,7 @@ func New(limit...int) *Queue { } return &Queue { list : list.New(), - limit : 0, + limit : size, limits : make(chan struct{}, size), events : make(chan struct{}, math.MaxInt32), closed : gtype.NewBool(), diff --git a/g/net/ghttp/http_server.go b/g/net/ghttp/http_server.go index dc0c7c3e9..20bf110a8 100644 --- a/g/net/ghttp/http_server.go +++ b/g/net/ghttp/http_server.go @@ -101,6 +101,7 @@ func GetServer(names...string) (*Server) { servedCount : gtype.NewInt(), closeQueue : gqueue.New(), } + // 设置路由解析缓存上限,使用LRU进行缓存淘汰 s.hooksCache.SetCap(10000) s.handlerCache.SetCap(10000) for _, v := range strings.Split(gHTTP_METHODS, ",") { @@ -143,10 +144,6 @@ func (s *Server) Run() error { // 清空当前的handlerCache func (s *Server) clearHandlerCache() { - // 只有在运行时才会生效 - if s.status != 1 { - return - } s.hmcmu.Lock() defer s.hmcmu.Unlock() s.handlerCache.Close() @@ -155,10 +152,6 @@ func (s *Server) clearHandlerCache() { // 清空当前的hooksCache func (s *Server) clearHooksCache() { - // 只有在运行时才会生效 - if s.status != 1 { - return - } s.hhcmu.Lock() defer s.hhcmu.Unlock() s.hooksCache.Close() diff --git a/g/net/ghttp/http_server_hooks.go b/g/net/ghttp/http_server_hooks.go index 01a077d14..683feaddc 100644 --- a/g/net/ghttp/http_server_hooks.go +++ b/g/net/ghttp/http_server_hooks.go @@ -21,6 +21,7 @@ type hookCacheItem struct { } // 事件回调注册方法 +// 因为有事件回调优先级的关系,叶子节点必须为一个链表,因此这里只有动态注册 func (s *Server) setHookHandler(pattern string, hook string, item *HandlerItem) error { domain, method, uri, err := s.parsePattern(pattern) if err != nil { @@ -33,6 +34,7 @@ func (s *Server) setHookHandler(pattern string, hook string, item *HandlerItem) s.hhmu.Lock() defer s.hhmu.Unlock() defer s.clearHooksCache() + if _, ok := s.hooksTree[domain]; !ok { s.hooksTree[domain] = make(map[string]interface{}) } @@ -87,6 +89,7 @@ func (s *Server) setHookHandler(pattern string, hook string, item *HandlerItem) // 事件回调 - 检索动态路由规则 // 并按照指定hook回调函数的优先级及注册顺序进行调用 func (s *Server) callHookHandler(r *Request, hook string) { + // 缓存清空时是直接修改属性,因此必须使用互斥锁 s.hhcmu.RLock() defer s.hhcmu.RUnlock() diff --git a/g/net/ghttp/http_server_router.go b/g/net/ghttp/http_server_router.go index 06eadf04c..f8b493305 100644 --- a/g/net/ghttp/http_server_router.go +++ b/g/net/ghttp/http_server_router.go @@ -23,6 +23,7 @@ type handlerCacheItem struct { // 查询请求处理方法 // 这里有个锁机制,可以并发读,但是不能并发写 func (s *Server) getHandler(r *Request) *HandlerItem { + // 缓存清空时是直接修改属性,因此必须使用互斥锁 s.hmcmu.RLock() defer s.hmcmu.RUnlock() @@ -76,22 +77,14 @@ func (s *Server) setHandler(pattern string, item *HandlerItem) error { item.uri = uri item.domain = domain item.method = method - // 静态注册 + s.hmmu.Lock() defer s.hmmu.Unlock() defer s.clearHandlerCache() - if method == gDEFAULT_METHOD { - for v, _ := range s.methodsMap { - s.handlerMap[s.handlerKey(domain, v, uri)] = item - } - } else { - s.handlerMap[s.handlerKey(domain, method, uri)] = item - } - - // 动态注册,首先需要判断是否是动态注册,如果不是那么就没必要添加到动态注册记录变量中 - // 非叶节点为哈希表检索节点,按照URI注册的层级进行高效检索,直至到叶子链表节点; - // 叶子节点是链表,按照优先级进行排序,优先级高的排前面,按照遍历检索,按照哈希表层级检索后的叶子链表一般数据量不大,所以效率比较高; if s.isUriHasRule(uri) { + // 动态注册,首先需要判断是否是动态注册,如果不是那么就没必要添加到动态注册记录变量中 + // 非叶节点为哈希表检索节点,按照URI注册的层级进行高效检索,直至到叶子链表节点; + // 叶子节点是链表,按照优先级进行排序,优先级高的排前面,按照遍历检索,按照哈希表层级检索后的叶子链表一般数据量不大,所以效率比较高; if _, ok := s.handlerTree[domain]; !ok { s.handlerTree[domain] = make(map[string]interface{}) } @@ -129,7 +122,6 @@ func (s *Server) setHandler(pattern string, item *HandlerItem) error { lists = append(lists, v.(*list.List)) } } - } } // 从头开始遍历链表,优先级高的放在前面 @@ -142,9 +134,16 @@ func (s *Server) setHandler(pattern string, item *HandlerItem) error { } l.PushBack(item) } + } else { + // 静态注册 + if method == gDEFAULT_METHOD { + for v, _ := range s.methodsMap { + s.handlerMap[s.handlerKey(domain, v, uri)] = item + } + } else { + s.handlerMap[s.handlerKey(domain, method, uri)] = item + } } - //b, _ := gparser.VarToJsonIndent(s.handlerTree) - //fmt.Println(string(b)) return nil } diff --git a/geg/other/test.go b/geg/other/test.go index 0fe79c90a..8bf6bd142 100644 --- a/geg/other/test.go +++ b/geg/other/test.go @@ -1,21 +1,23 @@ package main import ( - "gitee.com/johng/gf/g/net/ghttp" - "gitee.com/johng/gf/g/frame/gins" - "gitee.com/johng/gf/g" + "fmt" ) + +type T struct { + name string +} + + +func (t *T) swap(t2 *T) { + *t = &t2 +} + func main() { - s := ghttp.GetServer() - s.BindHandler("/template2", func(r *ghttp.Request){ - tplcontent := `id:{{.id}}, name:{{.name}}` - content, _ := gins.View().ParseContent(tplcontent, g.Map{ - "id" : 123, - "name" : "john", - }) - r.Response.Write(content) - }) - //s.SetPort(80) - s.Run() + t1 := &T{"john"} + t2 := &T{"smith"} + t2.swap(t2) + + fmt.Println(t1) } \ No newline at end of file