mirror of
https://github.com/tuna/tunasync.git
synced 2025-04-21 04:42:46 +00:00
[bug fix] provider is not terminated if premature stop command received
This commit is contained in:
parent
c8e7d29f34
commit
38b0156fae
@ -142,7 +142,7 @@ func (p *baseProvider) closeLogFile() (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *baseProvider) Run() error {
|
func (p *baseProvider) Run(started chan empty) error {
|
||||||
panic("Not Implemented")
|
panic("Not Implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -169,6 +169,7 @@ func (p *baseProvider) Terminate() error {
|
|||||||
defer p.Unlock()
|
defer p.Unlock()
|
||||||
logger.Debugf("terminating provider: %s", p.Name())
|
logger.Debugf("terminating provider: %s", p.Name())
|
||||||
if !p.IsRunning() {
|
if !p.IsRunning() {
|
||||||
|
logger.Warningf("Terminate() called while IsRunning is false: %s", p.Name())
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,7 +83,7 @@ sleep 30
|
|||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
err = provider.Run()
|
err := provider.Run(make(chan empty, 1))
|
||||||
ctx.So(err, ShouldNotBeNil)
|
ctx.So(err, ShouldNotBeNil)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
@ -86,12 +86,13 @@ func (p *cmdProvider) DataSize() string {
|
|||||||
return p.dataSize
|
return p.dataSize
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *cmdProvider) Run() error {
|
func (p *cmdProvider) Run(started chan empty) error {
|
||||||
p.dataSize = ""
|
p.dataSize = ""
|
||||||
defer p.closeLogFile()
|
defer p.closeLogFile()
|
||||||
if err := p.Start(); err != nil {
|
if err := p.Start(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
started <- empty{}
|
||||||
if err := p.Wait(); err != nil {
|
if err := p.Wait(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -139,5 +140,6 @@ func (p *cmdProvider) Start() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
p.isRunning.Store(true)
|
p.isRunning.Store(true)
|
||||||
|
logger.Debugf("set isRunning to true: %s", p.Name())
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -87,7 +87,7 @@ sleep 20
|
|||||||
cmdRun("docker", []string{"images"})
|
cmdRun("docker", []string{"images"})
|
||||||
exitedErr := make(chan error, 1)
|
exitedErr := make(chan error, 1)
|
||||||
go func() {
|
go func() {
|
||||||
err = provider.Run()
|
err = provider.Run(make(chan empty, 1))
|
||||||
logger.Debugf("provider.Run() exited")
|
logger.Debugf("provider.Run() exited")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Errorf("provider.Run() failed: %v", err)
|
logger.Errorf("provider.Run() failed: %v", err)
|
||||||
|
@ -155,11 +155,21 @@ func (m *mirrorJob) Run(managerChan chan<- jobMessage, semaphore chan empty) err
|
|||||||
|
|
||||||
var syncErr error
|
var syncErr error
|
||||||
syncDone := make(chan error, 1)
|
syncDone := make(chan error, 1)
|
||||||
|
started := make(chan empty, 10) // we may receive "started" more than one time (e.g. two_stage_rsync)
|
||||||
go func() {
|
go func() {
|
||||||
err := provider.Run()
|
err := provider.Run(started)
|
||||||
syncDone <- err
|
syncDone <- err
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
select { // Wait until provider started or error happened
|
||||||
|
case err := <-syncDone:
|
||||||
|
logger.Errorf("failed to start provider %s: %s", m.Name(), err.Error())
|
||||||
|
syncDone <- err // it will be read again later
|
||||||
|
case <-started:
|
||||||
|
logger.Debug("provider started")
|
||||||
|
}
|
||||||
|
// Now terminating the provider is feasible
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case syncErr = <-syncDone:
|
case syncErr = <-syncDone:
|
||||||
logger.Debug("syncing done")
|
logger.Debug("syncing done")
|
||||||
|
@ -24,9 +24,9 @@ type mirrorProvider interface {
|
|||||||
|
|
||||||
Type() providerEnum
|
Type() providerEnum
|
||||||
|
|
||||||
// run mirror job in background
|
// Start then Wait
|
||||||
Run() error
|
Run(started chan empty) error
|
||||||
// run mirror job in background
|
// Start the job
|
||||||
Start() error
|
Start() error
|
||||||
// Wait job to finish
|
// Wait job to finish
|
||||||
Wait() error
|
Wait() error
|
||||||
|
@ -96,7 +96,7 @@ exit 0
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
err = provider.Run()
|
err = provider.Run(make(chan empty, 1))
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
loggedContent, err := ioutil.ReadFile(provider.LogFile())
|
loggedContent, err := ioutil.ReadFile(provider.LogFile())
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
@ -127,7 +127,7 @@ exit 0
|
|||||||
provider, err := newRsyncProvider(c)
|
provider, err := newRsyncProvider(c)
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
|
|
||||||
err = provider.Run()
|
err = provider.Run(make(chan empty, 1))
|
||||||
So(err, ShouldNotBeNil)
|
So(err, ShouldNotBeNil)
|
||||||
loggedContent, err := ioutil.ReadFile(provider.LogFile())
|
loggedContent, err := ioutil.ReadFile(provider.LogFile())
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
@ -195,7 +195,7 @@ exit 0
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
err = provider.Run()
|
err = provider.Run(make(chan empty, 1))
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
loggedContent, err := ioutil.ReadFile(provider.LogFile())
|
loggedContent, err := ioutil.ReadFile(provider.LogFile())
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
@ -257,7 +257,7 @@ exit 0
|
|||||||
provider.WorkingDir(),
|
provider.WorkingDir(),
|
||||||
)
|
)
|
||||||
|
|
||||||
err = provider.Run()
|
err = provider.Run(make(chan empty, 1))
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
loggedContent, err := ioutil.ReadFile(provider.LogFile())
|
loggedContent, err := ioutil.ReadFile(provider.LogFile())
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
@ -321,7 +321,7 @@ echo $AOSP_REPO_BIN
|
|||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
So(readedScriptContent, ShouldResemble, []byte(scriptContent))
|
So(readedScriptContent, ShouldResemble, []byte(scriptContent))
|
||||||
|
|
||||||
err = provider.Run()
|
err = provider.Run(make(chan empty, 1))
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
|
|
||||||
loggedContent, err := ioutil.ReadFile(provider.LogFile())
|
loggedContent, err := ioutil.ReadFile(provider.LogFile())
|
||||||
@ -337,7 +337,7 @@ echo $AOSP_REPO_BIN
|
|||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
So(readedScriptContent, ShouldResemble, []byte(scriptContent))
|
So(readedScriptContent, ShouldResemble, []byte(scriptContent))
|
||||||
|
|
||||||
err = provider.Run()
|
err = provider.Run(make(chan empty, 1))
|
||||||
So(err, ShouldNotBeNil)
|
So(err, ShouldNotBeNil)
|
||||||
|
|
||||||
})
|
})
|
||||||
@ -349,11 +349,14 @@ sleep 10
|
|||||||
err = ioutil.WriteFile(scriptFile, []byte(scriptContent), 0755)
|
err = ioutil.WriteFile(scriptFile, []byte(scriptContent), 0755)
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
|
|
||||||
|
started := make(chan empty, 1)
|
||||||
go func() {
|
go func() {
|
||||||
err = provider.Run()
|
err := provider.Run(started)
|
||||||
ctx.So(err, ShouldNotBeNil)
|
ctx.So(err, ShouldNotBeNil)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
<-started
|
||||||
|
So(provider.IsRunning(), ShouldBeTrue)
|
||||||
time.Sleep(1 * time.Second)
|
time.Sleep(1 * time.Second)
|
||||||
err = provider.Terminate()
|
err = provider.Terminate()
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
@ -389,7 +392,7 @@ sleep 10
|
|||||||
|
|
||||||
Convey("Run the command", func() {
|
Convey("Run the command", func() {
|
||||||
|
|
||||||
err = provider.Run()
|
err = provider.Run(make(chan empty, 1))
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
|
|
||||||
})
|
})
|
||||||
@ -417,7 +420,7 @@ sleep 10
|
|||||||
provider, err := newCmdProvider(c)
|
provider, err := newCmdProvider(c)
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
|
|
||||||
err = provider.Run()
|
err = provider.Run(make(chan empty, 1))
|
||||||
So(err, ShouldNotBeNil)
|
So(err, ShouldNotBeNil)
|
||||||
So(provider.DataSize(), ShouldBeEmpty)
|
So(provider.DataSize(), ShouldBeEmpty)
|
||||||
})
|
})
|
||||||
@ -427,7 +430,7 @@ sleep 10
|
|||||||
provider, err := newCmdProvider(c)
|
provider, err := newCmdProvider(c)
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
|
|
||||||
err = provider.Run()
|
err = provider.Run(make(chan empty, 1))
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -437,7 +440,7 @@ sleep 10
|
|||||||
provider, err := newCmdProvider(c)
|
provider, err := newCmdProvider(c)
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
|
|
||||||
err = provider.Run()
|
err = provider.Run(make(chan empty, 1))
|
||||||
So(err, ShouldNotBeNil)
|
So(err, ShouldNotBeNil)
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -446,7 +449,7 @@ sleep 10
|
|||||||
provider, err := newCmdProvider(c)
|
provider, err := newCmdProvider(c)
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
|
|
||||||
err = provider.Run()
|
err = provider.Run(make(chan empty, 1))
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
So(provider.DataSize(), ShouldNotBeEmpty)
|
So(provider.DataSize(), ShouldNotBeEmpty)
|
||||||
_, err = strconv.ParseFloat(provider.DataSize(), 32)
|
_, err = strconv.ParseFloat(provider.DataSize(), 32)
|
||||||
@ -458,7 +461,7 @@ sleep 10
|
|||||||
provider, err := newCmdProvider(c)
|
provider, err := newCmdProvider(c)
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
|
|
||||||
err = provider.Run()
|
err = provider.Run(make(chan empty, 1))
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
So(provider.DataSize(), ShouldBeEmpty)
|
So(provider.DataSize(), ShouldBeEmpty)
|
||||||
})
|
})
|
||||||
@ -469,7 +472,7 @@ sleep 10
|
|||||||
provider, err := newCmdProvider(c)
|
provider, err := newCmdProvider(c)
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
|
|
||||||
err = provider.Run()
|
err = provider.Run(make(chan empty, 1))
|
||||||
So(err, ShouldNotBeNil)
|
So(err, ShouldNotBeNil)
|
||||||
So(provider.DataSize(), ShouldBeEmpty)
|
So(provider.DataSize(), ShouldBeEmpty)
|
||||||
})
|
})
|
||||||
@ -520,7 +523,7 @@ exit 0
|
|||||||
err = ioutil.WriteFile(scriptFile, []byte(scriptContent), 0755)
|
err = ioutil.WriteFile(scriptFile, []byte(scriptContent), 0755)
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
|
|
||||||
err = provider.Run()
|
err = provider.Run(make(chan empty, 2))
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
|
|
||||||
targetDir, _ := filepath.EvalSymlinks(provider.WorkingDir())
|
targetDir, _ := filepath.EvalSymlinks(provider.WorkingDir())
|
||||||
@ -562,11 +565,14 @@ exit 0
|
|||||||
err = ioutil.WriteFile(scriptFile, []byte(scriptContent), 0755)
|
err = ioutil.WriteFile(scriptFile, []byte(scriptContent), 0755)
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
|
|
||||||
|
started := make(chan empty, 2)
|
||||||
go func() {
|
go func() {
|
||||||
err = provider.Run()
|
err := provider.Run(started)
|
||||||
ctx.So(err, ShouldNotBeNil)
|
ctx.So(err, ShouldNotBeNil)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
<-started
|
||||||
|
So(provider.IsRunning(), ShouldBeTrue)
|
||||||
time.Sleep(1 * time.Second)
|
time.Sleep(1 * time.Second)
|
||||||
err = provider.Terminate()
|
err = provider.Terminate()
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
@ -606,7 +612,7 @@ exit 0
|
|||||||
provider, err := newTwoStageRsyncProvider(c)
|
provider, err := newTwoStageRsyncProvider(c)
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
|
|
||||||
err = provider.Run()
|
err = provider.Run(make(chan empty, 2))
|
||||||
So(err, ShouldNotBeNil)
|
So(err, ShouldNotBeNil)
|
||||||
loggedContent, err := ioutil.ReadFile(provider.LogFile())
|
loggedContent, err := ioutil.ReadFile(provider.LogFile())
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
|
@ -103,12 +103,13 @@ func (p *rsyncProvider) DataSize() string {
|
|||||||
return p.dataSize
|
return p.dataSize
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *rsyncProvider) Run() error {
|
func (p *rsyncProvider) Run(started chan empty) error {
|
||||||
p.dataSize = ""
|
p.dataSize = ""
|
||||||
defer p.closeLogFile()
|
defer p.closeLogFile()
|
||||||
if err := p.Start(); err != nil {
|
if err := p.Start(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
started <- empty{}
|
||||||
if err := p.Wait(); err != nil {
|
if err := p.Wait(); err != nil {
|
||||||
code, msg := internal.TranslateRsyncErrorCode(err)
|
code, msg := internal.TranslateRsyncErrorCode(err)
|
||||||
if code != 0 {
|
if code != 0 {
|
||||||
@ -144,5 +145,6 @@ func (p *rsyncProvider) Start() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
p.isRunning.Store(true)
|
p.isRunning.Store(true)
|
||||||
|
logger.Debugf("set isRunning to true: %s", p.Name())
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -133,7 +133,7 @@ func (p *twoStageRsyncProvider) Options(stage int) ([]string, error) {
|
|||||||
return options, nil
|
return options, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *twoStageRsyncProvider) Run() error {
|
func (p *twoStageRsyncProvider) Run(started chan empty) error {
|
||||||
p.Lock()
|
p.Lock()
|
||||||
defer p.Unlock()
|
defer p.Unlock()
|
||||||
|
|
||||||
@ -163,6 +163,7 @@ func (p *twoStageRsyncProvider) Run() error {
|
|||||||
}
|
}
|
||||||
p.isRunning.Store(true)
|
p.isRunning.Store(true)
|
||||||
logger.Debugf("set isRunning to true: %s", p.Name())
|
logger.Debugf("set isRunning to true: %s", p.Name())
|
||||||
|
started <- empty{}
|
||||||
|
|
||||||
p.Unlock()
|
p.Unlock()
|
||||||
err = p.Wait()
|
err = p.Wait()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user