refactor everything again
All checks were successful
Build and Publish / BuildAndDeploy (push) Successful in 1m51s
All checks were successful
Build and Publish / BuildAndDeploy (push) Successful in 1m51s
This commit is contained in:
52
main.go
52
main.go
@@ -10,7 +10,6 @@ import (
|
|||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
messages "git.tornberg.me/go-cart-actor/proto"
|
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
"github.com/prometheus/client_golang/prometheus/promauto"
|
"github.com/prometheus/client_golang/prometheus/promauto"
|
||||||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||||
@@ -85,57 +84,6 @@ func (a *App) HandleSave(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type PoolServer struct {
|
|
||||||
pod_name string
|
|
||||||
pool GrainPool
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewPoolServer(pool GrainPool, pod_name string) *PoolServer {
|
|
||||||
return &PoolServer{
|
|
||||||
pod_name: pod_name,
|
|
||||||
pool: pool,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *PoolServer) HandleGet(w http.ResponseWriter, r *http.Request) {
|
|
||||||
id := r.PathValue("id")
|
|
||||||
data, err := s.pool.Get(ToCartId(id))
|
|
||||||
if err != nil {
|
|
||||||
w.WriteHeader(http.StatusNotFound)
|
|
||||||
w.Write([]byte(err.Error()))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
w.Header().Set("Content-Type", "application/json")
|
|
||||||
w.Header().Set("X-Pod-Name", s.pod_name)
|
|
||||||
w.WriteHeader(http.StatusOK)
|
|
||||||
w.Write(data)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *PoolServer) HandleAddSku(w http.ResponseWriter, r *http.Request) {
|
|
||||||
id := r.PathValue("id")
|
|
||||||
sku := r.PathValue("sku")
|
|
||||||
data, err := s.pool.Process(ToCartId(id), Message{
|
|
||||||
Type: AddRequestType,
|
|
||||||
Content: &messages.AddRequest{Sku: sku},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
|
||||||
w.Write([]byte(err.Error()))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
w.Header().Set("Content-Type", "application/json")
|
|
||||||
w.Header().Set("X-Pod-Name", s.pod_name)
|
|
||||||
w.WriteHeader(http.StatusOK)
|
|
||||||
w.Write(data)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *PoolServer) Serve() *http.ServeMux {
|
|
||||||
mux := http.NewServeMux()
|
|
||||||
mux.HandleFunc("GET /{id}", s.HandleGet)
|
|
||||||
mux.HandleFunc("GET /{id}/add/{sku}", s.HandleAddSku)
|
|
||||||
return mux
|
|
||||||
}
|
|
||||||
|
|
||||||
var podIp = os.Getenv("POD_IP")
|
var podIp = os.Getenv("POD_IP")
|
||||||
var name = os.Getenv("POD_NAME")
|
var name = os.Getenv("POD_NAME")
|
||||||
|
|
||||||
|
|||||||
58
pool-server.go
Normal file
58
pool-server.go
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
messages "git.tornberg.me/go-cart-actor/proto"
|
||||||
|
)
|
||||||
|
|
||||||
|
type PoolServer struct {
|
||||||
|
pod_name string
|
||||||
|
pool GrainPool
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewPoolServer(pool GrainPool, pod_name string) *PoolServer {
|
||||||
|
return &PoolServer{
|
||||||
|
pod_name: pod_name,
|
||||||
|
pool: pool,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *PoolServer) HandleGet(w http.ResponseWriter, r *http.Request) {
|
||||||
|
id := r.PathValue("id")
|
||||||
|
data, err := s.pool.Get(ToCartId(id))
|
||||||
|
if err != nil {
|
||||||
|
w.WriteHeader(http.StatusNotFound)
|
||||||
|
w.Write([]byte(err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
w.Header().Set("X-Pod-Name", s.pod_name)
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
w.Write(data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *PoolServer) HandleAddSku(w http.ResponseWriter, r *http.Request) {
|
||||||
|
id := r.PathValue("id")
|
||||||
|
sku := r.PathValue("sku")
|
||||||
|
data, err := s.pool.Process(ToCartId(id), Message{
|
||||||
|
Type: AddRequestType,
|
||||||
|
Content: &messages.AddRequest{Sku: sku},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
|
w.Write([]byte(err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
w.Header().Set("X-Pod-Name", s.pod_name)
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
w.Write(data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *PoolServer) Serve() *http.ServeMux {
|
||||||
|
mux := http.NewServeMux()
|
||||||
|
mux.HandleFunc("GET /{id}", s.HandleGet)
|
||||||
|
mux.HandleFunc("GET /{id}/add/{sku}", s.HandleAddSku)
|
||||||
|
return mux
|
||||||
|
}
|
||||||
@@ -17,7 +17,7 @@ type PriceTuple struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type OutletItem struct {
|
type OutletItem struct {
|
||||||
ArticleNumber string `json:"sku,opmitempty"`
|
ArticleNumber string `json:"sku,omitempty"`
|
||||||
Price PriceTuple `json:"price,omitempty"`
|
Price PriceTuple `json:"price,omitempty"`
|
||||||
Title string `json:"title"`
|
Title string `json:"title"`
|
||||||
}
|
}
|
||||||
|
|||||||
10
rpc-pool.go
10
rpc-pool.go
@@ -25,18 +25,18 @@ func ToCartId(id string) CartId {
|
|||||||
type RemoteGrain struct {
|
type RemoteGrain struct {
|
||||||
*CartClient
|
*CartClient
|
||||||
Id CartId
|
Id CartId
|
||||||
Address string
|
Host string
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewRemoteGrain(id CartId, address string) (*RemoteGrain, error) {
|
func NewRemoteGrain(id CartId, host string) (*RemoteGrain, error) {
|
||||||
client, err := CartDial(fmt.Sprintf("%s:1337", address))
|
client, err := CartDial(fmt.Sprintf("%s:1337", host))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return &RemoteGrain{
|
return &RemoteGrain{
|
||||||
Id: id,
|
Id: id,
|
||||||
Address: address,
|
Host: host,
|
||||||
CartClient: client,
|
CartClient: client,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
@@ -75,7 +75,7 @@ func (p *RemoteGrainPool) findRemoteGrain(id CartId) *RemoteGrain {
|
|||||||
p.mu.RLock()
|
p.mu.RLock()
|
||||||
grain, ok := p.grains[id]
|
grain, ok := p.grains[id]
|
||||||
p.mu.RUnlock()
|
p.mu.RUnlock()
|
||||||
if !ok || grain == nil {
|
if !ok {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return grain
|
return grain
|
||||||
|
|||||||
@@ -48,55 +48,9 @@ func (h *GrainHandler) RemoteHandleMessageHandler(id CartId, data []byte) (uint1
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (h *GrainHandler) RemoteGetStateHandler(id CartId, data []byte) (uint16, []byte, error) {
|
func (h *GrainHandler) RemoteGetStateHandler(id CartId, data []byte) (uint16, []byte, error) {
|
||||||
data, err := h.pool.Get(id)
|
reply, err := h.pool.Get(id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return RemoteGetStateReply, nil, err
|
return RemoteGetStateReply, nil, err
|
||||||
}
|
}
|
||||||
return RemoteGetStateReply, data, nil
|
return RemoteGetStateReply, reply, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// func (h *GrainHandler) handleClient(conn net.Conn) {
|
|
||||||
// var err error
|
|
||||||
|
|
||||||
// defer conn.Close()
|
|
||||||
|
|
||||||
// var packet CartPacket
|
|
||||||
|
|
||||||
// for {
|
|
||||||
// err = binary.Read(conn, binary.LittleEndian, &packet)
|
|
||||||
// if err != nil {
|
|
||||||
// if err == io.EOF {
|
|
||||||
// break
|
|
||||||
// }
|
|
||||||
// fmt.Println("Error in connection:", err)
|
|
||||||
// }
|
|
||||||
// if packet.Version != 2 {
|
|
||||||
// fmt.Printf("Unknown version %d", packet.Version)
|
|
||||||
// break
|
|
||||||
// }
|
|
||||||
|
|
||||||
// switch packet.MessageType {
|
|
||||||
// case RemoteHandleMessage:
|
|
||||||
// var msg Message
|
|
||||||
// err = ReadMessage(conn, &msg)
|
|
||||||
// if err != nil {
|
|
||||||
// fmt.Println("Error reading message:", err)
|
|
||||||
// }
|
|
||||||
|
|
||||||
// data, err := h.pool.Process(packet.Id, msg)
|
|
||||||
// if err != nil {
|
|
||||||
// fmt.Println("Error handling message:", err)
|
|
||||||
// }
|
|
||||||
// SendRawResponse(conn, data)
|
|
||||||
|
|
||||||
// case RemoteGetState:
|
|
||||||
// data, err := h.pool.Get(packet.Id)
|
|
||||||
// if err != nil {
|
|
||||||
// fmt.Println("Error getting grain:", err)
|
|
||||||
// }
|
|
||||||
// SendRawResponse(conn, data)
|
|
||||||
// }
|
|
||||||
|
|
||||||
// }
|
|
||||||
|
|
||||||
// }
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"strings"
|
"strings"
|
||||||
@@ -26,11 +27,10 @@ type RemoteHost struct {
|
|||||||
type SyncedPool struct {
|
type SyncedPool struct {
|
||||||
*Server
|
*Server
|
||||||
mu sync.RWMutex
|
mu sync.RWMutex
|
||||||
//Discovery Discovery
|
|
||||||
Hostname string
|
Hostname string
|
||||||
local *GrainLocalPool
|
local *GrainLocalPool
|
||||||
remotes []*RemoteHost
|
remotes []*RemoteHost
|
||||||
remoteIndex map[CartId]*RemoteGrainPool
|
remoteIndex map[CartId]*RemoteGrain
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -97,16 +97,23 @@ func (p *SyncedPool) GrainOwnerChangeHandler(data []byte) (uint16, []byte, error
|
|||||||
log.Printf("Invalid remote grain change message\n")
|
log.Printf("Invalid remote grain change message\n")
|
||||||
return AckChange, []byte("incorrect"), nil
|
return AckChange, []byte("incorrect"), nil
|
||||||
}
|
}
|
||||||
|
id := ToCartId(idAndHostParts[0])
|
||||||
|
host := idAndHostParts[1]
|
||||||
|
|
||||||
for _, r := range p.remotes {
|
for _, r := range p.remotes {
|
||||||
if r.Host == string(idAndHostParts[1]) {
|
if r.Host == host {
|
||||||
log.Printf("Remote grain %s changed to %s\n", idAndHostParts[0], idAndHostParts[1])
|
log.Printf("Remote grain %s changed to %s\n", id, host)
|
||||||
p.mu.Lock()
|
p.mu.Lock()
|
||||||
if p.local.grains[ToCartId(idAndHostParts[0])] != nil {
|
if p.local.grains[id] != nil {
|
||||||
log.Printf("Grain %s already exists locally, deleting\n", idAndHostParts[0])
|
log.Printf("Grain %s already exists locally, deleting\n", id)
|
||||||
delete(p.local.grains, ToCartId(idAndHostParts[0]))
|
delete(p.local.grains, id)
|
||||||
}
|
}
|
||||||
p.remoteIndex[ToCartId(idAndHostParts[0])] = r.Pool
|
grain, err := NewRemoteGrain(id, r.Host)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Error creating remote grain %s: %v\n", id, err)
|
||||||
|
return AckChange, []byte("error"), nil
|
||||||
|
}
|
||||||
|
p.remoteIndex[id] = grain
|
||||||
p.mu.Unlock()
|
p.mu.Unlock()
|
||||||
return AckChange, []byte("ok"), nil
|
return AckChange, []byte("ok"), nil
|
||||||
}
|
}
|
||||||
@@ -131,7 +138,7 @@ func NewSyncedPool(local *GrainLocalPool, hostname string, discovery Discovery)
|
|||||||
local: local,
|
local: local,
|
||||||
|
|
||||||
remotes: make([]*RemoteHost, 0),
|
remotes: make([]*RemoteHost, 0),
|
||||||
remoteIndex: make(map[CartId]*RemoteGrainPool),
|
remoteIndex: make(map[CartId]*RemoteGrain),
|
||||||
}
|
}
|
||||||
|
|
||||||
server.HandleCall(Ping, pool.PongHandler)
|
server.HandleCall(Ping, pool.PongHandler)
|
||||||
@@ -227,8 +234,7 @@ func (p *SyncedPool) RemoveHostMappedCarts(host *RemoteHost) {
|
|||||||
p.mu.Lock()
|
p.mu.Lock()
|
||||||
defer p.mu.Unlock()
|
defer p.mu.Unlock()
|
||||||
for id, r := range p.remoteIndex {
|
for id, r := range p.remoteIndex {
|
||||||
if r == host.Pool {
|
if r.Host == host.Host {
|
||||||
p.remoteIndex[id].Delete(id)
|
|
||||||
delete(p.remoteIndex, id)
|
delete(p.remoteIndex, id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -340,7 +346,12 @@ func (p *SyncedPool) addRemoteHost(address string, remote *RemoteHost) error {
|
|||||||
log.Printf("Grain %s already exists locally, deleting\n", id)
|
log.Printf("Grain %s already exists locally, deleting\n", id)
|
||||||
delete(p.local.grains, id)
|
delete(p.local.grains, id)
|
||||||
}
|
}
|
||||||
p.remoteIndex[id] = remote.Pool
|
grain, err := NewRemoteGrain(id, remote.Host)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Error creating remote grain %s: %v\n", id, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
p.remoteIndex[id] = grain
|
||||||
}
|
}
|
||||||
p.mu.Unlock()
|
p.mu.Unlock()
|
||||||
}()
|
}()
|
||||||
@@ -376,47 +387,59 @@ func (p *SyncedPool) AddRemote(address string) error {
|
|||||||
return p.addRemoteHost(address, &remote)
|
return p.addRemoteHost(address, &remote)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *SyncedPool) getGrainPool(id CartId) (GrainPool, error) {
|
func (p *SyncedPool) getGrain(id CartId) (Grain, error) {
|
||||||
_, ok := p.local.grains[id]
|
localGrain, ok := p.local.grains[id]
|
||||||
if !ok {
|
if !ok {
|
||||||
// check if remote grain exists
|
// check if remote grain exists
|
||||||
p.mu.RLock()
|
p.mu.RLock()
|
||||||
remotePool, ok := p.remoteIndex[id]
|
remoteGrain, ok := p.remoteIndex[id]
|
||||||
p.mu.RUnlock()
|
p.mu.RUnlock()
|
||||||
if ok {
|
if ok {
|
||||||
if remotePool == nil {
|
if remoteGrain == nil {
|
||||||
p.remoteIndex[id].Delete(id)
|
// p.remoteIndex[id].Delete(id)
|
||||||
p.mu.Lock()
|
p.mu.Lock()
|
||||||
delete(p.remoteIndex, id)
|
delete(p.remoteIndex, id)
|
||||||
p.mu.Unlock()
|
p.mu.Unlock()
|
||||||
return nil, fmt.Errorf("remote pool is nil for %v", id)
|
log.Printf("Remote grain %s is nil\n", id)
|
||||||
}
|
//return nil, fmt.Errorf("remote pool is nil for %v", id)
|
||||||
|
} else {
|
||||||
remoteLookupCount.Inc()
|
remoteLookupCount.Inc()
|
||||||
return remotePool, nil
|
return remoteGrain, nil
|
||||||
}
|
}
|
||||||
if !ok {
|
}
|
||||||
|
|
||||||
err := p.RequestOwnership(id)
|
err := p.RequestOwnership(id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
return p.local, nil
|
return localGrain, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *SyncedPool) Process(id CartId, messages ...Message) ([]byte, error) {
|
func (p *SyncedPool) Process(id CartId, messages ...Message) ([]byte, error) {
|
||||||
pool, err := p.getGrainPool(id)
|
pool, err := p.getGrain(id)
|
||||||
|
var res []byte
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return pool.Process(id, messages...)
|
for _, m := range messages {
|
||||||
|
res, err = pool.HandleMessage(&m, false)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *SyncedPool) Get(id CartId) ([]byte, error) {
|
func (p *SyncedPool) Get(id CartId) ([]byte, error) {
|
||||||
pool, err := p.getGrainPool(id)
|
grain, err := p.getGrain(id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return pool.Get(id)
|
if remoteGrain, ok := grain.(*RemoteGrain); ok {
|
||||||
|
return remoteGrain.GetCurrentState()
|
||||||
|
}
|
||||||
|
|
||||||
|
return json.Marshal(grain)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -89,11 +89,11 @@ func (m *TCPCartServerMux) handleFunction(connection net.Conn, messageType uint1
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *TCPCartServerMux) HandleConnection(connection net.Conn) error {
|
func (m *TCPCartServerMux) HandleConnection(connection net.Conn) error {
|
||||||
var packet *CartPacket
|
var packet CartPacket
|
||||||
var err error
|
var err error
|
||||||
defer connection.Close()
|
defer connection.Close()
|
||||||
for {
|
for {
|
||||||
err = ReadPacket(connection, packet)
|
err = ReadPacket(connection, &packet)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err == io.EOF {
|
if err == io.EOF {
|
||||||
return nil
|
return nil
|
||||||
@@ -101,10 +101,7 @@ func (m *TCPCartServerMux) HandleConnection(connection net.Conn) error {
|
|||||||
log.Printf("Error receiving packet: %v\n", err)
|
log.Printf("Error receiving packet: %v\n", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if packet == nil {
|
|
||||||
log.Println("Packet is nil")
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
data, err := GetPacketData(connection, int(packet.DataLength))
|
data, err := GetPacketData(connection, int(packet.DataLength))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Error getting packet data: %v\n", err)
|
log.Printf("Error getting packet data: %v\n", err)
|
||||||
|
|||||||
Reference in New Issue
Block a user