mirror of
https://gitee.com/johng/gf
synced 2026-06-06 16:21:40 +08:00
ghttp.Server增加事件回调特性,去掉Request ID生成器,采用性能更高的gtype包实现请求ID生成
This commit is contained in:
@ -19,10 +19,10 @@ import (
|
||||
"path/filepath"
|
||||
"gitee.com/johng/gf/g/util/gutil"
|
||||
"gitee.com/johng/gf/g/net/grouter"
|
||||
"gitee.com/johng/gf/g/util/gidgen"
|
||||
"gitee.com/johng/gf/g/container/gmap"
|
||||
"gitee.com/johng/gf/g/container/gqueue"
|
||||
"gitee.com/johng/gf/g/container/glist"
|
||||
"gitee.com/johng/gf/g/container/gtype"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -41,7 +41,7 @@ type Server struct {
|
||||
status int8 // 当前服务器状态(0:未启动,1:运行中)
|
||||
handlerMap HandlerMap // 所有注册的回调函数
|
||||
methodsMap map[string]bool // 所有支持的HTTP Method(初始化时自动填充)
|
||||
idgen *gidgen.Gen // 请求ID生成器
|
||||
servedCount *gtype.Int // 已经服务的请求数(4-8字节,不考虑溢出情况)
|
||||
closeQueue *gqueue.Queue // 请求结束的关闭队列(存放的是需要异步关闭处理的*Request对象)
|
||||
hooksMap *gmap.StringInterfaceMap // 钩子注册方法map,键值为按照注册顺序生成的glist,用于hook顺序调用
|
||||
Router *grouter.Router // 路由管理对象
|
||||
@ -77,7 +77,7 @@ func GetServer(names...string) (*Server) {
|
||||
name : name,
|
||||
handlerMap : make(HandlerMap),
|
||||
methodsMap : make(map[string]bool),
|
||||
idgen : gidgen.New(50000),
|
||||
servedCount : gtype.NewInt(),
|
||||
closeQueue : gqueue.New(),
|
||||
hooksMap : gmap.NewStringInterfaceMap(),
|
||||
Router : grouter.New(),
|
||||
@ -492,6 +492,16 @@ func (s *Server)BindHookHandler(pattern string, hook string, handler HandlerFunc
|
||||
return nil
|
||||
}
|
||||
|
||||
// 通过map批量绑定回调函数
|
||||
func (s *Server)BindHookHandlerByMap(pattern string, hookmap map[string]HandlerFunc) error {
|
||||
for k, v := range hookmap {
|
||||
if err := s.BindHookHandler(pattern, k, v); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
//// 绑定URI服务注册的Init回调函数,回调时按照注册顺序执行
|
||||
//// Init回调调用时机为请求进入控制器之前,初始化Request对象之后
|
||||
//func (s *Server)BindHookHandlerInit(pattern string, handler HandlerFunc) error {
|
||||
|
||||
@ -12,10 +12,14 @@ func (s *Server) startCloseQueueLoop() {
|
||||
for {
|
||||
if v := s.closeQueue.PopFront(); v != nil {
|
||||
r := v.(*Request)
|
||||
s.callHookHandler(r, "BeforeRequestClose")
|
||||
|
||||
// 关闭当前会话的Cookie
|
||||
r.Cookie.Close()
|
||||
// 更新Sssion会话超时时间
|
||||
// 更新Session会话超时时间
|
||||
r.Session.UpdateExpire()
|
||||
|
||||
s.callHookHandler(r, "AfterRequestClose")
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
@ -119,6 +119,16 @@ func (d *Domain)BindHookHandler(pattern string, hook string, handler HandlerFunc
|
||||
return nil
|
||||
}
|
||||
|
||||
// 通过map批量绑定回调函数
|
||||
func (d *Domain)BindHookHandlerByMap(pattern string, hookmap map[string]HandlerFunc) error {
|
||||
for domain, _ := range d.m {
|
||||
if err := d.s.BindHookHandlerByMap(pattern + "@" + domain, hookmap); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
//// 绑定URI服务注册的Init回调函数,回调时按照注册顺序执行
|
||||
//// Init回调调用时机为请求进入控制器之前,初始化Request对象之后
|
||||
//func (d *Domain)BindHookHandlerInit(pattern string, handler HandlerFunc) error {
|
||||
|
||||
@ -38,7 +38,7 @@ func (s *Server)handleRequest(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
// 构造请求参数对象
|
||||
request := &Request{
|
||||
Id : s.idgen.Int(),
|
||||
Id : s.servedCount.Add(1),
|
||||
Server : s,
|
||||
Request : *r,
|
||||
Response : &Response {
|
||||
@ -89,7 +89,9 @@ func (s *Server)callHandler(h *HandlerItem, r *Request) {
|
||||
s.callHookHandler(r, "AfterCookieOutput")
|
||||
|
||||
// 输出缓冲区
|
||||
s.callHookHandler(r, "BeforeBufferOutput")
|
||||
r.Response.OutputBuffer()
|
||||
s.callHookHandler(r, "AfterBufferOutput")
|
||||
|
||||
// 将Request对象指针丢到队列中异步处理
|
||||
s.closeQueue.PushBack(r)
|
||||
|
||||
18
g/os/gtime/time_test.go
Normal file
18
g/os/gtime/time_test.go
Normal file
@ -0,0 +1,18 @@
|
||||
// Copyright 2017 gf Author(https://gitee.com/johng/gf). All Rights Reserved.
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the MIT License.
|
||||
// If a copy of the MIT was not distributed with this file,
|
||||
// You can obtain one at https://gitee.com/johng/gf.
|
||||
|
||||
package gtime_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"gitee.com/johng/gf/g/os/gtime"
|
||||
)
|
||||
|
||||
func BenchmarkNanosecond(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
gtime.Nanosecond()
|
||||
}
|
||||
}
|
||||
@ -1,68 +0,0 @@
|
||||
// Copyright 2017 gf Author(https://gitee.com/johng/gf). All Rights Reserved.
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the MIT License.
|
||||
// If a copy of the MIT was not distributed with this file,
|
||||
// You can obtain one at https://gitee.com/johng/gf.
|
||||
|
||||
// ID生成器.
|
||||
// 内部采用了通道+缓冲池来实现高效的ID递增生成,
|
||||
// 非常适合高并发下使用
|
||||
package gidgen
|
||||
|
||||
import "math"
|
||||
|
||||
// ID生成器管理对象
|
||||
type Gen struct {
|
||||
ch chan uint
|
||||
closeQueue chan struct{}
|
||||
}
|
||||
|
||||
// 创建一个ID生成器,并给定ID池大小
|
||||
func New (bufsize int) *Gen {
|
||||
g := &Gen {
|
||||
ch : make(chan uint, bufsize),
|
||||
closeQueue : make(chan struct{}),
|
||||
}
|
||||
go g.startLoop()
|
||||
return g
|
||||
}
|
||||
|
||||
// 关闭生成器
|
||||
func (g *Gen) Close() {
|
||||
close(g.closeQueue)
|
||||
close(g.ch)
|
||||
}
|
||||
|
||||
// 内部循环,当最大值使用完之后重新从1开始获取
|
||||
func (g *Gen) startLoop() {
|
||||
for {
|
||||
select {
|
||||
case <- g.closeQueue:
|
||||
return
|
||||
default:
|
||||
// 当ch达到缓冲池大小,会阻塞,只要有线程取出值,再立即填充
|
||||
for i := uint(1); i < uint(math.MaxUint64); i++ {
|
||||
g.ch <- i
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 从池中获取一个ID返回(uint)
|
||||
func (g *Gen) Uint() uint {
|
||||
return <- g.ch
|
||||
}
|
||||
|
||||
// 从池中获取一个ID返回(int)
|
||||
func (g *Gen) Int() int {
|
||||
i := <- g.ch
|
||||
if i != 0 {
|
||||
i = i & 0x7FFFFFFFFFFFFFFF
|
||||
// 可能是int与uint之间的临界点
|
||||
if i == 0 {
|
||||
return g.Int()
|
||||
}
|
||||
}
|
||||
return int(i)
|
||||
}
|
||||
|
||||
29
geg/net/ghttp/events.go
Normal file
29
geg/net/ghttp/events.go
Normal file
@ -0,0 +1,29 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"gitee.com/johng/gf/g/net/ghttp"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
func main() {
|
||||
pattern := "/"
|
||||
ghttp.GetServer().BindHookHandlerByMap(pattern, map[string]ghttp.HandlerFunc{
|
||||
"BeforeServe" : func(r *ghttp.Request){ fmt.Println("BeforeServe") },
|
||||
"AfterServe" : func(r *ghttp.Request){ fmt.Println("AfterServe") },
|
||||
"BeforeRouterPatch" : func(r *ghttp.Request){ fmt.Println("BeforeRouterPatch") },
|
||||
"AfterRouterPatch" : func(r *ghttp.Request){ fmt.Println("AfterRouterPatch") },
|
||||
"BeforeCookieOutput" : func(r *ghttp.Request){ fmt.Println("BeforeCookieOutput") },
|
||||
"AfterCookieOutput" : func(r *ghttp.Request){ fmt.Println("AfterCookieOutput") },
|
||||
"BeforeBufferOutput" : func(r *ghttp.Request){ fmt.Println("BeforeBufferOutput") },
|
||||
"AfterBufferOutput" : func(r *ghttp.Request){ fmt.Println("AfterBufferOutput") },
|
||||
"BeforeRequestClose" : func(r *ghttp.Request){ fmt.Println("BeforeRequestClose") },
|
||||
"AfterRequestClose" : func(r *ghttp.Request){ fmt.Println("AfterRequestClose") },
|
||||
})
|
||||
ghttp.GetServer().BindHandler(pattern, func(r *ghttp.Request) {
|
||||
r.Response.WriteString("Hello World!")
|
||||
})
|
||||
ghttp.GetServer().SetPort(10000)
|
||||
ghttp.GetServer().Run()
|
||||
|
||||
select { }
|
||||
}
|
||||
@ -1,56 +1,10 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"gitee.com/johng/gf/g/database/gdb"
|
||||
"fmt"
|
||||
"math"
|
||||
)
|
||||
|
||||
type Model struct {
|
||||
TableName string
|
||||
}
|
||||
|
||||
var Db *gdb.Db
|
||||
|
||||
func init() {
|
||||
gdb.AddDefaultConfigNode(gdb.ConfigNode {
|
||||
Host : "127.0.0.1",
|
||||
Port : "3306",
|
||||
User : "root",
|
||||
Pass : "123456",
|
||||
Name : "test",
|
||||
Type : "mysql",
|
||||
Role : "master",
|
||||
Charset : "utf8",
|
||||
})
|
||||
var err error
|
||||
Db, err = gdb.Instance()
|
||||
checkErr(err)
|
||||
}
|
||||
|
||||
func checkErr(err error) {
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
type UserModel struct {
|
||||
Model
|
||||
}
|
||||
|
||||
func (u *UserModel) Get() (user gdb.Map){
|
||||
user, _ = Db.Table("user").Fields("uid, nickname, email").Where("uid = ?", 15).One()
|
||||
return
|
||||
}
|
||||
|
||||
func (u *UserModel) Insert(data gdb.Map) (id int64) {
|
||||
ret, _ := Db.Table("user").Data(data).Insert()
|
||||
id, _ = ret.LastInsertId()
|
||||
return
|
||||
}
|
||||
|
||||
func main() {
|
||||
u := &UserModel{}
|
||||
user := u.Get()
|
||||
fmt.Println(user)
|
||||
u.Insert(gdb.Map{"uid": 100, "name": "jack"})
|
||||
fmt.Println(math.MaxInt64)
|
||||
}
|
||||
Reference in New Issue
Block a user