Add proxying memfs files

This commit is contained in:
Ingo Oppermann
2022-08-04 16:43:19 +02:00
parent fe889aa4e2
commit c31fd657be
7 changed files with 177 additions and 22 deletions

View File

@@ -3,7 +3,9 @@ package cluster
import (
"context"
"fmt"
"path/filepath"
"sync"
"time"
"github.com/datarhei/core/v16/log"
)
@@ -14,6 +16,7 @@ type Cluster interface {
ListNodes() []NodeReader
GetNode(id string) (NodeReader, error)
Stop()
GetFile(path string) (string, error)
}
type ClusterConfig struct {
@@ -21,9 +24,10 @@ type ClusterConfig struct {
}
type cluster struct {
nodes map[string]*node
idfiles map[string][]string
fileid map[string]string
nodes map[string]*node
idfiles map[string][]string
idupdate map[string]time.Time
fileid map[string]string
updates chan NodeState
@@ -36,11 +40,12 @@ type cluster struct {
func New(config ClusterConfig) (Cluster, error) {
c := &cluster{
nodes: map[string]*node{},
idfiles: map[string][]string{},
fileid: map[string]string{},
updates: make(chan NodeState, 64),
logger: config.Logger,
nodes: map[string]*node{},
idfiles: map[string][]string{},
idupdate: map[string]time.Time{},
fileid: map[string]string{},
updates: make(chan NodeState, 64),
logger: config.Logger,
}
if c.logger == nil {
@@ -56,7 +61,11 @@ func New(config ClusterConfig) (Cluster, error) {
case <-ctx.Done():
return
case state := <-c.updates:
c.logger.Info().WithField("node", state.ID).WithField("state", state.State).Log("got news from node")
c.logger.Debug().WithFields(log.Fields{
"node": state.ID,
"state": state.State,
"files": len(state.Files),
}).Log("got update")
c.lock.Lock()
@@ -66,6 +75,7 @@ func New(config ClusterConfig) (Cluster, error) {
delete(c.fileid, file)
}
delete(c.idfiles, state.ID)
delete(c.idupdate, state.ID)
if state.State == "connected" {
// Add files
@@ -73,6 +83,7 @@ func New(config ClusterConfig) (Cluster, error) {
c.fileid[file] = state.ID
}
c.idfiles[state.ID] = files
c.idupdate[state.ID] = state.LastUpdate
}
c.lock.Unlock()
@@ -153,8 +164,44 @@ func (c *cluster) GetNode(id string) (NodeReader, error) {
node, ok := c.nodes[id]
if !ok {
return nil, fmt.Errorf("no such node")
return nil, fmt.Errorf("node not found")
}
return node, nil
}
func (c *cluster) GetFile(path string) (string, error) {
c.lock.RLock()
defer c.lock.RUnlock()
c.logger.Debug().WithField("path", path).Log("opening")
id, ok := c.fileid[path]
if !ok {
c.logger.Debug().WithField("path", path).Log("not found")
return "", fmt.Errorf("file not found")
}
ts, ok := c.idupdate[id]
if !ok {
c.logger.Debug().WithField("path", path).Log("no age information found")
return "", fmt.Errorf("file not found")
}
if time.Since(ts) > 2*time.Second {
c.logger.Debug().WithField("path", path).Log("file too old")
return "", fmt.Errorf("file not found")
}
node, ok := c.nodes[id]
if !ok {
c.logger.Debug().WithField("path", path).Log("unknown node")
return "", fmt.Errorf("file not found")
}
url := node.Address() + "/" + filepath.Join("memfs", path)
c.logger.Debug().WithField("url", url).Log("file cluster url")
return url, nil
}