mirror of
https://github.com/zyedidia/micro.git
synced 2026-03-19 07:17:11 +09:00
save+backup: Process the save & backup with a sequential channel
As advantage we don't need to synchonize them any longer and don't need further insufficient lock mechanisms.
This commit is contained in:
@@ -6,8 +6,6 @@ import (
|
||||
"io/fs"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/zyedidia/micro/v2/internal/config"
|
||||
"github.com/zyedidia/micro/v2/internal/screen"
|
||||
@@ -34,27 +32,7 @@ The backup was created on %s and its path is:
|
||||
|
||||
Options: [r]ecover, [i]gnore, [a]bort: `
|
||||
|
||||
var backupRequestChan chan *Buffer
|
||||
|
||||
func backupThread() {
|
||||
for {
|
||||
time.Sleep(time.Second * 8)
|
||||
|
||||
for len(backupRequestChan) > 0 {
|
||||
b := <-backupRequestChan
|
||||
bfini := atomic.LoadInt32(&(b.fini)) != 0
|
||||
if !bfini {
|
||||
b.Backup()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func init() {
|
||||
backupRequestChan = make(chan *Buffer, 10)
|
||||
|
||||
go backupThread()
|
||||
}
|
||||
const backupSeconds = 8
|
||||
|
||||
func (b *Buffer) RequestBackup() {
|
||||
if !b.requestedBackup {
|
||||
|
||||
@@ -11,6 +11,8 @@ import (
|
||||
"os/signal"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
"unicode"
|
||||
|
||||
"github.com/zyedidia/micro/v2/internal/config"
|
||||
@@ -32,6 +34,48 @@ type wrappedFile struct {
|
||||
sigChan chan os.Signal
|
||||
}
|
||||
|
||||
type saveResponse struct {
|
||||
size int
|
||||
err error
|
||||
}
|
||||
|
||||
type saveRequest struct {
|
||||
buf *Buffer
|
||||
path string
|
||||
withSudo bool
|
||||
newFile bool
|
||||
saveResponseChan chan saveResponse
|
||||
}
|
||||
|
||||
var saveRequestChan chan saveRequest
|
||||
var backupRequestChan chan *Buffer
|
||||
|
||||
func init() {
|
||||
saveRequestChan = make(chan saveRequest, 10)
|
||||
backupRequestChan = make(chan *Buffer, 10)
|
||||
|
||||
go func() {
|
||||
duration := backupSeconds * float64(time.Second)
|
||||
backupTicker := time.NewTicker(time.Duration(duration))
|
||||
|
||||
for {
|
||||
select {
|
||||
case sr := <-saveRequestChan:
|
||||
size, err := sr.buf.safeWrite(sr.path, sr.withSudo, sr.newFile)
|
||||
sr.saveResponseChan <- saveResponse{size, err}
|
||||
case <-backupTicker.C:
|
||||
for len(backupRequestChan) > 0 {
|
||||
b := <-backupRequestChan
|
||||
bfini := atomic.LoadInt32(&(b.fini)) != 0
|
||||
if !bfini {
|
||||
b.Backup()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
func openFile(name string, withSudo bool) (wrappedFile, error) {
|
||||
var err error
|
||||
var writeCloser io.WriteCloser
|
||||
@@ -267,13 +311,16 @@ func (b *Buffer) saveToFile(filename string, withSudo bool, autoSave bool) error
|
||||
}
|
||||
}
|
||||
|
||||
size, err := b.safeWrite(absFilename, withSudo, newFile)
|
||||
saveResponseChan := make(chan saveResponse)
|
||||
saveRequestChan <- saveRequest{b, absFilename, withSudo, newFile, saveResponseChan}
|
||||
result := <-saveResponseChan
|
||||
err = result.err
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !b.Settings["fastdirty"].(bool) {
|
||||
if size > LargeFileThreshold {
|
||||
if result.size > LargeFileThreshold {
|
||||
// For large files 'fastdirty' needs to be on
|
||||
b.Settings["fastdirty"] = true
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user