refactor: phase 2 integrated new dialer into worker

This commit is contained in:
Jay
2026-06-06 17:32:03 -04:00
parent 7bc576ed98
commit a46e9f7ad8
13 changed files with 366 additions and 1026 deletions
+97 -39
View File
@@ -2,6 +2,8 @@ package honeybee
import (
"context"
"errors"
"fmt"
"log/slog"
"git.wisehodl.dev/jay/go-honeybee/transport"
@@ -19,6 +21,16 @@ type Dialer = types.Dialer
var NormalizeURL = transport.NormalizeURL
// ----------------------------------------------------------------------------
// Errors
// ----------------------------------------------------------------------------
var (
ErrPoolClosed = errors.New("pool is closed")
ErrPeerNotFound = errors.New("peer not found")
ErrPeerExists = errors.New("peer already exists")
)
// ----------------------------------------------------------------------------
// Types
// ----------------------------------------------------------------------------
@@ -55,10 +67,68 @@ type PeerStats struct {
}
type PoolPlugin struct {
Inbox chan<- types.InboxMessage
Events chan<- PoolEvent
InboxCounter *atomic.Uint64
ConnectionConfig transport.ConnectionConfig
Inbox chan<- types.InboxMessage
Events chan<- PoolEvent
InboxCounter *atomic.Uint64
}
// ----------------------------------------------------------------------------
// Config
// ----------------------------------------------------------------------------
type PoolConfig struct {
InboxBufferSize int
EventsBufferSize int
WorkerConfig WorkerConfig
}
type PoolOption func(*PoolConfig)
func NewPoolConfig(opts ...PoolOption) (*PoolConfig, error) {
workerCfg, _ := NewWorkerConfig()
cfg := &PoolConfig{
InboxBufferSize: 256,
EventsBufferSize: 10,
WorkerConfig: *workerCfg,
}
for _, o := range opts {
o(cfg)
}
if err := ValidatePoolConfig(cfg); err != nil {
return nil, err
}
return cfg, nil
}
func WithInboxBufferSize(value int) PoolOption {
return func(c *PoolConfig) {
c.InboxBufferSize = value
}
}
func WithEventsBufferSize(value int) PoolOption {
return func(c *PoolConfig) {
c.EventsBufferSize = value
}
}
func WithWorkerConfig(wc WorkerConfig) PoolOption {
return func(c *PoolConfig) {
c.WorkerConfig = wc
}
}
func ValidatePoolConfig(c *PoolConfig) error {
if c.InboxBufferSize < 1 {
return fmt.Errorf("invalid inbox buffer size: %d", c.InboxBufferSize)
}
if c.EventsBufferSize < 1 {
return fmt.Errorf("invalid events buffer size: %d", c.EventsBufferSize)
}
if err := ValidateWorkerConfig(&c.WorkerConfig); err != nil {
return err
}
return nil
}
// ----------------------------------------------------------------------------
@@ -93,18 +163,7 @@ type Pool struct {
func NewPool(ctx context.Context, config *PoolConfig, handler slog.Handler,
) (*Pool, error) {
if config == nil {
config = GetDefaultPoolConfig()
}
// If a custom factory is supplied, config.WorkerConfig is not used.
// The factory function should be non-blocking or else Connect() may cause
// deadlocks.
if config.WorkerFactory == nil {
config.WorkerFactory = func(
ctx context.Context, id string, handler slog.Handler) (Worker, error) {
wc := config.WorkerConfig
return NewWorker(ctx, id, &wc, handler)
}
config, _ = NewPoolConfig()
}
if err := ValidatePoolConfig(config); err != nil {
@@ -120,11 +179,11 @@ func NewPool(ctx context.Context, config *PoolConfig, handler slog.Handler,
}
var dialer types.Dialer
if config.ConnectionConfig.Dialer != nil {
dialer = config.ConnectionConfig.Dialer
} else {
dialer = transport.NewDialer()
}
// if config.ConnectionConfig.Dialer != nil {
// dialer = config.ConnectionConfig.Dialer
// } else {
// dialer = transport.NewDialer()
// }
return &Pool{
peers: make(map[string]*Peer),
@@ -262,15 +321,15 @@ func (p *Pool) Connect(id string, opts ...ConnectOption) error {
defer p.mu.Unlock()
if p.closed {
return NewPoolError(ErrPoolClosed)
return ErrPoolClosed
}
if _, exists := p.peers[id]; exists {
return NewPoolError(ErrPeerExists)
return ErrPeerExists
}
// The worker factory must be non-blocking to avoid deadlocks
worker, err := p.config.WorkerFactory(p.ctx, id, p.handler)
wc := p.config.WorkerConfig
worker, err := NewWorker(p.ctx, id, nil, &wc, p.handler)
if err != nil {
return err
}
@@ -279,19 +338,18 @@ func (p *Pool) Connect(id string, opts ...ConnectOption) error {
for _, opt := range opts {
opt(o)
}
effectiveDialer := p.dialer
if o.dialer != nil {
effectiveDialer = o.dialer
}
// effectiveDialer := p.dialer
// if o.dialer != nil {
// effectiveDialer = o.dialer
// }
cc := p.config.ConnectionConfig.Clone()
cc.Dialer = effectiveDialer
// cc := p.config.ConnectionConfig.Clone()
// cc.Dialer = effectiveDialer
pool := PoolPlugin{
Inbox: p.inbox,
Events: p.events,
InboxCounter: p.inboxCounter,
ConnectionConfig: cc,
Inbox: p.inbox,
Events: p.events,
InboxCounter: p.inboxCounter,
}
p.wg.Go(func() {
@@ -321,12 +379,12 @@ func (p *Pool) Remove(id string) error {
defer p.mu.Unlock()
if p.closed {
return NewPoolError(ErrPoolClosed)
return ErrPoolClosed
}
peer, exists := p.peers[id]
if !exists {
return NewPoolError(ErrPeerNotFound)
return ErrPeerNotFound
}
delete(p.peers, id)
@@ -349,12 +407,12 @@ func (p *Pool) Send(id string, data []byte) error {
defer p.mu.RUnlock()
if p.closed {
return NewPoolError(ErrPoolClosed)
return ErrPoolClosed
}
peer, exists := p.peers[id]
if !exists {
return NewPoolError(ErrPeerNotFound)
return ErrPeerNotFound
}
err = peer.worker.Send(data)