如何防止 sync.Pool 创建两个实例
How to prevent sync.Pool creating two instances
我正在实现一个 TCP 连接池以记录到 fluent-bit,这是代码
import (
"fmt"
"log"
"net"
"sync"
)
type FluentConnectionPool struct {
sync.Mutex
pool *sync.Pool
}
func (fl *FluentConnectionPool) Log(message string) {
fl.Lock()
defer fl.Unlock()
conn := fl.pool.Get().(*net.TCPConn)
defer fl.pool.Put(conn)
fmt.Printf("using: %v\n", conn.LocalAddr())
if _, err := conn.Write([]byte(message)) ; err != nil {
log.Fatal(err)
}
}
func (fl *FluentConnectionPool) Close() {
conn := fl.pool.Get().(*net.TCPConn)
defer conn.Close()
fmt.Printf("Closing: %v\n", conn.LocalAddr())
}
func New(address string) (*FluentConnectionPool, error) {
fluentAddress, err := net.ResolveTCPAddr("tcp", address)
if err != nil {
return nil, err
}
pool := &sync.Pool{New: func() interface{} {
connection, _ := net.DialTCP("tcp", nil, fluentAddress)
return connection
}}
return &FluentConnectionPool{
pool: pool,
}, nil
}
当我这样测试代码时
import "time"
func main() {
pool, _ := New("localhost:5170")
defer pool.Close()
for i := 0 ; i < 10 ; i++ {
go func() {
pool.Log(`{"data": {"name": "name here"}}`)
}()
}
time.Sleep(1 * time.Second)
}
输出是这样的
using: 127.0.0.1:43990
using: 127.0.0.1:43990
using: 127.0.0.1:43990
using: 127.0.0.1:43990
using: 127.0.0.1:43990
using: 127.0.0.1:43990
using: 127.0.0.1:43990
using: 127.0.0.1:43990
using: 127.0.0.1:43990
using: 127.0.0.1:43994
Closing: 127.0.0.1:43994
我不明白为什么即使我已锁定该功能,连接也会创建两次(43990 和 43994),所以 43990 上的连接仍然打开,您能解释一下为什么会这样吗?
谢谢!
来自 Pool
文档的这篇文章可能会解释该行为:
Any item stored in the Pool may be removed automatically at any time without notification. If the Pool holds the only reference when this happens, the item might be deallocated.
池很可能删除了您使用的连接。
我正在实现一个 TCP 连接池以记录到 fluent-bit,这是代码
import (
"fmt"
"log"
"net"
"sync"
)
type FluentConnectionPool struct {
sync.Mutex
pool *sync.Pool
}
func (fl *FluentConnectionPool) Log(message string) {
fl.Lock()
defer fl.Unlock()
conn := fl.pool.Get().(*net.TCPConn)
defer fl.pool.Put(conn)
fmt.Printf("using: %v\n", conn.LocalAddr())
if _, err := conn.Write([]byte(message)) ; err != nil {
log.Fatal(err)
}
}
func (fl *FluentConnectionPool) Close() {
conn := fl.pool.Get().(*net.TCPConn)
defer conn.Close()
fmt.Printf("Closing: %v\n", conn.LocalAddr())
}
func New(address string) (*FluentConnectionPool, error) {
fluentAddress, err := net.ResolveTCPAddr("tcp", address)
if err != nil {
return nil, err
}
pool := &sync.Pool{New: func() interface{} {
connection, _ := net.DialTCP("tcp", nil, fluentAddress)
return connection
}}
return &FluentConnectionPool{
pool: pool,
}, nil
}
当我这样测试代码时
import "time"
func main() {
pool, _ := New("localhost:5170")
defer pool.Close()
for i := 0 ; i < 10 ; i++ {
go func() {
pool.Log(`{"data": {"name": "name here"}}`)
}()
}
time.Sleep(1 * time.Second)
}
输出是这样的
using: 127.0.0.1:43990
using: 127.0.0.1:43990
using: 127.0.0.1:43990
using: 127.0.0.1:43990
using: 127.0.0.1:43990
using: 127.0.0.1:43990
using: 127.0.0.1:43990
using: 127.0.0.1:43990
using: 127.0.0.1:43990
using: 127.0.0.1:43994
Closing: 127.0.0.1:43994
我不明白为什么即使我已锁定该功能,连接也会创建两次(43990 和 43994),所以 43990 上的连接仍然打开,您能解释一下为什么会这样吗?
谢谢!
来自 Pool
文档的这篇文章可能会解释该行为:
Any item stored in the Pool may be removed automatically at any time without notification. If the Pool holds the only reference when this happens, the item might be deallocated.
池很可能删除了您使用的连接。