feat: initial commit
This commit is contained in:
96
reach/client/client.go
Normal file
96
reach/client/client.go
Normal file
@ -0,0 +1,96 @@
|
||||
package client
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
|
||||
"forge.cadoles.com/cadoles/go-emlid/reach/client/protocol"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
type Client struct {
|
||||
addr string
|
||||
opts *Options
|
||||
|
||||
proto protocol.Identifier
|
||||
ops protocol.Operations
|
||||
|
||||
getProtocolOnce sync.Once
|
||||
getProtocolOnceErr error
|
||||
}
|
||||
|
||||
func (c *Client) Protocol(ctx context.Context) (protocol.Identifier, protocol.Operations, error) {
|
||||
id, ops, err := c.getProtocol(ctx)
|
||||
if err != nil {
|
||||
return "", nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
return id, ops, nil
|
||||
}
|
||||
|
||||
func (c *Client) getProtocol(ctx context.Context) (protocol.Identifier, protocol.Operations, error) {
|
||||
c.getProtocolOnce.Do(func() {
|
||||
availables, err := c.opts.Protocols.Availables(ctx, c.addr)
|
||||
if err != nil {
|
||||
c.getProtocolOnceErr = errors.WithStack(err)
|
||||
return
|
||||
}
|
||||
|
||||
var preferred protocol.Protocol
|
||||
var fallback protocol.Protocol
|
||||
|
||||
for _, proto := range availables {
|
||||
if proto.Identifier() == c.opts.FallbackProtocol {
|
||||
fallback = proto
|
||||
}
|
||||
|
||||
if proto.Identifier() == c.opts.PreferredProtocol {
|
||||
preferred = proto
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if preferred != nil {
|
||||
c.proto = preferred.Identifier()
|
||||
c.ops = preferred.Operations(c.addr)
|
||||
return
|
||||
}
|
||||
|
||||
if fallback != nil {
|
||||
c.proto = fallback.Identifier()
|
||||
c.ops = fallback.Operations(c.addr)
|
||||
return
|
||||
}
|
||||
|
||||
for _, proto := range availables {
|
||||
if proto.Identifier() != c.opts.FallbackProtocol {
|
||||
continue
|
||||
}
|
||||
|
||||
fallback = proto
|
||||
break
|
||||
}
|
||||
|
||||
if fallback == nil {
|
||||
c.getProtocolOnceErr = errors.Errorf("neither preferred protocol '%v' or fallback '%v' are available", c.opts.PreferredProtocol, c.opts.FallbackProtocol)
|
||||
return
|
||||
}
|
||||
|
||||
c.proto = fallback.Identifier()
|
||||
c.ops = fallback.Operations(c.addr)
|
||||
})
|
||||
if c.getProtocolOnceErr != nil {
|
||||
return "", nil, errors.WithStack(c.getProtocolOnceErr)
|
||||
}
|
||||
|
||||
return c.proto, c.ops, nil
|
||||
}
|
||||
|
||||
func NewClient(addr string, funcs ...OptionFunc) *Client {
|
||||
opts := NewOptions(funcs...)
|
||||
client := &Client{
|
||||
addr: addr,
|
||||
opts: opts,
|
||||
}
|
||||
return client
|
||||
}
|
Reference in New Issue
Block a user