mirror of
https://github.com/octoleo/syncthing.git
synced 2024-11-17 10:35:11 +00:00
lib/model: Clarify master terminology (fixes #2679)
GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/3793
This commit is contained in:
parent
542b76f687
commit
398c356f22
1
AUTHORS
1
AUTHORS
@ -48,6 +48,7 @@ Felix Unterpaintner (bigbear2nd) <bigbear2nd@gmail.com>
|
|||||||
Francois-Xavier Gsell (zukoo) <fxgsell@gmail.com>
|
Francois-Xavier Gsell (zukoo) <fxgsell@gmail.com>
|
||||||
Frank Isemann (fti7) <frank@isemann.name>
|
Frank Isemann (fti7) <frank@isemann.name>
|
||||||
Gilli Sigurdsson (gillisig) <gilli@vx.is>
|
Gilli Sigurdsson (gillisig) <gilli@vx.is>
|
||||||
|
Heiko Zuerker (Smiley73) <heiko@zuerker.org>
|
||||||
Jaakko Hannikainen (jgke) <jgke@jgke.fi>
|
Jaakko Hannikainen (jgke) <jgke@jgke.fi>
|
||||||
Jacek Szafarkiewicz (hadogenes) <szafar@linux.pl>
|
Jacek Szafarkiewicz (hadogenes) <szafar@linux.pl>
|
||||||
Jake Peterson (acogdev) <jake@acogdev.com>
|
Jake Peterson (acogdev) <jake@acogdev.com>
|
||||||
|
1
NICKS
1
NICKS
@ -101,6 +101,7 @@ sciurius <jvromans@squirrel.nl>
|
|||||||
seehuhn <voss@seehuhn.de>
|
seehuhn <voss@seehuhn.de>
|
||||||
simplypeachy <aD@simplypeachy.co.uk>
|
simplypeachy <aD@simplypeachy.co.uk>
|
||||||
simplypeachy <simplypeachy@users.noreply.github.com>
|
simplypeachy <simplypeachy@users.noreply.github.com>
|
||||||
|
Smiley73 <heiko@zuerker.org>
|
||||||
snnd <dw@risu.io>
|
snnd <dw@risu.io>
|
||||||
Stefan-Code <stefan.github@gmail.com>
|
Stefan-Code <stefan.github@gmail.com>
|
||||||
Stefan-Code <Stefan.github@gmail.com>
|
Stefan-Code <Stefan.github@gmail.com>
|
||||||
|
@ -134,7 +134,7 @@ func reportData(cfg configIntf, m modelIntf) map[string]interface{} {
|
|||||||
for _, cfg := range cfg.Folders() {
|
for _, cfg := range cfg.Folders() {
|
||||||
rescanIntvs = append(rescanIntvs, cfg.RescanIntervalS)
|
rescanIntvs = append(rescanIntvs, cfg.RescanIntervalS)
|
||||||
|
|
||||||
if cfg.Type == config.FolderTypeReadOnly {
|
if cfg.Type == config.FolderTypeSendOnly {
|
||||||
folderUses["readonly"]++
|
folderUses["readonly"]++
|
||||||
}
|
}
|
||||||
if cfg.IgnorePerms {
|
if cfg.IgnorePerms {
|
||||||
|
@ -354,7 +354,7 @@
|
|||||||
<tr ng-if="folder.type != 'readwrite'">
|
<tr ng-if="folder.type != 'readwrite'">
|
||||||
<th><span class="fa fa-fw fa-lock"></span> <span translate>Folder Type</span></th>
|
<th><span class="fa fa-fw fa-lock"></span> <span translate>Folder Type</span></th>
|
||||||
<td class="text-right">
|
<td class="text-right">
|
||||||
<span ng-if="folder.type == 'readonly'" translate>Master</span>
|
<span ng-if="folder.type == 'readonly'" translate>Send Only</span>
|
||||||
<span ng-if="folder.type != 'readonly'">{{ folder.type.charAt(0).toUpperCase() + folder.type.slice(1) }}</span>
|
<span ng-if="folder.type != 'readonly'">{{ folder.type.charAt(0).toUpperCase() + folder.type.slice(1) }}</span>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -86,8 +86,8 @@
|
|||||||
<label translate>Folder Type</label>
|
<label translate>Folder Type</label>
|
||||||
<a href="https://docs.syncthing.net/users/foldermaster.html" target="_blank"><span class="fa fa-book"></span> <span translate>Help</span></a>
|
<a href="https://docs.syncthing.net/users/foldermaster.html" target="_blank"><span class="fa fa-book"></span> <span translate>Help</span></a>
|
||||||
<select class="form-control" ng-model="currentFolder.type">
|
<select class="form-control" ng-model="currentFolder.type">
|
||||||
<option value="readwrite" translate>Normal</option>
|
<option value="readwrite" translate>Send & Receive</option>
|
||||||
<option value="readonly" translate>Master</option>
|
<option value="readonly" translate>Send Only</option>
|
||||||
</select>
|
</select>
|
||||||
<p ng-if="currentFolder.type == 'readonly'" translate class="help-block">Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.</p>
|
<p ng-if="currentFolder.type == 'readonly'" translate class="help-block">Files are protected from changes made on other devices, but changes made on this device will be sent to the rest of the cluster.</p>
|
||||||
</div>
|
</div>
|
||||||
|
@ -407,9 +407,9 @@ func convertV13V14(cfg *Configuration) {
|
|||||||
|
|
||||||
for i, fcfg := range cfg.Folders {
|
for i, fcfg := range cfg.Folders {
|
||||||
if fcfg.DeprecatedReadOnly {
|
if fcfg.DeprecatedReadOnly {
|
||||||
cfg.Folders[i].Type = FolderTypeReadOnly
|
cfg.Folders[i].Type = FolderTypeSendOnly
|
||||||
} else {
|
} else {
|
||||||
cfg.Folders[i].Type = FolderTypeReadWrite
|
cfg.Folders[i].Type = FolderTypeSendReceive
|
||||||
}
|
}
|
||||||
cfg.Folders[i].DeprecatedReadOnly = false
|
cfg.Folders[i].DeprecatedReadOnly = false
|
||||||
}
|
}
|
||||||
|
@ -96,7 +96,7 @@ func TestDeviceConfig(t *testing.T) {
|
|||||||
ID: "test",
|
ID: "test",
|
||||||
RawPath: "testdata",
|
RawPath: "testdata",
|
||||||
Devices: []FolderDeviceConfiguration{{DeviceID: device1}, {DeviceID: device4}},
|
Devices: []FolderDeviceConfiguration{{DeviceID: device1}, {DeviceID: device4}},
|
||||||
Type: FolderTypeReadOnly,
|
Type: FolderTypeSendOnly,
|
||||||
RescanIntervalS: 600,
|
RescanIntervalS: 600,
|
||||||
Copiers: 0,
|
Copiers: 0,
|
||||||
Pullers: 0,
|
Pullers: 0,
|
||||||
|
@ -9,15 +9,15 @@ package config
|
|||||||
type FolderType int
|
type FolderType int
|
||||||
|
|
||||||
const (
|
const (
|
||||||
FolderTypeReadWrite FolderType = iota // default is readwrite
|
FolderTypeSendReceive FolderType = iota // default is sendreceive
|
||||||
FolderTypeReadOnly
|
FolderTypeSendOnly
|
||||||
)
|
)
|
||||||
|
|
||||||
func (t FolderType) String() string {
|
func (t FolderType) String() string {
|
||||||
switch t {
|
switch t {
|
||||||
case FolderTypeReadWrite:
|
case FolderTypeSendReceive:
|
||||||
return "readwrite"
|
return "readwrite"
|
||||||
case FolderTypeReadOnly:
|
case FolderTypeSendOnly:
|
||||||
return "readonly"
|
return "readonly"
|
||||||
default:
|
default:
|
||||||
return "unknown"
|
return "unknown"
|
||||||
@ -30,12 +30,12 @@ func (t FolderType) MarshalText() ([]byte, error) {
|
|||||||
|
|
||||||
func (t *FolderType) UnmarshalText(bs []byte) error {
|
func (t *FolderType) UnmarshalText(bs []byte) error {
|
||||||
switch string(bs) {
|
switch string(bs) {
|
||||||
case "readwrite":
|
case "readwrite", "sendreceive":
|
||||||
*t = FolderTypeReadWrite
|
*t = FolderTypeSendReceive
|
||||||
case "readonly":
|
case "readonly", "sendonly":
|
||||||
*t = FolderTypeReadOnly
|
*t = FolderTypeSendOnly
|
||||||
default:
|
default:
|
||||||
*t = FolderTypeReadWrite
|
*t = FolderTypeSendReceive
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -264,7 +264,7 @@ func (m *Model) startFolderLocked(folder string) config.FolderType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *Model) warnAboutOverwritingProtectedFiles(folder string) {
|
func (m *Model) warnAboutOverwritingProtectedFiles(folder string) {
|
||||||
if m.folderCfgs[folder].Type == config.FolderTypeReadOnly {
|
if m.folderCfgs[folder].Type == config.FolderTypeSendOnly {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1371,7 +1371,7 @@ func (m *Model) DownloadProgress(device protocol.DeviceID, folder string, update
|
|||||||
cfg, ok := m.folderCfgs[folder]
|
cfg, ok := m.folderCfgs[folder]
|
||||||
m.fmut.RUnlock()
|
m.fmut.RUnlock()
|
||||||
|
|
||||||
if !ok || cfg.Type == config.FolderTypeReadOnly || cfg.DisableTempIndexes {
|
if !ok || cfg.Type == config.FolderTypeSendOnly || cfg.DisableTempIndexes {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1955,7 +1955,7 @@ func (m *Model) generateClusterConfig(device protocol.DeviceID) protocol.Cluster
|
|||||||
protocolFolder := protocol.Folder{
|
protocolFolder := protocol.Folder{
|
||||||
ID: folder,
|
ID: folder,
|
||||||
Label: folderCfg.Label,
|
Label: folderCfg.Label,
|
||||||
ReadOnly: folderCfg.Type == config.FolderTypeReadOnly,
|
ReadOnly: folderCfg.Type == config.FolderTypeSendOnly,
|
||||||
IgnorePermissions: folderCfg.IgnorePerms,
|
IgnorePermissions: folderCfg.IgnorePerms,
|
||||||
IgnoreDelete: folderCfg.IgnoreDelete,
|
IgnoreDelete: folderCfg.IgnoreDelete,
|
||||||
DisableTempIndexes: folderCfg.DisableTempIndexes,
|
DisableTempIndexes: folderCfg.DisableTempIndexes,
|
||||||
|
@ -1028,7 +1028,7 @@ func TestROScanRecovery(t *testing.T) {
|
|||||||
fcfg := config.FolderConfiguration{
|
fcfg := config.FolderConfiguration{
|
||||||
ID: "default",
|
ID: "default",
|
||||||
RawPath: "testdata/rotestfolder",
|
RawPath: "testdata/rotestfolder",
|
||||||
Type: config.FolderTypeReadOnly,
|
Type: config.FolderTypeSendOnly,
|
||||||
RescanIntervalS: 1,
|
RescanIntervalS: 1,
|
||||||
}
|
}
|
||||||
cfg := config.Wrap("/tmp/test", config.Configuration{
|
cfg := config.Wrap("/tmp/test", config.Configuration{
|
||||||
@ -1115,7 +1115,7 @@ func TestRWScanRecovery(t *testing.T) {
|
|||||||
fcfg := config.FolderConfiguration{
|
fcfg := config.FolderConfiguration{
|
||||||
ID: "default",
|
ID: "default",
|
||||||
RawPath: "testdata/rwtestfolder",
|
RawPath: "testdata/rwtestfolder",
|
||||||
Type: config.FolderTypeReadWrite,
|
Type: config.FolderTypeSendReceive,
|
||||||
RescanIntervalS: 1,
|
RescanIntervalS: 1,
|
||||||
}
|
}
|
||||||
cfg := config.Wrap("/tmp/test", config.Configuration{
|
cfg := config.Wrap("/tmp/test", config.Configuration{
|
||||||
@ -1763,11 +1763,11 @@ func TestIssue3028(t *testing.T) {
|
|||||||
m.StartFolder("default")
|
m.StartFolder("default")
|
||||||
m.ServeBackground()
|
m.ServeBackground()
|
||||||
|
|
||||||
// Ugly hack for testing: reach into the model for the rwfolder and wait
|
// Ugly hack for testing: reach into the model for the SendReceiveFolder and wait
|
||||||
// for it to complete the initial scan. The risk is that it otherwise
|
// for it to complete the initial scan. The risk is that it otherwise
|
||||||
// runs during our modifications and screws up the test.
|
// runs during our modifications and screws up the test.
|
||||||
m.fmut.RLock()
|
m.fmut.RLock()
|
||||||
folder := m.folderRunners["default"].(*rwFolder)
|
folder := m.folderRunners["default"].(*sendReceiveFolder)
|
||||||
m.fmut.RUnlock()
|
m.fmut.RUnlock()
|
||||||
<-folder.initialScanCompleted
|
<-folder.initialScanCompleted
|
||||||
|
|
||||||
@ -1822,7 +1822,7 @@ func TestIssue3164(t *testing.T) {
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
fl := rwFolder{
|
fl := sendReceiveFolder{
|
||||||
dbUpdates: make(chan dbUpdateJob, 1),
|
dbUpdates: make(chan dbUpdateJob, 1),
|
||||||
dir: "testdata",
|
dir: "testdata",
|
||||||
}
|
}
|
||||||
|
@ -15,15 +15,15 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
folderFactories[config.FolderTypeReadOnly] = newROFolder
|
folderFactories[config.FolderTypeSendOnly] = newSendOnlyFolder
|
||||||
}
|
}
|
||||||
|
|
||||||
type roFolder struct {
|
type sendOnlyFolder struct {
|
||||||
folder
|
folder
|
||||||
}
|
}
|
||||||
|
|
||||||
func newROFolder(model *Model, cfg config.FolderConfiguration, _ versioner.Versioner, _ *fs.MtimeFS) service {
|
func newSendOnlyFolder(model *Model, cfg config.FolderConfiguration, _ versioner.Versioner, _ *fs.MtimeFS) service {
|
||||||
return &roFolder{
|
return &sendOnlyFolder{
|
||||||
folder: folder{
|
folder: folder{
|
||||||
stateTracker: newStateTracker(cfg.ID),
|
stateTracker: newStateTracker(cfg.ID),
|
||||||
scan: newFolderScanner(cfg),
|
scan: newFolderScanner(cfg),
|
||||||
@ -33,7 +33,7 @@ func newROFolder(model *Model, cfg config.FolderConfiguration, _ versioner.Versi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *roFolder) Serve() {
|
func (f *sendOnlyFolder) Serve() {
|
||||||
l.Debugln(f, "starting")
|
l.Debugln(f, "starting")
|
||||||
defer l.Debugln(f, "exiting")
|
defer l.Debugln(f, "exiting")
|
||||||
|
|
||||||
@ -86,6 +86,6 @@ func (f *roFolder) Serve() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *roFolder) String() string {
|
func (f *sendOnlyFolder) String() string {
|
||||||
return fmt.Sprintf("roFolder/%s@%p", f.folderID, f)
|
return fmt.Sprintf("sendOnlyFolder/%s@%p", f.folderID, f)
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
folderFactories[config.FolderTypeReadWrite] = newRWFolder
|
folderFactories[config.FolderTypeSendReceive] = newSendReceiveFolder
|
||||||
}
|
}
|
||||||
|
|
||||||
// A pullBlockState is passed to the puller routine for each block that needs
|
// A pullBlockState is passed to the puller routine for each block that needs
|
||||||
@ -78,7 +78,7 @@ type dbUpdateJob struct {
|
|||||||
jobType int
|
jobType int
|
||||||
}
|
}
|
||||||
|
|
||||||
type rwFolder struct {
|
type sendReceiveFolder struct {
|
||||||
folder
|
folder
|
||||||
|
|
||||||
mtimeFS *fs.MtimeFS
|
mtimeFS *fs.MtimeFS
|
||||||
@ -109,8 +109,8 @@ type rwFolder struct {
|
|||||||
initialScanCompleted chan (struct{}) // exposed for testing
|
initialScanCompleted chan (struct{}) // exposed for testing
|
||||||
}
|
}
|
||||||
|
|
||||||
func newRWFolder(model *Model, cfg config.FolderConfiguration, ver versioner.Versioner, mtimeFS *fs.MtimeFS) service {
|
func newSendReceiveFolder(model *Model, cfg config.FolderConfiguration, ver versioner.Versioner, mtimeFS *fs.MtimeFS) service {
|
||||||
f := &rwFolder{
|
f := &sendReceiveFolder{
|
||||||
folder: folder{
|
folder: folder{
|
||||||
stateTracker: newStateTracker(cfg.ID),
|
stateTracker: newStateTracker(cfg.ID),
|
||||||
scan: newFolderScanner(cfg),
|
scan: newFolderScanner(cfg),
|
||||||
@ -146,7 +146,7 @@ func newRWFolder(model *Model, cfg config.FolderConfiguration, ver versioner.Ver
|
|||||||
return f
|
return f
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *rwFolder) configureCopiersAndPullers(cfg config.FolderConfiguration) {
|
func (f *sendReceiveFolder) configureCopiersAndPullers(cfg config.FolderConfiguration) {
|
||||||
if f.copiers == 0 {
|
if f.copiers == 0 {
|
||||||
f.copiers = defaultCopiers
|
f.copiers = defaultCopiers
|
||||||
}
|
}
|
||||||
@ -170,13 +170,13 @@ func (f *rwFolder) configureCopiersAndPullers(cfg config.FolderConfiguration) {
|
|||||||
// Helper function to check whether either the ignorePerm flag has been
|
// Helper function to check whether either the ignorePerm flag has been
|
||||||
// set on the local host or the FlagNoPermBits has been set on the file/dir
|
// set on the local host or the FlagNoPermBits has been set on the file/dir
|
||||||
// which is being pulled.
|
// which is being pulled.
|
||||||
func (f *rwFolder) ignorePermissions(file protocol.FileInfo) bool {
|
func (f *sendReceiveFolder) ignorePermissions(file protocol.FileInfo) bool {
|
||||||
return f.ignorePerms || file.NoPermissions
|
return f.ignorePerms || file.NoPermissions
|
||||||
}
|
}
|
||||||
|
|
||||||
// Serve will run scans and pulls. It will return when Stop()ed or on a
|
// Serve will run scans and pulls. It will return when Stop()ed or on a
|
||||||
// critical error.
|
// critical error.
|
||||||
func (f *rwFolder) Serve() {
|
func (f *sendReceiveFolder) Serve() {
|
||||||
l.Debugln(f, "starting")
|
l.Debugln(f, "starting")
|
||||||
defer l.Debugln(f, "exiting")
|
defer l.Debugln(f, "exiting")
|
||||||
|
|
||||||
@ -317,7 +317,7 @@ func (f *rwFolder) Serve() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *rwFolder) IndexUpdated() {
|
func (f *sendReceiveFolder) IndexUpdated() {
|
||||||
select {
|
select {
|
||||||
case f.remoteIndex <- struct{}{}:
|
case f.remoteIndex <- struct{}{}:
|
||||||
default:
|
default:
|
||||||
@ -328,15 +328,15 @@ func (f *rwFolder) IndexUpdated() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *rwFolder) String() string {
|
func (f *sendReceiveFolder) String() string {
|
||||||
return fmt.Sprintf("rwFolder/%s@%p", f.folderID, f)
|
return fmt.Sprintf("sendReceiveFolder/%s@%p", f.folderID, f)
|
||||||
}
|
}
|
||||||
|
|
||||||
// pullerIteration runs a single puller iteration for the given folder and
|
// pullerIteration runs a single puller iteration for the given folder and
|
||||||
// returns the number items that should have been synced (even those that
|
// returns the number items that should have been synced (even those that
|
||||||
// might have failed). One puller iteration handles all files currently
|
// might have failed). One puller iteration handles all files currently
|
||||||
// flagged as needed in the folder.
|
// flagged as needed in the folder.
|
||||||
func (f *rwFolder) pullerIteration(ignores *ignore.Matcher) int {
|
func (f *sendReceiveFolder) pullerIteration(ignores *ignore.Matcher) int {
|
||||||
pullChan := make(chan pullBlockState)
|
pullChan := make(chan pullBlockState)
|
||||||
copyChan := make(chan copyBlocksState)
|
copyChan := make(chan copyBlocksState)
|
||||||
finisherChan := make(chan *sharedPullerState)
|
finisherChan := make(chan *sharedPullerState)
|
||||||
@ -603,7 +603,7 @@ nextFile:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// handleDir creates or updates the given directory
|
// handleDir creates or updates the given directory
|
||||||
func (f *rwFolder) handleDir(file protocol.FileInfo) {
|
func (f *sendReceiveFolder) handleDir(file protocol.FileInfo) {
|
||||||
// Used in the defer closure below, updated by the function body. Take
|
// Used in the defer closure below, updated by the function body. Take
|
||||||
// care not declare another err.
|
// care not declare another err.
|
||||||
var err error
|
var err error
|
||||||
@ -705,7 +705,7 @@ func (f *rwFolder) handleDir(file protocol.FileInfo) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// handleSymlink creates or updates the given symlink
|
// handleSymlink creates or updates the given symlink
|
||||||
func (f *rwFolder) handleSymlink(file protocol.FileInfo) {
|
func (f *sendReceiveFolder) handleSymlink(file protocol.FileInfo) {
|
||||||
// Used in the defer closure below, updated by the function body. Take
|
// Used in the defer closure below, updated by the function body. Take
|
||||||
// care not declare another err.
|
// care not declare another err.
|
||||||
var err error
|
var err error
|
||||||
@ -779,7 +779,7 @@ func (f *rwFolder) handleSymlink(file protocol.FileInfo) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// deleteDir attempts to delete the given directory
|
// deleteDir attempts to delete the given directory
|
||||||
func (f *rwFolder) deleteDir(file protocol.FileInfo, matcher *ignore.Matcher) {
|
func (f *sendReceiveFolder) deleteDir(file protocol.FileInfo, matcher *ignore.Matcher) {
|
||||||
// Used in the defer closure below, updated by the function body. Take
|
// Used in the defer closure below, updated by the function body. Take
|
||||||
// care not declare another err.
|
// care not declare another err.
|
||||||
var err error
|
var err error
|
||||||
@ -837,7 +837,7 @@ func (f *rwFolder) deleteDir(file protocol.FileInfo, matcher *ignore.Matcher) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// deleteFile attempts to delete the given file
|
// deleteFile attempts to delete the given file
|
||||||
func (f *rwFolder) deleteFile(file protocol.FileInfo) {
|
func (f *sendReceiveFolder) deleteFile(file protocol.FileInfo) {
|
||||||
// Used in the defer closure below, updated by the function body. Take
|
// Used in the defer closure below, updated by the function body. Take
|
||||||
// care not declare another err.
|
// care not declare another err.
|
||||||
var err error
|
var err error
|
||||||
@ -895,7 +895,7 @@ func (f *rwFolder) deleteFile(file protocol.FileInfo) {
|
|||||||
|
|
||||||
// renameFile attempts to rename an existing file to a destination
|
// renameFile attempts to rename an existing file to a destination
|
||||||
// and set the right attributes on it.
|
// and set the right attributes on it.
|
||||||
func (f *rwFolder) renameFile(source, target protocol.FileInfo) {
|
func (f *sendReceiveFolder) renameFile(source, target protocol.FileInfo) {
|
||||||
// Used in the defer closure below, updated by the function body. Take
|
// Used in the defer closure below, updated by the function body. Take
|
||||||
// care not declare another err.
|
// care not declare another err.
|
||||||
var err error
|
var err error
|
||||||
@ -1019,7 +1019,7 @@ func (f *rwFolder) renameFile(source, target protocol.FileInfo) {
|
|||||||
|
|
||||||
// handleFile queues the copies and pulls as necessary for a single new or
|
// handleFile queues the copies and pulls as necessary for a single new or
|
||||||
// changed file.
|
// changed file.
|
||||||
func (f *rwFolder) handleFile(file protocol.FileInfo, copyChan chan<- copyBlocksState, finisherChan chan<- *sharedPullerState) {
|
func (f *sendReceiveFolder) handleFile(file protocol.FileInfo, copyChan chan<- copyBlocksState, finisherChan chan<- *sharedPullerState) {
|
||||||
curFile, hasCurFile := f.model.CurrentFolderFile(f.folderID, file.Name)
|
curFile, hasCurFile := f.model.CurrentFolderFile(f.folderID, file.Name)
|
||||||
|
|
||||||
if hasCurFile && len(curFile.Blocks) == len(file.Blocks) && scanner.BlocksEqual(curFile.Blocks, file.Blocks) {
|
if hasCurFile && len(curFile.Blocks) == len(file.Blocks) && scanner.BlocksEqual(curFile.Blocks, file.Blocks) {
|
||||||
@ -1183,7 +1183,7 @@ func (f *rwFolder) handleFile(file protocol.FileInfo, copyChan chan<- copyBlocks
|
|||||||
|
|
||||||
// shortcutFile sets file mode and modification time, when that's the only
|
// shortcutFile sets file mode and modification time, when that's the only
|
||||||
// thing that has changed.
|
// thing that has changed.
|
||||||
func (f *rwFolder) shortcutFile(file protocol.FileInfo) error {
|
func (f *sendReceiveFolder) shortcutFile(file protocol.FileInfo) error {
|
||||||
realName, err := rootedJoinedPath(f.dir, file.Name)
|
realName, err := rootedJoinedPath(f.dir, file.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
f.newError(file.Name, err)
|
f.newError(file.Name, err)
|
||||||
@ -1210,7 +1210,7 @@ func (f *rwFolder) shortcutFile(file protocol.FileInfo) error {
|
|||||||
|
|
||||||
// copierRoutine reads copierStates until the in channel closes and performs
|
// copierRoutine reads copierStates until the in channel closes and performs
|
||||||
// the relevant copies when possible, or passes it to the puller routine.
|
// the relevant copies when possible, or passes it to the puller routine.
|
||||||
func (f *rwFolder) copierRoutine(in <-chan copyBlocksState, pullChan chan<- pullBlockState, out chan<- *sharedPullerState) {
|
func (f *sendReceiveFolder) copierRoutine(in <-chan copyBlocksState, pullChan chan<- pullBlockState, out chan<- *sharedPullerState) {
|
||||||
buf := make([]byte, protocol.BlockSize)
|
buf := make([]byte, protocol.BlockSize)
|
||||||
|
|
||||||
for state := range in {
|
for state := range in {
|
||||||
@ -1348,7 +1348,7 @@ func (f *rwFolder) copierRoutine(in <-chan copyBlocksState, pullChan chan<- pull
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *rwFolder) pullerRoutine(in <-chan pullBlockState, out chan<- *sharedPullerState) {
|
func (f *sendReceiveFolder) pullerRoutine(in <-chan pullBlockState, out chan<- *sharedPullerState) {
|
||||||
for state := range in {
|
for state := range in {
|
||||||
if state.failed() != nil {
|
if state.failed() != nil {
|
||||||
out <- state.sharedPullerState
|
out <- state.sharedPullerState
|
||||||
@ -1421,7 +1421,7 @@ func (f *rwFolder) pullerRoutine(in <-chan pullBlockState, out chan<- *sharedPul
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *rwFolder) performFinish(state *sharedPullerState) error {
|
func (f *sendReceiveFolder) performFinish(state *sharedPullerState) error {
|
||||||
// Set the correct permission bits on the new file
|
// Set the correct permission bits on the new file
|
||||||
if !f.ignorePermissions(state.file) {
|
if !f.ignorePermissions(state.file) {
|
||||||
if err := os.Chmod(state.tempName, os.FileMode(state.file.Permissions&0777)); err != nil {
|
if err := os.Chmod(state.tempName, os.FileMode(state.file.Permissions&0777)); err != nil {
|
||||||
@ -1483,7 +1483,7 @@ func (f *rwFolder) performFinish(state *sharedPullerState) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *rwFolder) finisherRoutine(in <-chan *sharedPullerState) {
|
func (f *sendReceiveFolder) finisherRoutine(in <-chan *sharedPullerState) {
|
||||||
for state := range in {
|
for state := range in {
|
||||||
if closed, err := state.finalClose(); closed {
|
if closed, err := state.finalClose(); closed {
|
||||||
l.Debugln(f, "closing", state.file.Name)
|
l.Debugln(f, "closing", state.file.Name)
|
||||||
@ -1514,17 +1514,17 @@ func (f *rwFolder) finisherRoutine(in <-chan *sharedPullerState) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Moves the given filename to the front of the job queue
|
// Moves the given filename to the front of the job queue
|
||||||
func (f *rwFolder) BringToFront(filename string) {
|
func (f *sendReceiveFolder) BringToFront(filename string) {
|
||||||
f.queue.BringToFront(filename)
|
f.queue.BringToFront(filename)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *rwFolder) Jobs() ([]string, []string) {
|
func (f *sendReceiveFolder) Jobs() ([]string, []string) {
|
||||||
return f.queue.Jobs()
|
return f.queue.Jobs()
|
||||||
}
|
}
|
||||||
|
|
||||||
// dbUpdaterRoutine aggregates db updates and commits them in batches no
|
// dbUpdaterRoutine aggregates db updates and commits them in batches no
|
||||||
// larger than 1000 items, and no more delayed than 2 seconds.
|
// larger than 1000 items, and no more delayed than 2 seconds.
|
||||||
func (f *rwFolder) dbUpdaterRoutine() {
|
func (f *sendReceiveFolder) dbUpdaterRoutine() {
|
||||||
const (
|
const (
|
||||||
maxBatchSize = 1000
|
maxBatchSize = 1000
|
||||||
maxBatchTime = 2 * time.Second
|
maxBatchTime = 2 * time.Second
|
||||||
@ -1635,7 +1635,7 @@ loop:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *rwFolder) inConflict(current, replacement protocol.Vector) bool {
|
func (f *sendReceiveFolder) inConflict(current, replacement protocol.Vector) bool {
|
||||||
if current.Concurrent(replacement) {
|
if current.Concurrent(replacement) {
|
||||||
// Obvious case
|
// Obvious case
|
||||||
return true
|
return true
|
||||||
@ -1661,7 +1661,7 @@ func removeAvailability(availabilities []Availability, availability Availability
|
|||||||
return availabilities
|
return availabilities
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *rwFolder) moveForConflict(name string) error {
|
func (f *sendReceiveFolder) moveForConflict(name string) error {
|
||||||
if strings.Contains(filepath.Base(name), ".sync-conflict-") {
|
if strings.Contains(filepath.Base(name), ".sync-conflict-") {
|
||||||
l.Infoln("Conflict for", name, "which is already a conflict copy; not copying again.")
|
l.Infoln("Conflict for", name, "which is already a conflict copy; not copying again.")
|
||||||
if err := os.Remove(name); err != nil && !os.IsNotExist(err) {
|
if err := os.Remove(name); err != nil && !os.IsNotExist(err) {
|
||||||
@ -1705,7 +1705,7 @@ func (f *rwFolder) moveForConflict(name string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *rwFolder) newError(path string, err error) {
|
func (f *sendReceiveFolder) newError(path string, err error) {
|
||||||
f.errorsMut.Lock()
|
f.errorsMut.Lock()
|
||||||
defer f.errorsMut.Unlock()
|
defer f.errorsMut.Unlock()
|
||||||
|
|
||||||
@ -1719,13 +1719,13 @@ func (f *rwFolder) newError(path string, err error) {
|
|||||||
f.errors[path] = err.Error()
|
f.errors[path] = err.Error()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *rwFolder) clearErrors() {
|
func (f *sendReceiveFolder) clearErrors() {
|
||||||
f.errorsMut.Lock()
|
f.errorsMut.Lock()
|
||||||
f.errors = make(map[string]string)
|
f.errors = make(map[string]string)
|
||||||
f.errorsMut.Unlock()
|
f.errorsMut.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *rwFolder) currentErrors() []fileError {
|
func (f *sendReceiveFolder) currentErrors() []fileError {
|
||||||
f.errorsMut.Lock()
|
f.errorsMut.Lock()
|
||||||
errors := make([]fileError, 0, len(f.errors))
|
errors := make([]fileError, 0, len(f.errors))
|
||||||
for path, err := range f.errors {
|
for path, err := range f.errors {
|
||||||
|
@ -69,8 +69,8 @@ func setUpModel(file protocol.FileInfo) *Model {
|
|||||||
return model
|
return model
|
||||||
}
|
}
|
||||||
|
|
||||||
func setUpRwFolder(model *Model) rwFolder {
|
func setUpSendReceiveFolder(model *Model) sendReceiveFolder {
|
||||||
return rwFolder{
|
return sendReceiveFolder{
|
||||||
folder: folder{
|
folder: folder{
|
||||||
stateTracker: newStateTracker("default"),
|
stateTracker: newStateTracker("default"),
|
||||||
model: model,
|
model: model,
|
||||||
@ -100,7 +100,7 @@ func TestHandleFile(t *testing.T) {
|
|||||||
requiredFile.Blocks = blocks[1:]
|
requiredFile.Blocks = blocks[1:]
|
||||||
|
|
||||||
m := setUpModel(existingFile)
|
m := setUpModel(existingFile)
|
||||||
f := setUpRwFolder(m)
|
f := setUpSendReceiveFolder(m)
|
||||||
copyChan := make(chan copyBlocksState, 1)
|
copyChan := make(chan copyBlocksState, 1)
|
||||||
|
|
||||||
f.handleFile(requiredFile, copyChan, nil)
|
f.handleFile(requiredFile, copyChan, nil)
|
||||||
@ -141,7 +141,7 @@ func TestHandleFileWithTemp(t *testing.T) {
|
|||||||
requiredFile.Blocks = blocks[1:]
|
requiredFile.Blocks = blocks[1:]
|
||||||
|
|
||||||
m := setUpModel(existingFile)
|
m := setUpModel(existingFile)
|
||||||
f := setUpRwFolder(m)
|
f := setUpSendReceiveFolder(m)
|
||||||
copyChan := make(chan copyBlocksState, 1)
|
copyChan := make(chan copyBlocksState, 1)
|
||||||
|
|
||||||
f.handleFile(requiredFile, copyChan, nil)
|
f.handleFile(requiredFile, copyChan, nil)
|
||||||
@ -189,7 +189,7 @@ func TestCopierFinder(t *testing.T) {
|
|||||||
requiredFile.Name = "file2"
|
requiredFile.Name = "file2"
|
||||||
|
|
||||||
m := setUpModel(existingFile)
|
m := setUpModel(existingFile)
|
||||||
f := setUpRwFolder(m)
|
f := setUpSendReceiveFolder(m)
|
||||||
copyChan := make(chan copyBlocksState)
|
copyChan := make(chan copyBlocksState)
|
||||||
pullChan := make(chan pullBlockState, 4)
|
pullChan := make(chan pullBlockState, 4)
|
||||||
finisherChan := make(chan *sharedPullerState, 1)
|
finisherChan := make(chan *sharedPullerState, 1)
|
||||||
@ -313,7 +313,7 @@ func TestWeakHash(t *testing.T) {
|
|||||||
|
|
||||||
// Setup the model/pull environment
|
// Setup the model/pull environment
|
||||||
m := setUpModel(existingFile)
|
m := setUpModel(existingFile)
|
||||||
fo := setUpRwFolder(m)
|
fo := setUpSendReceiveFolder(m)
|
||||||
copyChan := make(chan copyBlocksState)
|
copyChan := make(chan copyBlocksState)
|
||||||
pullChan := make(chan pullBlockState, expectBlocks)
|
pullChan := make(chan pullBlockState, expectBlocks)
|
||||||
finisherChan := make(chan *sharedPullerState, 1)
|
finisherChan := make(chan *sharedPullerState, 1)
|
||||||
@ -424,7 +424,7 @@ func TestLastResortPulling(t *testing.T) {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
f := setUpRwFolder(m)
|
f := setUpSendReceiveFolder(m)
|
||||||
|
|
||||||
copyChan := make(chan copyBlocksState)
|
copyChan := make(chan copyBlocksState)
|
||||||
pullChan := make(chan pullBlockState, 1)
|
pullChan := make(chan pullBlockState, 1)
|
||||||
@ -462,7 +462,7 @@ func TestDeregisterOnFailInCopy(t *testing.T) {
|
|||||||
m := NewModel(defaultConfig, protocol.LocalDeviceID, "device", "syncthing", "dev", db, nil)
|
m := NewModel(defaultConfig, protocol.LocalDeviceID, "device", "syncthing", "dev", db, nil)
|
||||||
m.AddFolder(defaultFolderConfig)
|
m.AddFolder(defaultFolderConfig)
|
||||||
|
|
||||||
f := setUpRwFolder(m)
|
f := setUpSendReceiveFolder(m)
|
||||||
|
|
||||||
// queue.Done should be called by the finisher routine
|
// queue.Done should be called by the finisher routine
|
||||||
f.queue.Push("filex", 0, time.Time{})
|
f.queue.Push("filex", 0, time.Time{})
|
||||||
@ -535,7 +535,7 @@ func TestDeregisterOnFailInPull(t *testing.T) {
|
|||||||
m := NewModel(defaultConfig, protocol.LocalDeviceID, "device", "syncthing", "dev", db, nil)
|
m := NewModel(defaultConfig, protocol.LocalDeviceID, "device", "syncthing", "dev", db, nil)
|
||||||
m.AddFolder(defaultFolderConfig)
|
m.AddFolder(defaultFolderConfig)
|
||||||
|
|
||||||
f := setUpRwFolder(m)
|
f := setUpSendReceiveFolder(m)
|
||||||
|
|
||||||
// queue.Done should be called by the finisher routine
|
// queue.Done should be called by the finisher routine
|
||||||
f.queue.Push("filex", 0, time.Time{})
|
f.queue.Push("filex", 0, time.Time{})
|
||||||
|
Loading…
Reference in New Issue
Block a user