diff --git a/g/net/ghttp/http.go b/g/net/ghttp/http.go
index a5180bd6c..0d32729f7 100644
--- a/g/net/ghttp/http.go
+++ b/g/net/ghttp/http.go
@@ -1,107 +1,2 @@
package ghttp
-import (
- "net/http"
- "time"
- "crypto/tls"
- "log"
- "net/url"
-)
-
-// http客户端
-type Client struct {
- http.Client
-}
-
-// http server结构体
-type Server struct {
- server http.Server
- config ServerConfig
- handlerMap HandlerMap
-}
-
-// 请求对象
-type ClientRequest struct {
- http.Request
- getvals *url.Values
-}
-
-// 客户端请求结果对象
-type ClientResponse struct {
- http.Response
-}
-
-// 服务端请求返回对象
-type ServerResponse struct {
- http.ResponseWriter
-}
-
-// http回调函数
-type HandlerFunc func(*ClientRequest, *ServerResponse)
-
-// uri与回调函数的绑定记录表
-type HandlerMap map[string]HandlerFunc
-
-// HTTP Server 设置结构体
-type ServerConfig struct {
- // HTTP Server基础字段
- Addr string // 监听IP和端口,监听本地所有IP使用":端口"
- Handler http.Handler // 默认的处理函数
- TLSConfig *tls.Config // TLS配置
- ReadTimeout time.Duration
- WriteTimeout time.Duration
- IdleTimeout time.Duration
- MaxHeaderBytes int // 最大的header长度
- ErrorLog *log.Logger // 错误日志的处理接口
- // gf 扩展信息字段
- IndexFiles []string // 默认访问的文件列表
- IndexFolder bool // 如果访问目录是否显示目录列表
- ServerAgent string // server agent
- ServerRoot string // 服务器服务的本地目录根路径
-}
-
-// 默认HTTP Server
-var defaultServerConfig = ServerConfig {
- Addr : ":80",
- Handler : nil,
- ReadTimeout : 60 * time.Second,
- WriteTimeout : 60 * time.Second,
- IdleTimeout : 60 * time.Second,
- MaxHeaderBytes : 1024,
- IndexFiles : []string{"index.html", "index.htm"},
- IndexFolder : false,
- ServerAgent : "gf",
- ServerRoot : "",
-}
-
-// 修改默认的http server配置
-func SetDefaultServerConfig (c ServerConfig) {
- defaultServerConfig = c
-}
-
-// 创建一个默认配置的HTTP Server(默认监听端口是80)
-func NewServer() (*Server) {
- return NewServerByConfig(defaultServerConfig)
-}
-
-// 创建一个HTTP Server,返回指针
-func NewServerByAddr(addr string) (*Server) {
- config := defaultServerConfig
- config.Addr = addr
- return NewServerByConfig(config)
-}
-
-// 创建一个HTTP Server
-func NewServerByAddrRoot(addr string, root string) (*Server) {
- config := defaultServerConfig
- config.Addr = addr
- config.ServerRoot = root
- return NewServerByConfig(config)
-}
-
-// 根据输入配置创建一个http server对象
-func NewServerByConfig(s ServerConfig) (*Server) {
- var server Server
- server.SetConfig(s)
- return &server
-}
\ No newline at end of file
diff --git a/g/net/ghttp/http_client.go b/g/net/ghttp/http_client.go
index 0f1877591..0fd08e395 100644
--- a/g/net/ghttp/http_client.go
+++ b/g/net/ghttp/http_client.go
@@ -4,8 +4,26 @@ import (
"net/http"
"strings"
"time"
+ "net/url"
+ "bytes"
)
+// http客户端
+type Client struct {
+ http.Client
+}
+
+// 请求对象
+type ClientRequest struct {
+ http.Request
+ getvals *url.Values // GET参数
+}
+
+// 客户端请求结果对象
+type ClientResponse struct {
+ http.Response
+}
+
// http客户端对象指针
func NewClient() (*Client) {
return &Client{}
@@ -17,106 +35,104 @@ func (c *Client) SetTimeOut(t time.Duration) {
}
// GET请求
-func (c *Client) Get(url string) *ClientResponse {
- return c.Request("GET", url, "")
+func (c *Client) Get(url string) (*ClientResponse, error) {
+ return c.Request("GET", url, []byte(""))
}
// PUT请求
-func (c *Client) Put(url, data string) *ClientResponse {
- return c.Request("PUT", url, data)
+func (c *Client) Put(url, data string) (*ClientResponse, error) {
+ return c.Request("PUT", url, []byte(data))
}
// POST请求提交数据
-func (c *Client) Post(url, data string) *ClientResponse {
+func (c *Client) Post(url, data string) (*ClientResponse, error) {
resp, err := http.Post(url, "application/x-www-form-urlencoded", strings.NewReader(data))
if err != nil {
- //glog.Println(err)
- return nil
+ return nil, err
}
r := &ClientResponse{}
r.Response = *resp
- return r
+ return r, nil
}
// DELETE请求
-func (c *Client) Delete(url, data string) *ClientResponse {
- return c.Request("DELETE", url, data)
+func (c *Client) Delete(url, data string) (*ClientResponse, error) {
+ return c.Request("DELETE", url, []byte(data))
}
-func (c *Client) Head(url, data string) *ClientResponse {
- return c.Request("HEAD", url, data)
+func (c *Client) Head(url, data string) (*ClientResponse, error) {
+ return c.Request("HEAD", url, []byte(data))
}
-func (c *Client) Patch(url, data string) *ClientResponse {
- return c.Request("PATCH", url, data)
+func (c *Client) Patch(url, data string) (*ClientResponse, error) {
+ return c.Request("PATCH", url, []byte(data))
}
-func (c *Client) Connect(url, data string) *ClientResponse{
- return c.Request("CONNECT", url, data)
+func (c *Client) Connect(url, data string) (*ClientResponse, error) {
+ return c.Request("CONNECT", url, []byte(data))
}
-func (c *Client) Options(url, data string) *ClientResponse{
- return c.Request("OPTIONS", url, data)
+func (c *Client) Options(url, data string) (*ClientResponse, error) {
+ return c.Request("OPTIONS", url, []byte(data))
}
-func (c *Client) Trace(url, data string) *ClientResponse {
- return c.Request("TRACE", url, data)
+func (c *Client) Trace(url, data string) (*ClientResponse, error) {
+ return c.Request("TRACE", url, []byte(data))
}
-// 请求并返回response对象
-func (c *Client) Request(method, url, data string) *ClientResponse {
- req, err := http.NewRequest(strings.ToUpper(method), url, strings.NewReader(data))
+// 请求并返回response对象,该方法支持二进制提交数据
+func (c *Client) Request(method, url string, data []byte) (*ClientResponse, error) {
+ req, err := http.NewRequest(strings.ToUpper(method), url, bytes.NewReader(data))
if err != nil {
- //glog.Println("creating request failed: " + err.Error())
- return nil
+ return nil, err
}
resp, err := c.Do(req)
if err != nil {
- //glog.Println("sending request failed: " + err.Error())
- return nil
+ return nil, err
}
r := &ClientResponse{}
r.Response = *resp
- return r
+ return r, nil
}
-func Get(url string) *ClientResponse {
- return Request("GET", url, "")
+func Get(url string) (*ClientResponse, error) {
+ return Request("GET", url, []byte(""))
}
-func Put(url, data string) *ClientResponse {
- return Request("PUT", url, data)
+func Put(url, data string) (*ClientResponse, error) {
+ return Request("PUT", url, []byte(data))
}
-func Post(url, data string) *ClientResponse {
- return Request("PUT", url, data)
+func Post(url, data string) (*ClientResponse, error) {
+ return Request("PUT", url, []byte(data))
}
-func Delete(url, data string) *ClientResponse {
- return Request("DELETE", url, data)
+func Delete(url, data string) (*ClientResponse, error) {
+ return Request("DELETE", url, []byte(data))
}
-func Head(url, data string) *ClientResponse {
- return Request("HEAD", url, data)
+func Head(url, data string) (*ClientResponse, error) {
+ return Request("HEAD", url, []byte(data))
}
-func Patch(url, data string) *ClientResponse {
- return Request("PATCH", url, data)
+func Patch(url, data string) (*ClientResponse, error) {
+ return Request("PATCH", url, []byte(data))
}
-func Connect(url, data string) *ClientResponse{
- return Request("CONNECT", url, data)
+func Connect(url, data string) (*ClientResponse, error) {
+ return Request("CONNECT", url, []byte(data))
}
-func Options(url, data string) *ClientResponse{
- return Request("OPTIONS", url, data)
+func Options(url, data string) (*ClientResponse, error) {
+ return Request("OPTIONS", url, []byte(data))
}
-func Trace(url, data string) *ClientResponse {
- return Request("TRACE", url, data)
+func Trace(url, data string) (*ClientResponse, error) {
+ return Request("TRACE", url, []byte(data))
}
-func Request(method, url, data string) *ClientResponse {
+// 该方法支持二进制提交数据
+func Request(method, url string, data []byte) (*ClientResponse, error) {
return NewClient().Request(method, url, data)
}
diff --git a/g/net/ghttp/http_request.go b/g/net/ghttp/http_client_request.go
similarity index 100%
rename from g/net/ghttp/http_request.go
rename to g/net/ghttp/http_client_request.go
diff --git a/g/net/ghttp/http_client_response.go b/g/net/ghttp/http_client_response.go
new file mode 100644
index 000000000..4c615ad36
--- /dev/null
+++ b/g/net/ghttp/http_client_response.go
@@ -0,0 +1,20 @@
+package ghttp
+
+import (
+ "io/ioutil"
+)
+
+// 获取返回的数据
+func (r *ClientResponse) ReadAll() []byte {
+ body, err := ioutil.ReadAll(r.Body)
+ if err != nil {
+ return nil
+ }
+ return body
+}
+
+// 关闭返回的HTTP链接
+func (r *ClientResponse) Close() {
+ r.Response.Close = true
+ r.Body.Close()
+}
\ No newline at end of file
diff --git a/g/net/ghttp/http_controller.go b/g/net/ghttp/http_controller.go
index 1b65b2181..97f33ea96 100644
--- a/g/net/ghttp/http_controller.go
+++ b/g/net/ghttp/http_controller.go
@@ -5,25 +5,12 @@ type Controller struct {
Server *Server
}
-// 控制器接口
-type ControllerApi interface {
- Get(r *ClientRequest, w *ServerResponse)
- Put(r *ClientRequest, w *ServerResponse)
- Post(r *ClientRequest, w *ServerResponse)
- Delete(r *ClientRequest, w *ServerResponse)
- Head(r *ClientRequest, w *ServerResponse)
- Patch(r *ClientRequest, w *ServerResponse)
- Connect(r *ClientRequest, w *ServerResponse)
- Options(r *ClientRequest, w *ServerResponse)
- Trace(r *ClientRequest, w *ServerResponse)
-}
-
-func (c *Controller) Get(r *ClientRequest, w *ServerResponse) {}
-func (c *Controller) Put(r *ClientRequest, w *ServerResponse) {}
-func (c *Controller) Post(r *ClientRequest, w *ServerResponse) {}
-func (c *Controller) Delete(r *ClientRequest, w *ServerResponse) {}
-func (c *Controller) Head(r *ClientRequest, w *ServerResponse) {}
-func (c *Controller) Patch(r *ClientRequest, w *ServerResponse) {}
-func (c *Controller) Connect(r *ClientRequest, w *ServerResponse) {}
-func (c *Controller) Options(r *ClientRequest, w *ServerResponse) {}
-func (c *Controller) Trace(r *ClientRequest, w *ServerResponse) {}
\ No newline at end of file
+func (c *Controller) Get(*ClientRequest, *ServerResponse) {}
+func (c *Controller) Put(*ClientRequest, *ServerResponse) {}
+func (c *Controller) Post(*ClientRequest, *ServerResponse) {}
+func (c *Controller) Delete(*ClientRequest, *ServerResponse) {}
+func (c *Controller) Head(*ClientRequest, *ServerResponse) {}
+func (c *Controller) Patch(*ClientRequest, *ServerResponse) {}
+func (c *Controller) Connect(*ClientRequest, *ServerResponse) {}
+func (c *Controller) Options(*ClientRequest, *ServerResponse) {}
+func (c *Controller) Trace(*ClientRequest, *ServerResponse) {}
\ No newline at end of file
diff --git a/g/net/ghttp/http_controller_rest.go b/g/net/ghttp/http_controller_rest.go
new file mode 100644
index 000000000..183ab6a17
--- /dev/null
+++ b/g/net/ghttp/http_controller_rest.go
@@ -0,0 +1,14 @@
+package ghttp
+
+// RESTful控制器接口
+type ControllerRest interface {
+ Get(*ClientRequest, *ServerResponse)
+ Put(*ClientRequest, *ServerResponse)
+ Post(*ClientRequest, *ServerResponse)
+ Delete(*ClientRequest, *ServerResponse)
+ Head(*ClientRequest, *ServerResponse)
+ Patch(*ClientRequest, *ServerResponse)
+ Connect(*ClientRequest, *ServerResponse)
+ Options(*ClientRequest, *ServerResponse)
+ Trace(*ClientRequest, *ServerResponse)
+}
\ No newline at end of file
diff --git a/g/net/ghttp/http_response.go b/g/net/ghttp/http_response.go
deleted file mode 100644
index 0a1fac0ed..000000000
--- a/g/net/ghttp/http_response.go
+++ /dev/null
@@ -1,35 +0,0 @@
-package ghttp
-
-import (
- "gitee.com/johng/gf/g/encoding/gjson"
- "io/ioutil"
- "gitee.com/johng/gf/g/os/glog"
-)
-
-type ResponseJson struct {
- Result int `json:"result"`
- Message string `json:"message"`
- Data interface{} `json:"data"`
-}
-
-// 关闭返回的HTTP链接
-func (r *ClientResponse) Close() {
- r.Response.Close = true
- r.Body.Close()
-}
-
-// 返回固定格式的json
-func (r *ServerResponse) ResponseJson(result int, message string, data interface{}) {
- r.Header().Set("Content-type", "application/json")
- r.Write([]byte(gjson.Encode(ResponseJson{ result, message, data })))
-}
-
-// 获取返回的数据
-func (r *ClientResponse) ReadAll() string {
- body, err := ioutil.ReadAll(r.Body)
- if err != nil {
- glog.Println(err)
- return ""
- }
- return string(body)
-}
\ No newline at end of file
diff --git a/g/net/ghttp/http_server.go b/g/net/ghttp/http_server.go
index ae1cb0a96..1cfe5c912 100644
--- a/g/net/ghttp/http_server.go
+++ b/g/net/ghttp/http_server.go
@@ -7,16 +7,38 @@ import (
"crypto/tls"
"time"
"log"
- "regexp"
- "gitee.com/johng/gf/g/os/glog"
+ "sync"
+ "errors"
)
+// http server结构体
+type Server struct {
+ hmu sync.RWMutex // handlerMap互斥锁
+ server http.Server // 底层http server对象
+ config ServerConfig // 配置对象
+ handlerMap HandlerMap // 回调函数
+}
+
+// http回调函数
+type HandlerFunc func(*ClientRequest, *ServerResponse)
+
+// uri与回调函数的绑定记录表
+type HandlerMap map[string]HandlerFunc
+
+// 创建一个默认配置的HTTP Server(默认监听端口是80)
+func NewServer() (*Server) {
+ server := Server{}
+ server.SetConfig(defaultServerConfig)
+ return &server
+}
+
// 执行
func (s *Server)Run() error {
// 底层http server配置
if s.config.Handler == nil {
s.config.Handler = http.HandlerFunc(s.defaultHttpHandle)
}
+ // 底层http server初始化
s.server = http.Server {
Addr : s.config.Addr,
Handler : s.config.Handler,
@@ -26,16 +48,10 @@ func (s *Server)Run() error {
MaxHeaderBytes : s.config.MaxHeaderBytes,
}
// 执行端口监听
- err := s.server.ListenAndServe()
- if err != nil {
- glog.Fatalln(err)
+ if err := s.server.ListenAndServe(); err != nil {
+ return err
}
- return err
-}
-
-// 获取默认的http server设置
-func (h Server)GetDefaultSetting() ServerConfig {
- return defaultServerConfig
+ return nil
}
// http server setting设置
@@ -121,23 +137,25 @@ func (s *Server)SetServerRoot(root string) {
// 绑定URI到操作函数/方法
// pattern的格式形如:/user/list, put:/user, delete:/user
// 支持RESTful的请求格式,具体业务逻辑由绑定的处理方法来执行
-func (s *Server)BindHandle(pattern string, handler HandlerFunc ) {
+func (s *Server)BindHandle(pattern string, handler HandlerFunc) error {
+ s.hmu.Lock()
+ defer s.hmu.Unlock()
if s.handlerMap == nil {
s.handlerMap = make(HandlerMap)
}
key := ""
- reg := regexp.MustCompile(`(\w+?)\s*:\s*(.+)`)
- result := reg.FindStringSubmatch(pattern)
+ result := strings.Split(pattern, ":")
if len(result) > 1 {
- key = strings.ToUpper(result[1]) + ":" + result[2]
+ key = strings.ToUpper(result[0]) + ":" + result[1]
} else {
key = strings.TrimSpace(pattern)
}
if _, ok := s.handlerMap[key]; ok {
- panic("duplicated http server handler for: " + pattern)
+ return errors.New("duplicated http server handler for: " + pattern)
} else {
s.handlerMap[key] = handler
}
+ return nil
}
// 通过映射数组绑定URI到操作函数/方法
@@ -148,7 +166,7 @@ func (s *Server)BindHandleByMap(m HandlerMap) {
}
// 绑定控制器,控制器需要继承gmvc.ControllerBase对象并实现需要的REST方法
-func (s *Server)BindController(uri string, c ControllerApi) {
+func (s *Server)BindController(uri string, c ControllerRest) {
s.BindHandleByMap(HandlerMap{
"GET:" + uri : c.Get,
"PUT:" + uri : c.Put,
diff --git a/g/net/ghttp/http_server_config.go b/g/net/ghttp/http_server_config.go
new file mode 100644
index 000000000..0860d444f
--- /dev/null
+++ b/g/net/ghttp/http_server_config.go
@@ -0,0 +1,46 @@
+package ghttp
+
+import (
+ "net/http"
+ "crypto/tls"
+ "time"
+ "log"
+ "gitee.com/johng/gf/g/os/gfile"
+)
+
+// HTTP Server 设置结构体
+type ServerConfig struct {
+ // HTTP Server基础字段
+ Addr string // 监听IP和端口,监听本地所有IP使用":端口"
+ Handler http.Handler // 默认的处理函数
+ TLSConfig *tls.Config // TLS配置
+ ReadTimeout time.Duration
+ WriteTimeout time.Duration
+ IdleTimeout time.Duration
+ MaxHeaderBytes int // 最大的header长度
+ ErrorLog *log.Logger // 错误日志的处理接口
+ // gf 扩展信息字段
+ IndexFiles []string // 默认访问的文件列表
+ IndexFolder bool // 如果访问目录是否显示目录列表
+ ServerAgent string // server agent
+ ServerRoot string // 服务器服务的本地目录根路径
+}
+
+// 默认HTTP Server
+var defaultServerConfig = ServerConfig {
+ Addr : ":80",
+ Handler : nil,
+ ReadTimeout : 60 * time.Second,
+ WriteTimeout : 60 * time.Second,
+ IdleTimeout : 60 * time.Second,
+ MaxHeaderBytes : 1024,
+ IndexFiles : []string{"index.html", "index.htm"},
+ IndexFolder : false,
+ ServerAgent : "gf",
+ ServerRoot : gfile.SelfDir(),
+}
+
+// 获取默认的http server设置
+func DefaultSetting() ServerConfig {
+ return defaultServerConfig
+}
\ No newline at end of file
diff --git a/g/net/ghttp/http_server_handle.go b/g/net/ghttp/http_server_handle.go
index 56c04f520..df6ab9b47 100644
--- a/g/net/ghttp/http_server_handle.go
+++ b/g/net/ghttp/http_server_handle.go
@@ -15,8 +15,8 @@ import (
// 默认HTTP Server处理入口,底层默认使用了gorutine调用该接口
func (s *Server)defaultHttpHandle(w http.ResponseWriter, r *http.Request) {
request := ClientRequest{}
- response := ServerResponse {}
- request.Request = *r
+ response := ServerResponse {server : s}
+ request.Request = *r
response.ResponseWriter = w
if f, ok := s.handlerMap[r.URL.Path]; ok {
f(&request, &response)
@@ -93,8 +93,7 @@ func (s *Server)listDir(w http.ResponseWriter, f http.File) {
if d.IsDir() {
name += "/"
}
- url := url.URL{Path: name}
- fmt.Fprintf(w, "%s\n", url.String(), ghtml.SpecialChars(name))
+ fmt.Fprintf(w, "%s\n", url.URL{Path: name}.String(), ghtml.SpecialChars(name))
}
fmt.Fprintf(w, "\n")
}
diff --git a/g/net/ghttp/http_server_response.go b/g/net/ghttp/http_server_response.go
new file mode 100644
index 000000000..80561dd4e
--- /dev/null
+++ b/g/net/ghttp/http_server_response.go
@@ -0,0 +1,36 @@
+package ghttp
+
+import (
+ "net/http"
+ "gitee.com/johng/gf/g/encoding/gjson"
+)
+
+// 服务端请求返回对象
+type ServerResponse struct {
+ http.ResponseWriter
+ server *Server // 所属Server对象
+}
+
+// 返回的固定JSON数据结构
+type ResponseJson struct {
+ Result int `json:"result"`
+ Message string `json:"message"`
+ Data interface{} `json:"data"`
+}
+
+// 返回信息
+func (r *ServerResponse) Response(content []byte) {
+ if r.Header().Get("Content-Type") == "" {
+ r.Header().Set("Content-Type", "text/plain; charset=utf-8")
+ }
+ r.Write(content)
+}
+
+// 返回固定格式的json
+func (r *ServerResponse) ResponseJson(result int, message string, data interface{}) {
+ if r.Header().Get("Content-Type") == "" {
+ r.Header().Set("Content-Type", "application/json")
+ }
+ r.Write([]byte(gjson.Encode(ResponseJson{ result, message, data })))
+}
+
diff --git a/g/os/gcache/gcache.go b/g/os/gcache/gcache.go
index 0f1c99b34..e02be91de 100644
--- a/g/os/gcache/gcache.go
+++ b/g/os/gcache/gcache.go
@@ -8,35 +8,41 @@ import (
)
const (
- gCACHE_GROUP_SIZE = 4 // 缓存分区大小,不能超过uint8的最大值
+ gDEFAULT_CACHE_GROUP_SIZE = 4 // 默认缓存分区大小,不能超过uint8的最大值
)
+// 缓存对象
type Cache struct {
sync.RWMutex
- m map[uint8]*CacheMap // 以分区大小数字作为索引
+ g uint8 // 分区大小
+ m map[uint8]*CacheMap // 以分区大小数字作为索引
}
+// 缓存分区对象
type CacheMap struct {
sync.RWMutex
- deleted bool // 对象是否已删除,以便判断停止goroutine
+ closed bool // 对象是否已删除,以便判断停止goroutine
m map[string]CacheItem // 键值对
}
+// 缓存数据项
type CacheItem struct {
v interface{} // 缓存键值
e int64 // 过期时间
}
// 全局缓存管理对象
-var cache *Cache = New()
+var cache *Cache = New(gDEFAULT_CACHE_GROUP_SIZE)
// Cache对象按照缓存键名首字母做了分组
-func New() *Cache {
+func New(group uint8) *Cache {
c := &Cache {
+ g : group,
m : make(map[uint8]*CacheMap),
}
+ // 初始化分区对象
var i uint8 = 0
- for ; i < gCACHE_GROUP_SIZE; i++ {
+ for ; i < group; i++ {
m := &CacheMap {
m : make(map[string]CacheItem),
}
@@ -158,20 +164,14 @@ func (c *Cache) Size() int {
func (c *Cache) Close() {
c.RLock()
for _, cm := range c.m {
- cm.Lock()
- cm.deleted = true
- cm.Unlock()
+ cm.Close()
}
c.RUnlock()
-
- c.Lock()
- c.m = nil
- c.Unlock()
}
// 计算缓存的索引
func (c *Cache) getIndex(k string) uint8 {
- return uint8(ghash.BKDRHash([]byte(k)) % gCACHE_GROUP_SIZE)
+ return uint8(ghash.BKDRHash([]byte(k)) % uint32(c.g))
}
// 设置kv缓存键值对,过期时间单位为毫秒
@@ -207,26 +207,32 @@ func (cm *CacheMap) Remove(k string) {
cm.Unlock()
}
-// 自动清理过期键值对(每间隔60秒执行)
+// 关闭缓存分区
+func (cm *CacheMap) Close() {
+ cm.Lock()
+ cm.closed = true
+ cm.Unlock()
+}
+
+// 是否删除
+func (cm *CacheMap) isClosed() bool {
+ cm.RLock()
+ r := cm.closed
+ cm.RUnlock()
+ return r
+}
+
+// 自动清理过期键值对(每间隔3秒执行)
func (cm *CacheMap) autoClearLoop() {
- for !cm.deleted {
- expired := make([]string, 0)
- cm.RLock()
+ for !cm.isClosed() {
+ cm.Lock()
for k, v := range cm.m {
if v.e > 0 && v.e < gtime.Millisecond() {
- expired = append(expired, k)
- }
- }
- cm.RUnlock()
-
- if len(expired) > 0 {
- cm.Lock()
- for _, k := range expired {
delete(cm.m, k)
}
- cm.Unlock()
}
- time.Sleep(60 * time.Second)
+ cm.Unlock()
+ time.Sleep(3 * time.Second)
}
}