87
cluster/cluster.go
Normal file
87
cluster/cluster.go
Normal file
@@ -0,0 +1,87 @@
|
||||
package cluster
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var clusterTypes map[string]Cluster
|
||||
|
||||
func init() {
|
||||
clusterTypes = make(map[string]Cluster)
|
||||
RegisterCluster("none", &clusterNone{})
|
||||
}
|
||||
func RegisterCluster(engine string, cluster Cluster) {
|
||||
clusterTypes[engine] = cluster
|
||||
}
|
||||
|
||||
// Info struct contains cluster info
|
||||
type Info struct {
|
||||
BlockSize uint32
|
||||
Mode string
|
||||
}
|
||||
|
||||
// Member struct contains info about cluster member
|
||||
type Member struct {
|
||||
UUID []byte
|
||||
Name string
|
||||
Network string
|
||||
Host string
|
||||
Port string
|
||||
}
|
||||
|
||||
// Cluster represents cluster interface
|
||||
type Cluster interface {
|
||||
Start() error
|
||||
Stop() error
|
||||
Configure(interface{}) error
|
||||
// Format() error
|
||||
// Check() error
|
||||
// Recover() error
|
||||
// Info() (*Info, error)
|
||||
// Snapshot() error
|
||||
// Reweight() error
|
||||
// Members() []Member
|
||||
}
|
||||
|
||||
func New(ctype string, cfg interface{}) (Cluster, error) {
|
||||
var err error
|
||||
|
||||
cluster, ok := clusterTypes[ctype]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unknown cluster type %s. only %s supported", ctype, strings.Join(ClusterTypes(), ","))
|
||||
}
|
||||
|
||||
if cfg == nil {
|
||||
return cluster, nil
|
||||
}
|
||||
|
||||
err = cluster.Configure(cfg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return cluster, nil
|
||||
}
|
||||
|
||||
func ClusterTypes() []string {
|
||||
var ctypes []string
|
||||
for ctype, _ := range clusterTypes {
|
||||
ctypes = append(ctypes, ctype)
|
||||
}
|
||||
return ctypes
|
||||
}
|
||||
|
||||
type clusterNone struct{}
|
||||
|
||||
func (c *clusterNone) Configure(data interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *clusterNone) Start() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *clusterNone) Stop() error {
|
||||
return nil
|
||||
}
|
65
cluster/etcdint/etcdint.go
Normal file
65
cluster/etcdint/etcdint.go
Normal file
@@ -0,0 +1,65 @@
|
||||
package etcdint
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
"github.com/sdstack/storage/cluster"
|
||||
|
||||
"github.com/coreos/etcd/embed"
|
||||
"github.com/coreos/etcd/wal"
|
||||
"github.com/mitchellh/mapstructure"
|
||||
)
|
||||
|
||||
type config struct {
|
||||
WalSize int64 `mapstructure:"wal_size"`
|
||||
Store string `mapstructure:"store"`
|
||||
}
|
||||
|
||||
// Internal strect holds data used by internal cluster engine
|
||||
type ClusterEtcdint struct {
|
||||
etcdsrv *embed.Etcd
|
||||
etcdcfg *embed.Config
|
||||
cfg *config
|
||||
}
|
||||
|
||||
func init() {
|
||||
cluster.RegisterCluster("etcdint", &ClusterEtcdint{})
|
||||
}
|
||||
|
||||
func (c *ClusterEtcdint) Configure(data interface{}) error {
|
||||
var err error
|
||||
|
||||
c.etcdcfg = embed.NewConfig()
|
||||
err = mapstructure.Decode(data, &c.cfg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c.etcdcfg.Dir = c.cfg.Store
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Start internal cluster engine
|
||||
func (c *ClusterEtcdint) Start() error {
|
||||
wal.SegmentSizeBytes = c.cfg.WalSize
|
||||
e, err := embed.StartEtcd(c.etcdcfg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
select {
|
||||
case <-e.Server.ReadyNotify():
|
||||
c.etcdsrv = e
|
||||
break
|
||||
case <-time.After(60 * time.Second):
|
||||
e.Server.Stop() // trigger a shutdown
|
||||
return errors.New("Server took too long to start!")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Stop internal cluster engin
|
||||
func (c *ClusterEtcdint) Stop() error {
|
||||
c.etcdsrv.Server.Stop()
|
||||
return nil
|
||||
}
|
Reference in New Issue
Block a user