mirror of
https://github.com/datarhei/core.git
synced 2025-10-06 00:17:07 +08:00
131 lines
2.2 KiB
Go
131 lines
2.2 KiB
Go
package forwarder
|
|
|
|
import (
|
|
"io"
|
|
"net/http"
|
|
"sync"
|
|
"time"
|
|
|
|
apiclient "github.com/datarhei/core/v16/cluster/client"
|
|
"github.com/datarhei/core/v16/log"
|
|
)
|
|
|
|
// Forwarder forwards any HTTP request from a follower to the leader
|
|
type Forwarder struct {
|
|
ID string
|
|
Logger log.Logger
|
|
|
|
lock sync.RWMutex
|
|
client apiclient.APIClient
|
|
}
|
|
|
|
type Config struct {
|
|
ID string
|
|
Logger log.Logger
|
|
}
|
|
|
|
func New(config Config) (*Forwarder, error) {
|
|
f := &Forwarder{
|
|
ID: config.ID,
|
|
Logger: config.Logger,
|
|
}
|
|
|
|
if f.Logger == nil {
|
|
f.Logger = log.New("")
|
|
}
|
|
|
|
tr := http.DefaultTransport.(*http.Transport).Clone()
|
|
tr.MaxIdleConns = 10
|
|
tr.IdleConnTimeout = 30 * time.Second
|
|
|
|
client := &http.Client{
|
|
Transport: tr,
|
|
Timeout: 5 * time.Second,
|
|
}
|
|
|
|
f.client = apiclient.APIClient{
|
|
Client: client,
|
|
}
|
|
|
|
return f, nil
|
|
}
|
|
|
|
func (f *Forwarder) SetLeader(address string) {
|
|
f.lock.Lock()
|
|
defer f.lock.Unlock()
|
|
|
|
if f.client.Address == address {
|
|
return
|
|
}
|
|
|
|
f.Logger.Debug().Log("Setting leader address to %s", address)
|
|
|
|
f.client.Address = address
|
|
}
|
|
|
|
func (f *Forwarder) HasLeader() bool {
|
|
return len(f.client.Address) != 0
|
|
}
|
|
|
|
func (f *Forwarder) Join(origin, id, raftAddress, peerAddress string) error {
|
|
if origin == "" {
|
|
origin = f.ID
|
|
}
|
|
|
|
r := apiclient.JoinRequest{
|
|
ID: id,
|
|
RaftAddress: raftAddress,
|
|
}
|
|
|
|
f.Logger.Debug().WithField("request", r).Log("Forwarding to leader")
|
|
|
|
f.lock.RLock()
|
|
client := f.client
|
|
f.lock.RUnlock()
|
|
|
|
if len(peerAddress) != 0 {
|
|
client = apiclient.APIClient{
|
|
Address: peerAddress,
|
|
Client: f.client.Client,
|
|
}
|
|
}
|
|
|
|
return client.Join(origin, r)
|
|
}
|
|
|
|
func (f *Forwarder) Leave(origin, id string) error {
|
|
if origin == "" {
|
|
origin = f.ID
|
|
}
|
|
|
|
f.Logger.Debug().WithField("id", id).Log("Forwarding to leader")
|
|
|
|
f.lock.RLock()
|
|
client := f.client
|
|
f.lock.RUnlock()
|
|
|
|
return client.Leave(origin, id)
|
|
}
|
|
|
|
func (f *Forwarder) TransferLeadership(origin, id string) error {
|
|
if origin == "" {
|
|
origin = f.ID
|
|
}
|
|
|
|
f.Logger.Debug().WithField("id", id).Log("Transferring leadership")
|
|
|
|
f.lock.RLock()
|
|
client := f.client
|
|
f.lock.RUnlock()
|
|
|
|
return client.TransferLeadership(origin, id)
|
|
}
|
|
|
|
func (f *Forwarder) Snapshot(origin string) (io.ReadCloser, error) {
|
|
f.lock.RLock()
|
|
client := f.client
|
|
f.lock.RUnlock()
|
|
|
|
return client.Snapshot(origin)
|
|
}
|