go-proxy/events.go
Virgil e41ad7ef2e feat(proxy): dispatch submits and drain shutdown
Co-Authored-By: Virgil <virgil@lethean.io>
2026-04-04 11:18:35 +00:00

82 lines
2.6 KiB
Go

package proxy
import "sync"
// EventBus dispatches proxy lifecycle events to registered listeners.
// Dispatch is synchronous on the calling goroutine. Listeners must not block.
//
// bus := proxy.NewEventBus()
// bus.Subscribe(proxy.EventLogin, customDiff.OnLogin)
// bus.Subscribe(proxy.EventAccept, stats.OnAccept)
type EventBus struct {
listeners map[EventType][]EventHandler
mu sync.RWMutex
}
// EventType identifies the proxy lifecycle event.
type EventType int
const (
EventLogin EventType = iota // miner completed login
EventSubmit // miner submitted a share
EventAccept // pool accepted a submitted share
EventReject // pool rejected a share (or share expired)
EventClose // miner TCP connection closed
)
// EventHandler is the callback signature for all event types.
type EventHandler func(Event)
// Event carries the data for any proxy lifecycle event.
// Fields not relevant to the event type are zero/nil.
//
// bus.Dispatch(proxy.Event{Type: proxy.EventLogin, Miner: m})
type Event struct {
Type EventType
Miner *Miner // always set
Job *Job // set for Accept and Reject events
JobID string // set for Submit events
Nonce string // set for Submit events
Result string // set for Submit events
Algo string // set for Submit events
RequestID int64 // set for Submit events
Diff uint64 // effective difficulty of the share (Accept and Reject)
Error string // rejection reason (Reject only)
Latency uint16 // pool response time in ms (Accept and Reject)
Expired bool // true if the share was accepted but against the previous job
}
// NewEventBus builds an empty synchronous event dispatcher.
//
// bus := proxy.NewEventBus()
func NewEventBus() *EventBus {
return &EventBus{
listeners: make(map[EventType][]EventHandler),
}
}
// Subscribe registers a handler for the given event type. Safe to call before Start.
//
// bus.Subscribe(proxy.EventAccept, func(e proxy.Event) { stats.OnAccept(e) })
func (b *EventBus) Subscribe(eventType EventType, handler EventHandler) {
if handler == nil {
return
}
b.mu.Lock()
defer b.mu.Unlock()
b.listeners[eventType] = append(b.listeners[eventType], handler)
}
// Dispatch calls all registered handlers for the event's type in subscription order.
//
// bus.Dispatch(proxy.Event{Type: proxy.EventLogin, Miner: m})
func (b *EventBus) Dispatch(event Event) {
b.mu.RLock()
handlers := append([]EventHandler(nil), b.listeners[event.Type]...)
b.mu.RUnlock()
for _, handler := range handlers {
handler(event)
}
}