Как предотвратить syn c .Pool при создании двух экземпляров - PullRequest
0 голосов
/ 04 мая 2020

Я реализую пул соединений TCP для записи в свободный бит, вот код

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 остается открытым, не могли бы вы объяснить, почему это произошло?

Спасибо!

1 Ответ

1 голос
/ 04 мая 2020

Это из документов Pool может объяснить поведение:

Любой элемент, сохраненный в пуле, может быть удален автоматически в любое время без уведомления. Если в этом случае пул содержит единственную ссылку, элемент может быть освобожден.

Вероятно, пул удалил используемое вами соединение.

...