@@ -77,11 +77,11 @@ type puller interface {
|
||||
pull() bool // true when successfull and should not be retried
|
||||
}
|
||||
|
||||
func newFolder(model *model, fset *db.FileSet, ignores *ignore.Matcher, cfg config.FolderConfiguration) folder {
|
||||
func newFolder(model *model, fset *db.FileSet, ignores *ignore.Matcher, cfg config.FolderConfiguration, evLogger events.Logger) folder {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
|
||||
return folder{
|
||||
stateTracker: newStateTracker(cfg.ID),
|
||||
stateTracker: newStateTracker(cfg.ID, evLogger),
|
||||
FolderConfiguration: cfg,
|
||||
FolderStatisticsReference: stats.NewFolderStatisticsReference(model.db, cfg.ID),
|
||||
|
||||
@@ -630,7 +630,7 @@ func (f *folder) monitorWatch(ctx context.Context) {
|
||||
failTimer.Reset(time.Minute)
|
||||
continue
|
||||
}
|
||||
watchaggregator.Aggregate(eventChan, f.watchChan, f.FolderConfiguration, f.model.cfg, aggrCtx)
|
||||
watchaggregator.Aggregate(eventChan, f.watchChan, f.FolderConfiguration, f.model.cfg, f.evLogger, aggrCtx)
|
||||
l.Debugln("Started filesystem watcher for folder", f.Description())
|
||||
case err = <-errChan:
|
||||
f.setWatchError(err)
|
||||
@@ -669,7 +669,7 @@ func (f *folder) setWatchError(err error) {
|
||||
if err != nil {
|
||||
data["to"] = err.Error()
|
||||
}
|
||||
events.Default.Log(events.FolderWatchStateChanged, data)
|
||||
f.evLogger.Log(events.FolderWatchStateChanged, data)
|
||||
}
|
||||
if err == nil {
|
||||
return
|
||||
@@ -800,7 +800,7 @@ func (f *folder) updateLocals(fs []protocol.FileInfo) {
|
||||
filenames[i] = file.Name
|
||||
}
|
||||
|
||||
events.Default.Log(events.LocalIndexUpdated, map[string]interface{}{
|
||||
f.evLogger.Log(events.LocalIndexUpdated, map[string]interface{}{
|
||||
"folder": f.ID,
|
||||
"items": len(fs),
|
||||
"filenames": filenames,
|
||||
@@ -839,7 +839,7 @@ func (f *folder) emitDiskChangeEvents(fs []protocol.FileInfo, typeOfEvent events
|
||||
}
|
||||
|
||||
// Two different events can be fired here based on what EventType is passed into function
|
||||
events.Default.Log(typeOfEvent, map[string]string{
|
||||
f.evLogger.Log(typeOfEvent, map[string]string{
|
||||
"folder": f.ID,
|
||||
"folderID": f.ID, // incorrect, deprecated, kept for historical compliance
|
||||
"label": f.Label,
|
||||
|
||||
@@ -12,6 +12,7 @@ import (
|
||||
|
||||
"github.com/syncthing/syncthing/lib/config"
|
||||
"github.com/syncthing/syncthing/lib/db"
|
||||
"github.com/syncthing/syncthing/lib/events"
|
||||
"github.com/syncthing/syncthing/lib/fs"
|
||||
"github.com/syncthing/syncthing/lib/ignore"
|
||||
"github.com/syncthing/syncthing/lib/protocol"
|
||||
@@ -56,8 +57,8 @@ type receiveOnlyFolder struct {
|
||||
*sendReceiveFolder
|
||||
}
|
||||
|
||||
func newReceiveOnlyFolder(model *model, fset *db.FileSet, ignores *ignore.Matcher, cfg config.FolderConfiguration, ver versioner.Versioner, fs fs.Filesystem) service {
|
||||
sr := newSendReceiveFolder(model, fset, ignores, cfg, ver, fs).(*sendReceiveFolder)
|
||||
func newReceiveOnlyFolder(model *model, fset *db.FileSet, ignores *ignore.Matcher, cfg config.FolderConfiguration, ver versioner.Versioner, fs fs.Filesystem, evLogger events.Logger) service {
|
||||
sr := newSendReceiveFolder(model, fset, ignores, cfg, ver, fs, evLogger).(*sendReceiveFolder)
|
||||
sr.localFlags = protocol.FlagLocalReceiveOnly // gets propagated to the scanner, and set on locally changed files
|
||||
return &receiveOnlyFolder{sr}
|
||||
}
|
||||
|
||||
@@ -321,6 +321,7 @@ func setupROFolder() (*model, *sendOnlyFolder) {
|
||||
|
||||
f := &sendOnlyFolder{
|
||||
folder: folder{
|
||||
stateTracker: newStateTracker(fcfg.ID, m.evLogger),
|
||||
fset: m.folderFiles[fcfg.ID],
|
||||
FolderConfiguration: fcfg,
|
||||
},
|
||||
|
||||
@@ -9,6 +9,7 @@ package model
|
||||
import (
|
||||
"github.com/syncthing/syncthing/lib/config"
|
||||
"github.com/syncthing/syncthing/lib/db"
|
||||
"github.com/syncthing/syncthing/lib/events"
|
||||
"github.com/syncthing/syncthing/lib/fs"
|
||||
"github.com/syncthing/syncthing/lib/ignore"
|
||||
"github.com/syncthing/syncthing/lib/protocol"
|
||||
@@ -24,9 +25,9 @@ type sendOnlyFolder struct {
|
||||
folder
|
||||
}
|
||||
|
||||
func newSendOnlyFolder(model *model, fset *db.FileSet, ignores *ignore.Matcher, cfg config.FolderConfiguration, _ versioner.Versioner, _ fs.Filesystem) service {
|
||||
func newSendOnlyFolder(model *model, fset *db.FileSet, ignores *ignore.Matcher, cfg config.FolderConfiguration, _ versioner.Versioner, _ fs.Filesystem, evLogger events.Logger) service {
|
||||
f := &sendOnlyFolder{
|
||||
folder: newFolder(model, fset, ignores, cfg),
|
||||
folder: newFolder(model, fset, ignores, cfg, evLogger),
|
||||
}
|
||||
f.folder.puller = f
|
||||
f.folder.Service = util.AsService(f.serve)
|
||||
|
||||
@@ -108,9 +108,9 @@ type sendReceiveFolder struct {
|
||||
pullErrorsMut sync.Mutex
|
||||
}
|
||||
|
||||
func newSendReceiveFolder(model *model, fset *db.FileSet, ignores *ignore.Matcher, cfg config.FolderConfiguration, ver versioner.Versioner, fs fs.Filesystem) service {
|
||||
func newSendReceiveFolder(model *model, fset *db.FileSet, ignores *ignore.Matcher, cfg config.FolderConfiguration, ver versioner.Versioner, fs fs.Filesystem, evLogger events.Logger) service {
|
||||
f := &sendReceiveFolder{
|
||||
folder: newFolder(model, fset, ignores, cfg),
|
||||
folder: newFolder(model, fset, ignores, cfg, evLogger),
|
||||
fs: fs,
|
||||
versioner: ver,
|
||||
queue: newJobQueue(),
|
||||
@@ -211,7 +211,7 @@ func (f *sendReceiveFolder) pull() bool {
|
||||
// errors preventing us. Flag this with a warning and
|
||||
// wait a bit longer before retrying.
|
||||
if errors := f.Errors(); len(errors) > 0 {
|
||||
events.Default.Log(events.FolderErrors, map[string]interface{}{
|
||||
f.evLogger.Log(events.FolderErrors, map[string]interface{}{
|
||||
"folder": f.folderID,
|
||||
"errors": errors,
|
||||
})
|
||||
@@ -544,7 +544,7 @@ func (f *sendReceiveFolder) handleDir(file protocol.FileInfo, dbUpdateChan chan<
|
||||
|
||||
f.resetPullError(file.Name)
|
||||
|
||||
events.Default.Log(events.ItemStarted, map[string]string{
|
||||
f.evLogger.Log(events.ItemStarted, map[string]string{
|
||||
"folder": f.folderID,
|
||||
"item": file.Name,
|
||||
"type": "dir",
|
||||
@@ -552,7 +552,7 @@ func (f *sendReceiveFolder) handleDir(file protocol.FileInfo, dbUpdateChan chan<
|
||||
})
|
||||
|
||||
defer func() {
|
||||
events.Default.Log(events.ItemFinished, map[string]interface{}{
|
||||
f.evLogger.Log(events.ItemFinished, map[string]interface{}{
|
||||
"folder": f.folderID,
|
||||
"item": file.Name,
|
||||
"error": events.Error(err),
|
||||
@@ -700,7 +700,7 @@ func (f *sendReceiveFolder) handleSymlink(file protocol.FileInfo, dbUpdateChan c
|
||||
|
||||
f.resetPullError(file.Name)
|
||||
|
||||
events.Default.Log(events.ItemStarted, map[string]string{
|
||||
f.evLogger.Log(events.ItemStarted, map[string]string{
|
||||
"folder": f.folderID,
|
||||
"item": file.Name,
|
||||
"type": "symlink",
|
||||
@@ -708,7 +708,7 @@ func (f *sendReceiveFolder) handleSymlink(file protocol.FileInfo, dbUpdateChan c
|
||||
})
|
||||
|
||||
defer func() {
|
||||
events.Default.Log(events.ItemFinished, map[string]interface{}{
|
||||
f.evLogger.Log(events.ItemFinished, map[string]interface{}{
|
||||
"folder": f.folderID,
|
||||
"item": file.Name,
|
||||
"error": events.Error(err),
|
||||
@@ -782,7 +782,7 @@ func (f *sendReceiveFolder) deleteDir(file protocol.FileInfo, dbUpdateChan chan<
|
||||
// care not declare another err.
|
||||
var err error
|
||||
|
||||
events.Default.Log(events.ItemStarted, map[string]string{
|
||||
f.evLogger.Log(events.ItemStarted, map[string]string{
|
||||
"folder": f.folderID,
|
||||
"item": file.Name,
|
||||
"type": "dir",
|
||||
@@ -790,7 +790,7 @@ func (f *sendReceiveFolder) deleteDir(file protocol.FileInfo, dbUpdateChan chan<
|
||||
})
|
||||
|
||||
defer func() {
|
||||
events.Default.Log(events.ItemFinished, map[string]interface{}{
|
||||
f.evLogger.Log(events.ItemFinished, map[string]interface{}{
|
||||
"folder": f.folderID,
|
||||
"item": file.Name,
|
||||
"error": events.Error(err),
|
||||
@@ -822,7 +822,7 @@ func (f *sendReceiveFolder) deleteFileWithCurrent(file, cur protocol.FileInfo, h
|
||||
|
||||
f.resetPullError(file.Name)
|
||||
|
||||
events.Default.Log(events.ItemStarted, map[string]string{
|
||||
f.evLogger.Log(events.ItemStarted, map[string]string{
|
||||
"folder": f.folderID,
|
||||
"item": file.Name,
|
||||
"type": "file",
|
||||
@@ -833,7 +833,7 @@ func (f *sendReceiveFolder) deleteFileWithCurrent(file, cur protocol.FileInfo, h
|
||||
if err != nil {
|
||||
f.newPullError(file.Name, errors.Wrap(err, "delete file"))
|
||||
}
|
||||
events.Default.Log(events.ItemFinished, map[string]interface{}{
|
||||
f.evLogger.Log(events.ItemFinished, map[string]interface{}{
|
||||
"folder": f.folderID,
|
||||
"item": file.Name,
|
||||
"error": events.Error(err),
|
||||
@@ -897,13 +897,13 @@ func (f *sendReceiveFolder) renameFile(cur, source, target protocol.FileInfo, db
|
||||
// care not declare another err.
|
||||
var err error
|
||||
|
||||
events.Default.Log(events.ItemStarted, map[string]string{
|
||||
f.evLogger.Log(events.ItemStarted, map[string]string{
|
||||
"folder": f.folderID,
|
||||
"item": source.Name,
|
||||
"type": "file",
|
||||
"action": "delete",
|
||||
})
|
||||
events.Default.Log(events.ItemStarted, map[string]string{
|
||||
f.evLogger.Log(events.ItemStarted, map[string]string{
|
||||
"folder": f.folderID,
|
||||
"item": target.Name,
|
||||
"type": "file",
|
||||
@@ -911,14 +911,14 @@ func (f *sendReceiveFolder) renameFile(cur, source, target protocol.FileInfo, db
|
||||
})
|
||||
|
||||
defer func() {
|
||||
events.Default.Log(events.ItemFinished, map[string]interface{}{
|
||||
f.evLogger.Log(events.ItemFinished, map[string]interface{}{
|
||||
"folder": f.folderID,
|
||||
"item": source.Name,
|
||||
"error": events.Error(err),
|
||||
"type": "file",
|
||||
"action": "delete",
|
||||
})
|
||||
events.Default.Log(events.ItemFinished, map[string]interface{}{
|
||||
f.evLogger.Log(events.ItemFinished, map[string]interface{}{
|
||||
"folder": f.folderID,
|
||||
"item": target.Name,
|
||||
"error": events.Error(err),
|
||||
@@ -1095,7 +1095,7 @@ func (f *sendReceiveFolder) handleFile(file protocol.FileInfo, copyChan chan<- c
|
||||
// Shuffle the blocks
|
||||
rand.Shuffle(blocks)
|
||||
|
||||
events.Default.Log(events.ItemStarted, map[string]string{
|
||||
f.evLogger.Log(events.ItemStarted, map[string]string{
|
||||
"folder": f.folderID,
|
||||
"item": file.Name,
|
||||
"type": "file",
|
||||
@@ -1178,7 +1178,7 @@ func (f *sendReceiveFolder) shortcutFile(file, curFile protocol.FileInfo, dbUpda
|
||||
|
||||
f.resetPullError(file.Name)
|
||||
|
||||
events.Default.Log(events.ItemStarted, map[string]string{
|
||||
f.evLogger.Log(events.ItemStarted, map[string]string{
|
||||
"folder": f.folderID,
|
||||
"item": file.Name,
|
||||
"type": "file",
|
||||
@@ -1186,7 +1186,7 @@ func (f *sendReceiveFolder) shortcutFile(file, curFile protocol.FileInfo, dbUpda
|
||||
})
|
||||
|
||||
var err error
|
||||
defer events.Default.Log(events.ItemFinished, map[string]interface{}{
|
||||
defer f.evLogger.Log(events.ItemFinished, map[string]interface{}{
|
||||
"folder": f.folderID,
|
||||
"item": file.Name,
|
||||
"error": events.Error(err),
|
||||
@@ -1575,7 +1575,7 @@ func (f *sendReceiveFolder) finisherRoutine(in <-chan *sharedPullerState, dbUpda
|
||||
|
||||
f.model.progressEmitter.Deregister(state)
|
||||
|
||||
events.Default.Log(events.ItemFinished, map[string]interface{}{
|
||||
f.evLogger.Log(events.ItemFinished, map[string]interface{}{
|
||||
"folder": f.folderID,
|
||||
"item": state.file.Name,
|
||||
"error": events.Error(err),
|
||||
|
||||
@@ -96,7 +96,7 @@ func setupSendReceiveFolder(files ...protocol.FileInfo) (*model, *sendReceiveFol
|
||||
|
||||
f := &sendReceiveFolder{
|
||||
folder: folder{
|
||||
stateTracker: newStateTracker("default"),
|
||||
stateTracker: newStateTracker("default", model.evLogger),
|
||||
model: model,
|
||||
fset: model.folderFiles[fcfg.ID],
|
||||
initialScanFinished: make(chan struct{}),
|
||||
@@ -121,6 +121,12 @@ func setupSendReceiveFolder(files ...protocol.FileInfo) (*model, *sendReceiveFol
|
||||
return model, f
|
||||
}
|
||||
|
||||
func cleanupSRFolder(f *sendReceiveFolder, m *model) {
|
||||
m.evLogger.Stop()
|
||||
os.Remove(m.cfg.ConfigPath())
|
||||
os.Remove(f.Filesystem().URI())
|
||||
}
|
||||
|
||||
// Layout of the files: (indexes from the above array)
|
||||
// 12345678 - Required file
|
||||
// 02005008 - Existing file (currently in the index)
|
||||
@@ -137,10 +143,7 @@ func TestHandleFile(t *testing.T) {
|
||||
requiredFile.Blocks = blocks[1:]
|
||||
|
||||
m, f := setupSendReceiveFolder(existingFile)
|
||||
defer func() {
|
||||
os.Remove(m.cfg.ConfigPath())
|
||||
os.Remove(f.Filesystem().URI())
|
||||
}()
|
||||
defer cleanupSRFolder(f, m)
|
||||
|
||||
copyChan := make(chan copyBlocksState, 1)
|
||||
dbUpdateChan := make(chan dbUpdateJob, 1)
|
||||
@@ -183,10 +186,7 @@ func TestHandleFileWithTemp(t *testing.T) {
|
||||
requiredFile.Blocks = blocks[1:]
|
||||
|
||||
m, f := setupSendReceiveFolder(existingFile)
|
||||
defer func() {
|
||||
os.Remove(m.cfg.ConfigPath())
|
||||
os.Remove(f.Filesystem().URI())
|
||||
}()
|
||||
defer cleanupSRFolder(f, m)
|
||||
|
||||
if _, err := prepareTmpFile(f.Filesystem()); err != nil {
|
||||
t.Fatal(err)
|
||||
@@ -236,10 +236,7 @@ func TestCopierFinder(t *testing.T) {
|
||||
requiredFile.Name = "file2"
|
||||
|
||||
m, f := setupSendReceiveFolder(existingFile)
|
||||
defer func() {
|
||||
os.Remove(m.cfg.ConfigPath())
|
||||
os.Remove(f.Filesystem().URI())
|
||||
}()
|
||||
defer cleanupSRFolder(f, m)
|
||||
|
||||
if _, err := prepareTmpFile(f.Filesystem()); err != nil {
|
||||
t.Fatal(err)
|
||||
@@ -302,11 +299,8 @@ func TestCopierFinder(t *testing.T) {
|
||||
func TestWeakHash(t *testing.T) {
|
||||
// Setup the model/pull environment
|
||||
model, fo := setupSendReceiveFolder()
|
||||
defer cleanupSRFolder(fo, model)
|
||||
ffs := fo.Filesystem()
|
||||
defer func() {
|
||||
os.Remove(model.cfg.ConfigPath())
|
||||
os.Remove(ffs.URI())
|
||||
}()
|
||||
|
||||
tempFile := fs.TempName("weakhash")
|
||||
var shift int64 = 10
|
||||
@@ -432,10 +426,7 @@ func TestCopierCleanup(t *testing.T) {
|
||||
// Create a file
|
||||
file := setupFile("test", []int{0})
|
||||
m, f := setupSendReceiveFolder(file)
|
||||
defer func() {
|
||||
os.Remove(m.cfg.ConfigPath())
|
||||
os.Remove(f.Filesystem().URI())
|
||||
}()
|
||||
defer cleanupSRFolder(f, m)
|
||||
|
||||
file.Blocks = []protocol.BlockInfo{blocks[1]}
|
||||
file.Version = file.Version.Update(myID.Short())
|
||||
@@ -468,13 +459,10 @@ func TestDeregisterOnFailInCopy(t *testing.T) {
|
||||
file := setupFile("filex", []int{0, 2, 0, 0, 5, 0, 0, 8})
|
||||
|
||||
m, f := setupSendReceiveFolder()
|
||||
defer func() {
|
||||
os.Remove(m.cfg.ConfigPath())
|
||||
os.Remove(f.Filesystem().URI())
|
||||
}()
|
||||
defer cleanupSRFolder(f, m)
|
||||
|
||||
// Set up our evet subscription early
|
||||
s := events.Default.Subscribe(events.ItemFinished)
|
||||
s := m.evLogger.Subscribe(events.ItemFinished)
|
||||
|
||||
// queue.Done should be called by the finisher routine
|
||||
f.queue.Push("filex", 0, time.Time{})
|
||||
@@ -558,13 +546,10 @@ func TestDeregisterOnFailInPull(t *testing.T) {
|
||||
file := setupFile("filex", []int{0, 2, 0, 0, 5, 0, 0, 8})
|
||||
|
||||
m, f := setupSendReceiveFolder()
|
||||
defer func() {
|
||||
os.Remove(m.cfg.ConfigPath())
|
||||
os.Remove(f.Filesystem().URI())
|
||||
}()
|
||||
defer cleanupSRFolder(f, m)
|
||||
|
||||
// Set up our evet subscription early
|
||||
s := events.Default.Subscribe(events.ItemFinished)
|
||||
s := m.evLogger.Subscribe(events.ItemFinished)
|
||||
|
||||
// queue.Done should be called by the finisher routine
|
||||
f.queue.Push("filex", 0, time.Time{})
|
||||
@@ -636,12 +621,9 @@ func TestDeregisterOnFailInPull(t *testing.T) {
|
||||
|
||||
func TestIssue3164(t *testing.T) {
|
||||
m, f := setupSendReceiveFolder()
|
||||
defer cleanupSRFolder(f, m)
|
||||
ffs := f.Filesystem()
|
||||
tmpDir := ffs.URI()
|
||||
defer func() {
|
||||
os.Remove(m.cfg.ConfigPath())
|
||||
os.Remove(tmpDir)
|
||||
}()
|
||||
|
||||
ignDir := filepath.Join("issue3164", "oktodelete")
|
||||
subDir := filepath.Join(ignDir, "foobar")
|
||||
@@ -728,11 +710,8 @@ func TestDiffEmpty(t *testing.T) {
|
||||
// in the db.
|
||||
func TestDeleteIgnorePerms(t *testing.T) {
|
||||
m, f := setupSendReceiveFolder()
|
||||
defer cleanupSRFolder(f, m)
|
||||
ffs := f.Filesystem()
|
||||
defer func() {
|
||||
os.Remove(m.cfg.ConfigPath())
|
||||
os.Remove(ffs.URI())
|
||||
}()
|
||||
f.IgnorePerms = true
|
||||
|
||||
name := "deleteIgnorePerms"
|
||||
@@ -778,7 +757,7 @@ func TestCopyOwner(t *testing.T) {
|
||||
// filesystem.
|
||||
|
||||
m, f := setupSendReceiveFolder()
|
||||
defer os.Remove(m.cfg.ConfigPath())
|
||||
defer cleanupSRFolder(f, m)
|
||||
f.folder.FolderConfiguration = config.NewFolderConfiguration(m.id, f.ID, f.Label, fs.FilesystemTypeFake, "/TestCopyOwner")
|
||||
f.folder.FolderConfiguration.CopyOwnershipFromParent = true
|
||||
|
||||
@@ -867,11 +846,8 @@ func TestCopyOwner(t *testing.T) {
|
||||
// is replaced with a directory and versions are conflicting
|
||||
func TestSRConflictReplaceFileByDir(t *testing.T) {
|
||||
m, f := setupSendReceiveFolder()
|
||||
defer cleanupSRFolder(f, m)
|
||||
ffs := f.Filesystem()
|
||||
defer func() {
|
||||
os.Remove(m.cfg.ConfigPath())
|
||||
os.Remove(ffs.URI())
|
||||
}()
|
||||
|
||||
name := "foo"
|
||||
|
||||
@@ -902,11 +878,8 @@ func TestSRConflictReplaceFileByDir(t *testing.T) {
|
||||
// is replaced with a link and versions are conflicting
|
||||
func TestSRConflictReplaceFileByLink(t *testing.T) {
|
||||
m, f := setupSendReceiveFolder()
|
||||
defer cleanupSRFolder(f, m)
|
||||
ffs := f.Filesystem()
|
||||
defer func() {
|
||||
os.Remove(m.cfg.ConfigPath())
|
||||
os.Remove(ffs.URI())
|
||||
}()
|
||||
|
||||
name := "foo"
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@ type folderSummaryService struct {
|
||||
cfg config.Wrapper
|
||||
model Model
|
||||
id protocol.DeviceID
|
||||
evLogger events.Logger
|
||||
immediate chan string
|
||||
|
||||
// For keeping track of folders to recalculate for
|
||||
@@ -47,7 +48,7 @@ type folderSummaryService struct {
|
||||
lastEventReqMut sync.Mutex
|
||||
}
|
||||
|
||||
func NewFolderSummaryService(cfg config.Wrapper, m Model, id protocol.DeviceID) FolderSummaryService {
|
||||
func NewFolderSummaryService(cfg config.Wrapper, m Model, id protocol.DeviceID, evLogger events.Logger) FolderSummaryService {
|
||||
service := &folderSummaryService{
|
||||
Supervisor: suture.New("folderSummaryService", suture.Spec{
|
||||
PassThroughPanics: true,
|
||||
@@ -55,6 +56,7 @@ func NewFolderSummaryService(cfg config.Wrapper, m Model, id protocol.DeviceID)
|
||||
cfg: cfg,
|
||||
model: m,
|
||||
id: id,
|
||||
evLogger: evLogger,
|
||||
immediate: make(chan string),
|
||||
folders: make(map[string]struct{}),
|
||||
foldersMut: sync.NewMutex(),
|
||||
@@ -144,8 +146,8 @@ func (c *folderSummaryService) OnEventRequest() {
|
||||
// listenForUpdates subscribes to the event bus and makes note of folders that
|
||||
// need their data recalculated.
|
||||
func (c *folderSummaryService) listenForUpdates(stop chan struct{}) {
|
||||
sub := events.Default.Subscribe(events.LocalIndexUpdated | events.RemoteIndexUpdated | events.StateChanged | events.RemoteDownloadProgress | events.DeviceConnected | events.FolderWatchStateChanged | events.DownloadProgress)
|
||||
defer events.Default.Unsubscribe(sub)
|
||||
sub := c.evLogger.Subscribe(events.LocalIndexUpdated | events.RemoteIndexUpdated | events.StateChanged | events.RemoteDownloadProgress | events.DeviceConnected | events.FolderWatchStateChanged | events.DownloadProgress)
|
||||
defer sub.Unsubscribe()
|
||||
|
||||
for {
|
||||
// This loop needs to be fast so we don't miss too many events.
|
||||
@@ -291,7 +293,7 @@ func (c *folderSummaryService) sendSummary(folder string) {
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
events.Default.Log(events.FolderSummary, map[string]interface{}{
|
||||
c.evLogger.Log(events.FolderSummary, map[string]interface{}{
|
||||
"folder": folder,
|
||||
"summary": data,
|
||||
})
|
||||
@@ -311,6 +313,6 @@ func (c *folderSummaryService) sendSummary(folder string) {
|
||||
comp := c.model.Completion(devCfg.DeviceID, folder).Map()
|
||||
comp["folder"] = folder
|
||||
comp["device"] = devCfg.DeviceID.String()
|
||||
events.Default.Log(events.FolderCompletion, comp)
|
||||
c.evLogger.Log(events.FolderCompletion, comp)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,6 +42,7 @@ func (s folderState) String() string {
|
||||
|
||||
type stateTracker struct {
|
||||
folderID string
|
||||
evLogger events.Logger
|
||||
|
||||
mut sync.Mutex
|
||||
current folderState
|
||||
@@ -49,9 +50,10 @@ type stateTracker struct {
|
||||
changed time.Time
|
||||
}
|
||||
|
||||
func newStateTracker(id string) stateTracker {
|
||||
func newStateTracker(id string, evLogger events.Logger) stateTracker {
|
||||
return stateTracker{
|
||||
folderID: id,
|
||||
evLogger: evLogger,
|
||||
mut: sync.NewMutex(),
|
||||
}
|
||||
}
|
||||
@@ -83,7 +85,7 @@ func (s *stateTracker) setState(newState folderState) {
|
||||
s.current = newState
|
||||
s.changed = time.Now()
|
||||
|
||||
events.Default.Log(events.StateChanged, eventData)
|
||||
s.evLogger.Log(events.StateChanged, eventData)
|
||||
}
|
||||
s.mut.Unlock()
|
||||
}
|
||||
@@ -124,5 +126,5 @@ func (s *stateTracker) setError(err error) {
|
||||
s.err = err
|
||||
s.changed = time.Now()
|
||||
|
||||
events.Default.Log(events.StateChanged, eventData)
|
||||
s.evLogger.Log(events.StateChanged, eventData)
|
||||
}
|
||||
|
||||
@@ -128,6 +128,7 @@ type model struct {
|
||||
shortID protocol.ShortID
|
||||
cacheIgnoredFiles bool
|
||||
protectedFiles []string
|
||||
evLogger events.Logger
|
||||
|
||||
clientName string
|
||||
clientVersion string
|
||||
@@ -152,7 +153,7 @@ type model struct {
|
||||
foldersRunning int32 // for testing only
|
||||
}
|
||||
|
||||
type folderFactory func(*model, *db.FileSet, *ignore.Matcher, config.FolderConfiguration, versioner.Versioner, fs.Filesystem) service
|
||||
type folderFactory func(*model, *db.FileSet, *ignore.Matcher, config.FolderConfiguration, versioner.Versioner, fs.Filesystem, events.Logger) service
|
||||
|
||||
var (
|
||||
folderFactories = make(map[config.FolderType]folderFactory)
|
||||
@@ -175,7 +176,7 @@ var (
|
||||
// NewModel creates and starts a new model. The model starts in read-only mode,
|
||||
// where it sends index information to connected peers and responds to requests
|
||||
// for file data without altering the local folder in any way.
|
||||
func NewModel(cfg config.Wrapper, id protocol.DeviceID, clientName, clientVersion string, ldb *db.Lowlevel, protectedFiles []string) Model {
|
||||
func NewModel(cfg config.Wrapper, id protocol.DeviceID, clientName, clientVersion string, ldb *db.Lowlevel, protectedFiles []string, evLogger events.Logger) Model {
|
||||
m := &model{
|
||||
Supervisor: suture.New("model", suture.Spec{
|
||||
Log: func(line string) {
|
||||
@@ -186,11 +187,12 @@ func NewModel(cfg config.Wrapper, id protocol.DeviceID, clientName, clientVersio
|
||||
cfg: cfg,
|
||||
db: ldb,
|
||||
finder: db.NewBlockFinder(ldb),
|
||||
progressEmitter: NewProgressEmitter(cfg),
|
||||
progressEmitter: NewProgressEmitter(cfg, evLogger),
|
||||
id: id,
|
||||
shortID: id.Short(),
|
||||
cacheIgnoredFiles: cfg.Options().CacheIgnoredFiles,
|
||||
protectedFiles: protectedFiles,
|
||||
evLogger: evLogger,
|
||||
clientName: clientName,
|
||||
clientVersion: clientVersion,
|
||||
folderCfgs: make(map[string]config.FolderConfiguration),
|
||||
@@ -310,7 +312,7 @@ func (m *model) startFolderLocked(cfg config.FolderConfiguration) {
|
||||
ffs.Hide(".stversions")
|
||||
ffs.Hide(".stignore")
|
||||
|
||||
p := folderFactory(m, fset, m.folderIgnores[folder], cfg, ver, ffs)
|
||||
p := folderFactory(m, fset, m.folderIgnores[folder], cfg, ver, ffs, m.evLogger)
|
||||
|
||||
m.folderRunners[folder] = p
|
||||
|
||||
@@ -1023,7 +1025,7 @@ func (m *model) handleIndex(deviceID protocol.DeviceID, folder string, fs []prot
|
||||
}
|
||||
files.Update(deviceID, fs)
|
||||
|
||||
events.Default.Log(events.RemoteIndexUpdated, map[string]interface{}{
|
||||
m.evLogger.Log(events.RemoteIndexUpdated, map[string]interface{}{
|
||||
"device": deviceID.String(),
|
||||
"folder": folder,
|
||||
"items": len(fs),
|
||||
@@ -1077,7 +1079,7 @@ func (m *model) ClusterConfig(deviceID protocol.DeviceID, cm protocol.ClusterCon
|
||||
}
|
||||
m.cfg.AddOrUpdatePendingFolder(folder.ID, folder.Label, deviceID)
|
||||
changed = true
|
||||
events.Default.Log(events.FolderRejected, map[string]string{
|
||||
m.evLogger.Log(events.FolderRejected, map[string]string{
|
||||
"folder": folder.ID,
|
||||
"folderLabel": folder.Label,
|
||||
"device": deviceID.String(),
|
||||
@@ -1180,6 +1182,7 @@ func (m *model) ClusterConfig(deviceID protocol.DeviceID, cm protocol.ClusterCon
|
||||
fset: fs,
|
||||
prevSequence: startSequence,
|
||||
dropSymlinks: dropSymlinks,
|
||||
evLogger: m.evLogger,
|
||||
}
|
||||
is.Service = util.AsService(is.serve)
|
||||
// The token isn't tracked as the service stops when the connection
|
||||
@@ -1432,7 +1435,7 @@ func (m *model) Closed(conn protocol.Connection, err error) {
|
||||
delete(m.closed, device)
|
||||
|
||||
l.Infof("Connection to %s at %s closed: %v", device, conn.Name(), err)
|
||||
events.Default.Log(events.DeviceDisconnected, map[string]string{
|
||||
m.evLogger.Log(events.DeviceDisconnected, map[string]string{
|
||||
"id": device.String(),
|
||||
"error": err.Error(),
|
||||
})
|
||||
@@ -1773,7 +1776,7 @@ func (m *model) OnHello(remoteID protocol.DeviceID, addr net.Addr, hello protoco
|
||||
if !ok {
|
||||
m.cfg.AddOrUpdatePendingDevice(remoteID, hello.DeviceName, addr.String())
|
||||
_ = m.cfg.Save() // best effort
|
||||
events.Default.Log(events.DeviceRejected, map[string]string{
|
||||
m.evLogger.Log(events.DeviceRejected, map[string]string{
|
||||
"name": hello.DeviceName,
|
||||
"device": remoteID.String(),
|
||||
"address": addr.String(),
|
||||
@@ -1859,7 +1862,7 @@ func (m *model) AddConnection(conn connections.Connection, hello protocol.HelloR
|
||||
event["addr"] = addr.String()
|
||||
}
|
||||
|
||||
events.Default.Log(events.DeviceConnected, event)
|
||||
m.evLogger.Log(events.DeviceConnected, event)
|
||||
|
||||
l.Infof(`Device %s client is "%s %s" named "%s" at %s`, deviceID, hello.ClientName, hello.ClientVersion, hello.DeviceName, conn)
|
||||
|
||||
@@ -1894,7 +1897,7 @@ func (m *model) DownloadProgress(device protocol.DeviceID, folder string, update
|
||||
downloads.Update(folder, updates)
|
||||
state := downloads.GetBlockCounts(folder)
|
||||
|
||||
events.Default.Log(events.RemoteDownloadProgress, map[string]interface{}{
|
||||
m.evLogger.Log(events.RemoteDownloadProgress, map[string]interface{}{
|
||||
"device": device.String(),
|
||||
"folder": folder,
|
||||
"state": state,
|
||||
@@ -1926,6 +1929,7 @@ type indexSender struct {
|
||||
fset *db.FileSet
|
||||
prevSequence int64
|
||||
dropSymlinks bool
|
||||
evLogger events.Logger
|
||||
connClosed chan struct{}
|
||||
}
|
||||
|
||||
@@ -1941,8 +1945,8 @@ func (s *indexSender) serve(stop chan struct{}) {
|
||||
// Subscribe to LocalIndexUpdated (we have new information to send) and
|
||||
// DeviceDisconnected (it might be us who disconnected, so we should
|
||||
// exit).
|
||||
sub := events.Default.Subscribe(events.LocalIndexUpdated | events.DeviceDisconnected)
|
||||
defer events.Default.Unsubscribe(sub)
|
||||
sub := s.evLogger.Subscribe(events.LocalIndexUpdated | events.DeviceDisconnected)
|
||||
defer sub.Unsubscribe()
|
||||
|
||||
evChan := sub.C()
|
||||
ticker := time.NewTicker(time.Minute)
|
||||
@@ -2531,7 +2535,7 @@ func (m *model) CommitConfiguration(from, to config.Configuration) bool {
|
||||
if toCfg.Paused {
|
||||
eventType = events.FolderPaused
|
||||
}
|
||||
events.Default.Log(eventType, map[string]string{"id": toCfg.ID, "label": toCfg.Label})
|
||||
m.evLogger.Log(eventType, map[string]string{"id": toCfg.ID, "label": toCfg.Label})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2559,9 +2563,9 @@ func (m *model) CommitConfiguration(from, to config.Configuration) bool {
|
||||
if toCfg.Paused {
|
||||
l.Infoln("Pausing", deviceID)
|
||||
m.closeConn(deviceID, errDevicePaused)
|
||||
events.Default.Log(events.DevicePaused, map[string]string{"device": deviceID.String()})
|
||||
m.evLogger.Log(events.DevicePaused, map[string]string{"device": deviceID.String()})
|
||||
} else {
|
||||
events.Default.Log(events.DeviceResumed, map[string]string{"device": deviceID.String()})
|
||||
m.evLogger.Log(events.DeviceResumed, map[string]string{"device": deviceID.String()})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -110,7 +110,7 @@ func createTmpWrapper(cfg config.Configuration) config.Wrapper {
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
wrapper := config.Wrap(tmpFile.Name(), cfg)
|
||||
wrapper := config.Wrap(tmpFile.Name(), cfg, events.NoopLogger)
|
||||
tmpFile.Close()
|
||||
return wrapper
|
||||
}
|
||||
@@ -303,7 +303,7 @@ func TestDeviceRename(t *testing.T) {
|
||||
DeviceID: device1,
|
||||
},
|
||||
}
|
||||
cfg := config.Wrap("testdata/tmpconfig.xml", rawCfg)
|
||||
cfg := config.Wrap("testdata/tmpconfig.xml", rawCfg, events.NoopLogger)
|
||||
|
||||
db := db.OpenMemory()
|
||||
m := newModel(cfg, myID, "syncthing", "dev", db, nil)
|
||||
@@ -339,7 +339,7 @@ func TestDeviceRename(t *testing.T) {
|
||||
t.Errorf("Device name got overwritten")
|
||||
}
|
||||
|
||||
cfgw, err := config.Load("testdata/tmpconfig.xml", myID)
|
||||
cfgw, err := config.Load("testdata/tmpconfig.xml", myID, events.NoopLogger)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
@@ -3358,12 +3358,12 @@ func TestModTimeWindow(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestDevicePause(t *testing.T) {
|
||||
sub := events.Default.Subscribe(events.DevicePaused)
|
||||
defer events.Default.Unsubscribe(sub)
|
||||
|
||||
m, _, fcfg := setupModelWithConnection()
|
||||
defer cleanupModelAndRemoveDir(m, fcfg.Filesystem().URI())
|
||||
|
||||
sub := m.evLogger.Subscribe(events.DevicePaused)
|
||||
defer sub.Unsubscribe()
|
||||
|
||||
m.pmut.RLock()
|
||||
closed := m.closed[device1]
|
||||
m.pmut.RUnlock()
|
||||
|
||||
@@ -29,6 +29,7 @@ type ProgressEmitter struct {
|
||||
connections map[protocol.DeviceID]protocol.Connection
|
||||
foldersByConns map[protocol.DeviceID][]string
|
||||
disabled bool
|
||||
evLogger events.Logger
|
||||
mut sync.Mutex
|
||||
|
||||
timer *time.Timer
|
||||
@@ -36,13 +37,14 @@ type ProgressEmitter struct {
|
||||
|
||||
// NewProgressEmitter creates a new progress emitter which emits
|
||||
// DownloadProgress events every interval.
|
||||
func NewProgressEmitter(cfg config.Wrapper) *ProgressEmitter {
|
||||
func NewProgressEmitter(cfg config.Wrapper, evLogger events.Logger) *ProgressEmitter {
|
||||
t := &ProgressEmitter{
|
||||
registry: make(map[string]map[string]*sharedPullerState),
|
||||
timer: time.NewTimer(time.Millisecond),
|
||||
sentDownloadStates: make(map[protocol.DeviceID]*sentDownloadState),
|
||||
connections: make(map[protocol.DeviceID]protocol.Connection),
|
||||
foldersByConns: make(map[protocol.DeviceID][]string),
|
||||
evLogger: evLogger,
|
||||
mut: sync.NewMutex(),
|
||||
}
|
||||
t.Service = util.AsService(t.serve)
|
||||
@@ -107,7 +109,7 @@ func (t *ProgressEmitter) sendDownloadProgressEventLocked() {
|
||||
output[folder][name] = puller.Progress()
|
||||
}
|
||||
}
|
||||
events.Default.Log(events.DownloadProgress, output)
|
||||
t.evLogger.Log(events.DownloadProgress, output)
|
||||
l.Debugf("progress emitter: emitting %#v", output)
|
||||
}
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ func caller(skip int) string {
|
||||
return fmt.Sprintf("%s:%d", filepath.Base(file), line)
|
||||
}
|
||||
|
||||
func expectEvent(w *events.Subscription, t *testing.T, size int) {
|
||||
func expectEvent(w events.Subscription, t *testing.T, size int) {
|
||||
event, err := w.Poll(timeout)
|
||||
if err != nil {
|
||||
t.Fatal("Unexpected error:", err, "at", caller(1))
|
||||
@@ -44,7 +44,7 @@ func expectEvent(w *events.Subscription, t *testing.T, size int) {
|
||||
}
|
||||
}
|
||||
|
||||
func expectTimeout(w *events.Subscription, t *testing.T) {
|
||||
func expectTimeout(w events.Subscription, t *testing.T) {
|
||||
_, err := w.Poll(timeout)
|
||||
if err != events.ErrTimeout {
|
||||
t.Fatal("Unexpected non-Timeout error:", err, "at", caller(1))
|
||||
@@ -52,7 +52,11 @@ func expectTimeout(w *events.Subscription, t *testing.T) {
|
||||
}
|
||||
|
||||
func TestProgressEmitter(t *testing.T) {
|
||||
w := events.Default.Subscribe(events.DownloadProgress)
|
||||
evLogger := events.NewLogger()
|
||||
go evLogger.Serve()
|
||||
defer evLogger.Stop()
|
||||
|
||||
w := evLogger.Subscribe(events.DownloadProgress)
|
||||
|
||||
c := createTmpWrapper(config.Configuration{})
|
||||
defer os.Remove(c.ConfigPath())
|
||||
@@ -60,7 +64,7 @@ func TestProgressEmitter(t *testing.T) {
|
||||
ProgressUpdateIntervalS: 0,
|
||||
})
|
||||
|
||||
p := NewProgressEmitter(c)
|
||||
p := NewProgressEmitter(c, evLogger)
|
||||
go p.Serve()
|
||||
p.interval = 0
|
||||
|
||||
@@ -112,7 +116,11 @@ func TestSendDownloadProgressMessages(t *testing.T) {
|
||||
|
||||
fc := &fakeConnection{}
|
||||
|
||||
p := NewProgressEmitter(c)
|
||||
evLogger := events.NewLogger()
|
||||
go evLogger.Serve()
|
||||
defer evLogger.Stop()
|
||||
|
||||
p := NewProgressEmitter(c, evLogger)
|
||||
p.temporaryIndexSubscribe(fc, []string{"folder", "folder2"})
|
||||
p.registry["folder"] = make(map[string]*sharedPullerState)
|
||||
p.registry["folder2"] = make(map[string]*sharedPullerState)
|
||||
|
||||
@@ -350,8 +350,8 @@ func pullInvalidIgnored(t *testing.T, ft config.FolderType) {
|
||||
}
|
||||
fc.mut.Unlock()
|
||||
|
||||
sub := events.Default.Subscribe(events.FolderErrors)
|
||||
defer events.Default.Unsubscribe(sub)
|
||||
sub := m.evLogger.Subscribe(events.FolderErrors)
|
||||
defer sub.Unsubscribe()
|
||||
|
||||
fc.sendIndexUpdate()
|
||||
|
||||
@@ -640,8 +640,8 @@ func TestRequestSymlinkWindows(t *testing.T) {
|
||||
t.Fatalf("timed out before pull was finished")
|
||||
}
|
||||
|
||||
sub := events.Default.Subscribe(events.StateChanged | events.LocalIndexUpdated)
|
||||
defer events.Default.Unsubscribe(sub)
|
||||
sub := m.evLogger.Subscribe(events.StateChanged | events.LocalIndexUpdated)
|
||||
defer sub.Unsubscribe()
|
||||
|
||||
m.ScanFolder("default")
|
||||
|
||||
@@ -978,8 +978,8 @@ func TestNeedFolderFiles(t *testing.T) {
|
||||
tmpDir := tfs.URI()
|
||||
defer cleanupModelAndRemoveDir(m, tmpDir)
|
||||
|
||||
sub := events.Default.Subscribe(events.RemoteIndexUpdated)
|
||||
defer events.Default.Unsubscribe(sub)
|
||||
sub := m.evLogger.Subscribe(events.RemoteIndexUpdated)
|
||||
defer sub.Unsubscribe()
|
||||
|
||||
errPreventSync := errors.New("you aren't getting any of this")
|
||||
fc.mut.Lock()
|
||||
|
||||
@@ -13,6 +13,7 @@ import (
|
||||
|
||||
"github.com/syncthing/syncthing/lib/config"
|
||||
"github.com/syncthing/syncthing/lib/db"
|
||||
"github.com/syncthing/syncthing/lib/events"
|
||||
"github.com/syncthing/syncthing/lib/fs"
|
||||
"github.com/syncthing/syncthing/lib/protocol"
|
||||
)
|
||||
@@ -117,12 +118,16 @@ func setupModel(w config.Wrapper) *model {
|
||||
}
|
||||
|
||||
func newModel(cfg config.Wrapper, id protocol.DeviceID, clientName, clientVersion string, ldb *db.Lowlevel, protectedFiles []string) *model {
|
||||
return NewModel(cfg, id, clientName, clientVersion, ldb, protectedFiles).(*model)
|
||||
evLogger := events.NewLogger()
|
||||
m := NewModel(cfg, id, clientName, clientVersion, ldb, protectedFiles, evLogger).(*model)
|
||||
go evLogger.Serve()
|
||||
return m
|
||||
}
|
||||
|
||||
func cleanupModel(m *model) {
|
||||
m.Stop()
|
||||
m.db.Close()
|
||||
m.evLogger.Stop()
|
||||
os.Remove(m.cfg.ConfigPath())
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user