2018-07-04 19:32:51 +08:00
|
|
|
|
// Copyright 2018 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 gpool
|
|
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
|
"time"
|
2018-07-26 13:00:04 +08:00
|
|
|
|
"errors"
|
2018-07-04 19:32:51 +08:00
|
|
|
|
"gitee.com/johng/gf/g/os/gtime"
|
|
|
|
|
|
"gitee.com/johng/gf/g/container/glist"
|
|
|
|
|
|
"gitee.com/johng/gf/g/container/gtype"
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
// 对象池
|
|
|
|
|
|
type Pool struct {
|
2018-07-26 13:00:04 +08:00
|
|
|
|
list *glist.List // 可用/闲置的文件指针链表
|
|
|
|
|
|
closed *gtype.Bool // 连接池是否已关闭
|
|
|
|
|
|
Expire int64 // (毫秒)闲置最大时间,超过该时间则被系统回收
|
|
|
|
|
|
NewFunc func()(interface{}, error) // 创建对象的方法定义
|
|
|
|
|
|
ExpireFunc func(interface{}) // 对象的过期销毁方法(当池对象销毁需要执行额外的销毁操作时,需要定义该方法)
|
|
|
|
|
|
// 例如: net.Conn, os.File等对象都需要执行额外关闭操作
|
2018-07-04 19:32:51 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 对象池数据项
|
|
|
|
|
|
type poolItem struct {
|
|
|
|
|
|
expire int64 // (毫秒)过期时间
|
|
|
|
|
|
value interface{} // 对象值
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 创建一个对象池,为保证执行效率,过期时间一旦设定之后无法修改
|
2018-07-26 13:00:04 +08:00
|
|
|
|
// expire = 0表示不过期,expire < 0表示使用完立即回收,expire > 0表示超时回收
|
2018-07-21 15:23:16 +08:00
|
|
|
|
// 注意过期时间单位为**毫秒**
|
2018-07-04 19:32:51 +08:00
|
|
|
|
func New(expire int, newFunc...func() (interface{}, error)) *Pool {
|
|
|
|
|
|
r := &Pool {
|
|
|
|
|
|
list : glist.New(),
|
|
|
|
|
|
closed : gtype.NewBool(),
|
2018-07-12 20:32:56 +08:00
|
|
|
|
Expire : int64(expire),
|
2018-07-04 19:32:51 +08:00
|
|
|
|
}
|
|
|
|
|
|
if len(newFunc) > 0 {
|
2018-07-12 20:32:56 +08:00
|
|
|
|
r.NewFunc = newFunc[0]
|
2018-07-04 19:32:51 +08:00
|
|
|
|
}
|
|
|
|
|
|
go r.expireCheckingLoop()
|
|
|
|
|
|
return r
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-07-26 13:00:04 +08:00
|
|
|
|
// 设置对象过期销毁时的关闭方法
|
|
|
|
|
|
func (p *Pool) SetExpireFunc(expireFunc func(interface{})) {
|
|
|
|
|
|
p.ExpireFunc = expireFunc
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-07-04 19:32:51 +08:00
|
|
|
|
// 放一个临时对象到池中
|
2018-07-30 11:22:21 +08:00
|
|
|
|
func (p *Pool) Put(value interface{}) {
|
|
|
|
|
|
item := &poolItem {
|
|
|
|
|
|
value : value,
|
|
|
|
|
|
}
|
|
|
|
|
|
if p.Expire == 0 {
|
|
|
|
|
|
item.expire = 0
|
|
|
|
|
|
} else {
|
|
|
|
|
|
item.expire = gtime.Millisecond() + p.Expire
|
|
|
|
|
|
}
|
|
|
|
|
|
p.list.PushBack(item)
|
2018-07-04 19:32:51 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 从池中获得一个临时对象
|
|
|
|
|
|
func (p *Pool) Get() (interface{}, error) {
|
|
|
|
|
|
for !p.closed.Val() {
|
|
|
|
|
|
if r := p.list.PopFront(); r != nil {
|
|
|
|
|
|
f := r.(*poolItem)
|
2018-08-16 18:17:47 +08:00
|
|
|
|
if f.expire == 0 || f.expire > gtime.Millisecond() {
|
2018-07-04 19:32:51 +08:00
|
|
|
|
return f.value, nil
|
|
|
|
|
|
}
|
|
|
|
|
|
} else {
|
|
|
|
|
|
break
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2018-07-12 20:32:56 +08:00
|
|
|
|
if p.NewFunc != nil {
|
|
|
|
|
|
return p.NewFunc()
|
2018-07-04 19:32:51 +08:00
|
|
|
|
}
|
|
|
|
|
|
return nil, errors.New("pool is empty")
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 查询当前池中的对象数量
|
|
|
|
|
|
func (p *Pool) Size() int {
|
|
|
|
|
|
return p.list.Len()
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 关闭池
|
|
|
|
|
|
func (p *Pool) Close() {
|
|
|
|
|
|
p.closed.Set(true)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 超时检测循环
|
|
|
|
|
|
func (p *Pool) expireCheckingLoop() {
|
|
|
|
|
|
for !p.closed.Val() {
|
2018-07-21 15:23:16 +08:00
|
|
|
|
for {
|
|
|
|
|
|
if r := p.list.PopFront(); r != nil {
|
2018-07-26 13:00:04 +08:00
|
|
|
|
item := r.(*poolItem)
|
2018-08-16 18:17:47 +08:00
|
|
|
|
if item.expire == 0 || item.expire > gtime.Millisecond() {
|
2018-07-26 13:00:04 +08:00
|
|
|
|
p.list.PushFront(item)
|
2018-07-21 15:23:16 +08:00
|
|
|
|
break
|
|
|
|
|
|
}
|
2018-07-26 13:00:04 +08:00
|
|
|
|
if p.ExpireFunc != nil {
|
|
|
|
|
|
p.ExpireFunc(item.value)
|
|
|
|
|
|
}
|
2018-07-27 11:08:42 +08:00
|
|
|
|
} else {
|
|
|
|
|
|
break
|
2018-07-04 19:32:51 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2018-07-21 15:23:16 +08:00
|
|
|
|
time.Sleep(time.Second)
|
2018-07-04 19:32:51 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|