2
0
Эх сурвалжийг харах

feature(worker): framework of mirror provider

bigeagle 9 жил өмнө
parent
commit
44af0d5e62

+ 1 - 0
.testpackages.txt

@@ -1,2 +1,3 @@
 github.com/tuna/tunasync/internal
 github.com/tuna/tunasync/manager
+github.com/tuna/tunasync/worker

+ 84 - 4
worker/provider.go

@@ -1,13 +1,93 @@
+package worker
+
 // mirror provider is the wrapper of mirror jobs
 
-package worker
+type providerType uint8
+
+const (
+	_WorkingDirKey = "working_dir"
+	_LogDirKey     = "log_dir"
+	_LogFileKey    = "log_file"
+)
 
-// a mirrorProvider instance
+// A mirrorProvider instance
 type mirrorProvider interface {
+	// name
+	Name() string
+
+	// TODO: implement Run, Terminate and Hooks
 	// run mirror job
 	Run()
 	// terminate mirror job
 	Terminate()
-	// get context
-	Context()
+	// job hooks
+	Hooks()
+
+	Interval() int
+
+	WorkingDir() string
+	LogDir() string
+	LogFile() string
+
+	// enter context
+	EnterContext() *Context
+	// exit context
+	ExitContext() *Context
+	// return context
+	Context() *Context
+}
+
+type baseProvider struct {
+	ctx      *Context
+	name     string
+	interval int
+}
+
+func (p *baseProvider) Name() string {
+	return p.name
+}
+
+func (p *baseProvider) EnterContext() *Context {
+	p.ctx = p.ctx.Enter()
+	return p.ctx
+}
+
+func (p *baseProvider) ExitContext() *Context {
+	p.ctx, _ = p.ctx.Exit()
+	return p.ctx
+}
+
+func (p *baseProvider) Context() *Context {
+	return p.ctx
+}
+
+func (p *baseProvider) Interval() int {
+	return p.interval
+}
+
+func (p *baseProvider) WorkingDir() string {
+	if v, ok := p.ctx.Get(_WorkingDirKey); ok {
+		if s, ok := v.(string); ok {
+			return s
+		}
+	}
+	panic("working dir is impossible to be non-exist")
+}
+
+func (p *baseProvider) LogDir() string {
+	if v, ok := p.ctx.Get(_LogDirKey); ok {
+		if s, ok := v.(string); ok {
+			return s
+		}
+	}
+	panic("log dir is impossible to be unavailable")
+}
+
+func (p *baseProvider) LogFile() string {
+	if v, ok := p.ctx.Get(_LogFileKey); ok {
+		if s, ok := v.(string); ok {
+			return s
+		}
+	}
+	panic("log dir is impossible to be unavailable")
 }

+ 59 - 0
worker/provider_test.go

@@ -0,0 +1,59 @@
+package worker
+
+import (
+	"testing"
+
+	. "github.com/smartystreets/goconvey/convey"
+)
+
+func TestRsyncProvider(t *testing.T) {
+	Convey("Rsync Provider should work", t, func() {
+
+		c := rsyncConfig{
+			name:        "tuna",
+			upstreamURL: "rsync://rsync.tuna.moe/tuna/",
+			workingDir:  "/srv/mirror/production/tuna",
+			logDir:      "/var/log/tunasync",
+			logFile:     "tuna.log",
+			useIPv6:     true,
+			interval:    600,
+		}
+
+		provider, err := newRsyncProvider(c)
+		So(err, ShouldBeNil)
+
+		So(provider.Name(), ShouldEqual, c.name)
+		So(provider.WorkingDir(), ShouldEqual, c.workingDir)
+		So(provider.LogDir(), ShouldEqual, c.logDir)
+		So(provider.LogFile(), ShouldEqual, c.logFile)
+
+		Convey("When entering a context (auto exit)", func() {
+			func() {
+				ctx := provider.EnterContext()
+				defer provider.ExitContext()
+				So(provider.WorkingDir(), ShouldEqual, c.workingDir)
+				newWorkingDir := "/srv/mirror/working/tuna"
+				ctx.Set(_WorkingDirKey, newWorkingDir)
+				So(provider.WorkingDir(), ShouldEqual, newWorkingDir)
+			}()
+
+			Convey("After context is done", func() {
+				So(provider.WorkingDir(), ShouldEqual, c.workingDir)
+			})
+		})
+
+		Convey("When entering a context (manually exit)", func() {
+			ctx := provider.EnterContext()
+			So(provider.WorkingDir(), ShouldEqual, c.workingDir)
+			newWorkingDir := "/srv/mirror/working/tuna"
+			ctx.Set(_WorkingDirKey, newWorkingDir)
+			So(provider.WorkingDir(), ShouldEqual, newWorkingDir)
+
+			Convey("After context is done", func() {
+				provider.ExitContext()
+				So(provider.WorkingDir(), ShouldEqual, c.workingDir)
+			})
+		})
+
+	})
+}

+ 48 - 0
worker/rsync_provider.go

@@ -0,0 +1,48 @@
+package worker
+
+type rsyncConfig struct {
+	name                               string
+	upstreamURL, password, excludeFile string
+	workingDir, logDir, logFile        string
+	useIPv6                            bool
+	interval                           int
+}
+
+// An RsyncProvider provides the implementation to rsync-based syncing jobs
+type rsyncProvider struct {
+	baseProvider
+	rsyncConfig
+}
+
+func newRsyncProvider(c rsyncConfig) (*rsyncProvider, error) {
+	// TODO: check config options
+	provider := &rsyncProvider{
+		baseProvider: baseProvider{
+			name:     c.name,
+			ctx:      NewContext(),
+			interval: c.interval,
+		},
+		rsyncConfig: c,
+	}
+
+	provider.ctx.Set(_WorkingDirKey, c.workingDir)
+	provider.ctx.Set(_LogDirKey, c.logDir)
+	provider.ctx.Set(_LogFileKey, c.logFile)
+
+	return provider, nil
+}
+
+// TODO: implement this
+func (p *rsyncProvider) Run() {
+
+}
+
+// TODO: implement this
+func (p *rsyncProvider) Terminate() {
+
+}
+
+// TODO: implement this
+func (p *rsyncProvider) Hooks() {
+
+}