From 44af0d5e62faf7846b8d0c2a8dbc12970a3bc9c2 Mon Sep 17 00:00:00 2001 From: bigeagle Date: Thu, 21 Apr 2016 21:57:32 +0800 Subject: [PATCH] feature(worker): framework of mirror provider --- .testpackages.txt | 1 + worker/provider.go | 90 +++++++++++++++++++++++++++++++++++++--- worker/provider_test.go | 59 ++++++++++++++++++++++++++ worker/rsync_provider.go | 48 +++++++++++++++++++++ 4 files changed, 193 insertions(+), 5 deletions(-) create mode 100644 worker/provider_test.go create mode 100644 worker/rsync_provider.go diff --git a/.testpackages.txt b/.testpackages.txt index ba04577..f95aed0 100644 --- a/.testpackages.txt +++ b/.testpackages.txt @@ -1,2 +1,3 @@ github.com/tuna/tunasync/internal github.com/tuna/tunasync/manager +github.com/tuna/tunasync/worker diff --git a/worker/provider.go b/worker/provider.go index 410e93a..065c40e 100644 --- a/worker/provider.go +++ b/worker/provider.go @@ -1,13 +1,93 @@ -// mirror provider is the wrapper of mirror jobs - package worker -// a mirrorProvider instance +// mirror provider is the wrapper of mirror jobs + +type providerType uint8 + +const ( + _WorkingDirKey = "working_dir" + _LogDirKey = "log_dir" + _LogFileKey = "log_file" +) + +// 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") } diff --git a/worker/provider_test.go b/worker/provider_test.go new file mode 100644 index 0000000..7374da8 --- /dev/null +++ b/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) + }) + }) + + }) +} diff --git a/worker/rsync_provider.go b/worker/rsync_provider.go new file mode 100644 index 0000000..b0bcd06 --- /dev/null +++ b/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() { + +}