go-emlid/reach/client/protocol/registry.go

83 lines
1.7 KiB
Go

package protocol
import (
"context"
"time"
"github.com/pkg/errors"
)
type Registry struct {
protocols map[Identifier]ProtocolFactory
}
func (r *Registry) Register(identifier Identifier, factory ProtocolFactory) {
r.protocols[identifier] = factory
}
func (r *Registry) Get(identifier Identifier, funcs ...ProtocolOptionFunc) (Protocol, error) {
factory, exists := r.protocols[identifier]
if !exists {
return nil, errors.WithStack(ErrNotFound)
}
protocolOpts := NewProtocolOptions(funcs...)
proto, err := factory(protocolOpts)
if err != nil {
return nil, errors.WithStack(err)
}
return proto, nil
}
func (r *Registry) Availables(ctx context.Context, addr string, timeout time.Duration, funcs ...ProtocolOptionFunc) ([]Protocol, error) {
availables := make([]Protocol, 0)
protocolOpts := NewProtocolOptions(funcs...)
for _, factory := range r.protocols {
proto, err := factory(protocolOpts)
if err != nil {
return nil, errors.WithStack(err)
}
timeoutCtx, cancel := context.WithTimeout(ctx, timeout)
available, err := proto.Available(timeoutCtx, addr)
if err != nil {
cancel()
return nil, errors.WithStack(err)
}
cancel()
if !available {
continue
}
availables = append(availables, proto)
}
return availables, nil
}
func NewRegistry() *Registry {
return &Registry{
protocols: make(map[Identifier]ProtocolFactory),
}
}
var defaultRegistry = NewRegistry()
func DefaultRegistry() *Registry {
return defaultRegistry
}
func Register(identifier Identifier, factory ProtocolFactory) {
defaultRegistry.Register(identifier, factory)
}
func Availables(ctx context.Context, addr string, timeout time.Duration) ([]Protocol, error) {
return defaultRegistry.Availables(ctx, addr, timeout)
}