Files
go-cart-actor/remote-host.go
matst80 6abd818ed6
All checks were successful
Build and Publish / BuildAndDeployAmd64 (push) Successful in 28s
Build and Publish / BuildAndDeploy (push) Successful in 2m20s
better logs
2024-11-12 21:33:01 +01:00

95 lines
2.1 KiB
Go

package main
import (
"fmt"
"log"
"strings"
)
type RemoteHost struct {
*Client
Host string
MissedPings int
}
func (h *RemoteHost) IsHealthy() bool {
return !h.Dead && h.MissedPings < 3
}
func (h *RemoteHost) Initialize(p *SyncedPool) {
ids, err := h.GetCartMappings()
if err != nil {
log.Printf("Error getting remote mappings: %v\n", err)
return
}
log.Printf("Remote %s has %d grains\n", h.Host, len(ids))
p.mu.Lock()
local := 0
remoteNo := 0
for _, id := range ids {
go p.SpawnRemoteGrain(id, h.Host)
remoteNo++
}
log.Printf("Removed %d local grains, added %d remote grains\n", local, remoteNo)
p.mu.Unlock()
go p.Negotiate()
}
func (h *RemoteHost) Ping() error {
_, err := h.Call(Ping, Pong, []byte{})
if err != nil {
h.MissedPings++
log.Printf("Error pinging remote %s, missed pings: %d", h.Host, h.MissedPings)
} else {
h.MissedPings = 0
}
return err
}
func (h *RemoteHost) Negotiate(knownHosts []string) ([]string, error) {
reply, err := h.Call(RemoteNegotiate, RemoteNegotiateResponse, []byte(strings.Join(knownHosts, ";")))
if err != nil {
return nil, err
}
if reply.StatusCode != 200 {
return nil, fmt.Errorf("remote returned error on negotiate: %s", string(reply.Data))
}
return strings.Split(string(reply.Data), ";"), nil
}
func (g *RemoteHost) GetCartMappings() ([]CartId, error) {
reply, err := g.Call(GetCartIds, CartIdsResponse, []byte{})
if err != nil {
return nil, err
}
if reply.StatusCode != 200 {
log.Printf("Remote returned error on get cart mappings: %s", string(reply.Data))
return nil, fmt.Errorf("remote returned error: %s", string(reply.Data))
}
parts := strings.Split(string(reply.Data), ";")
ids := make([]CartId, 0, len(parts))
for _, p := range parts {
ids = append(ids, ToCartId(p))
}
return ids, nil
}
func (r *RemoteHost) ConfirmChange(id CartId, host string) error {
reply, err := r.Call(RemoteGrainChanged, AckChange, []byte(fmt.Sprintf("%s;%s", id, host)))
if err != nil {
return err
}
if string(reply.Data) != "ok" {
return fmt.Errorf("remote grain change failed %s", string(reply.Data))
}
return nil
}