all: Add folder pause, make pauses optionally permanent (fixes #3407, fixes #215, fixes #3001)#3520
all: Add folder pause, make pauses optionally permanent (fixes #3407, fixes #215, fixes #3001)#3520AudriusButkevicius wants to merge 10 commits intosyncthing:masterfrom
Conversation
4842840 to
4df5c77
Compare
|
+122 −116 - 2 features in 6 lines. If we'd exclude the test changes, that'd be less. |
|
This will screw up many, many things on my side. In particular, I use device pausing and unpausing to disable devices which are connected to over a metered connection. I use the endpoints and events which you've just removed... Please don't merge until 0.15! |
|
If anything, I think life is easier now, because you just listen to ConfigSaved, and set/read Paused on each device/folder. Agree, it's not a zero effort change, but I think it's for the better. |
|
Not quite. In order to set the config, I need to model it exactly using my data structures, so that I can parse it in its entirety, then set it back with no loss of information. Since the config format changes often, and I need to be backwards compatible, this would mean a lot of different models, and a lot of very similar-looking code around each, to support. I will also have to start keeping much closer tabs on when the config format changes. In reality, I will probably have stop Syncthing from automatically upgrading, and instead manually vet each new version before allowing users to upgrade. That mechanism will take even more time to get in place... I've avoided setting the config so far for this reason. Before you release this, I need the chance add support for setting config, in parallel with the current approach, and add a switch which selects between the two approaches based on the Syncthing version (which means I need to know ahead of time which version will contain these changes). At the very least, I need time to remove my features which depend on device pausing, and push this to the majority of users, which will take several weeks. If I don't do this, 5000 Windows users will insta-crash, which won't be pretty. |
|
We could maintain backwards compatibility, and deprecate the stuff I removed later to make life easier, but not sure how much of a benefit that is, as it just defers work which will have to be done anyway. |
|
Could we not do this and retain the REST methods, having them internally just doing the config updates? The difference would be that the actions are persisted, but otherwise the behavior would be the same |
|
Maintaining backwards compatibility, at least for a while, would be a huge help for me. Yes it's just deferring work which needs to be done anyway, but that gives me time to get a fix in place, while allowing you to get your new feature out earlier. How hard would it be to keep the events for a while? I won't crash if they're removed, bur I'll do strange things if the user manually pauses and unpauses devices. |
|
I'm not familiar with the Syncthing source code, so I'm just going by the referenced issues, and it sounds really good! Some questions:
|
|
Answer to both questions is yes. You can also pause syncthing by pausing all devices, not only folders. Or start with -paused command line. Folder being paused will still makes syncthing connect and exchange pings etc etc, but it will be minimal cost. |
|
Sounds perfect! |
|
Added backwards compatibility. I guess it will be easy just to revert that once we decide to drop 0.15. |
568ad03 to
dce533d
Compare
cmd/syncthing/main.go
Outdated
|
|
||
| "github.com/thejerf/suture" | ||
|
|
||
| _ "net/http/pprof" |
There was a problem hiding this comment.
the STPROFILER=":9090" doesn't work if this is not imported.
There was a problem hiding this comment.
Right, I had mentally deprecated that, woops
|
I only glanced at the diff briefly now on my phone, so take this with a grain of salt. My previous attempts at folder pausing were shot down for the following reasons:
|
|
Paused folders simply stop existing. So nothing is received, nothing is sent (absent from CC), and nothing is scanned. |
|
That doesn't stop another device from requesting files from me for that folder though, if they see that I'm connected and they have an index for it since before? I also don't think we should remove the folder from the clusterconfig we send. For one thing that will interact badly with your introducer change in the other PR - pause a folder on an introducer and it'll be unshared everywhere... Better to have a |
|
You can't request blocks from a paused folder, because it's not running, hence folderSharedWith returns false. Regarding the introducer issue, good point. Let's decide which one are we merging first and I'll patch up the other |
|
I don't understand what you mean about folderSharedWith. That check is just based on the config. If the other device pauses the folder, I'm still sharing it with them so I have reason to request blocks from them if they are connected and the index says they have the blocks I need? |
|
folderSharedWith checks m.deviceFolders, which gets populated as folders are started. Paused folders are not started. |
|
But I'm not talking about the paused side, I'm talking about the other side that might want to request blocks from the paused side. |
|
Yes, requests will go out, but will not be answered, i guess that should be addressed. |
|
Yet adding a paused boolean to protocol.Folder breaks backwards compatibility to some extent, as old clients will ignore the fact that it's paused and keep sending requests. Is that fine? |
|
perhaps we should add a separate ClusterConfig.PausedFolders and use that in the de-introducer branch to work around the folders being missing in the CM? |
I think that's fine |
|
Actually it's fairly trivial, so I've "just added another map"™ to the soup. |
c054f04 to
f7d8062
Compare
|
As long as the Available() call doesn't return the device I think it should be fine, it's similar to B not being connected at all |
lib/config/optionsconfiguration.go
Outdated
| OverwriteRemoteDevNames bool `xml:"overwriteRemoteDeviceNamesOnConnect" json:"overwriteRemoteDeviceNamesOnConnect" default:"false"` | ||
| TempIndexMinBlocks int `xml:"tempIndexMinBlocks" json:"tempIndexMinBlocks" default:"10"` | ||
| UnackedNotificationIDs []string `xml:"unackedNotificationID" json:"unackedNotificationIDs"` | ||
| UnpauseOnStart bool `xml:"unpauseOnStart" json:"unpauseOnStart"` |
There was a problem hiding this comment.
What's the intention for this config? It's essentially a bool you can set to have other bools changed in the config on startup? It's somewhat confusing to me what the results may be of pausing some device, setting this to to true, starting up with -paused etc at the same time so it seems we have too many ways to do the same thing.
The -paused startup flag make senses to me in that I can see a use case for starting Syncthing but having it be passive until you've had a change to do something with the config or whatever.
Not equally sure about the -unpaused?
There was a problem hiding this comment.
If this is set and you don't start with -(un)paused, it will unpause everything, just as it does in the current release. This just gives feature parity
No! Think of the other API consumers! We're relying on you! |
aefce77 to
527b153
Compare
|
Rebased on master, undeprecated existing stuff, added events for folder pauses, yet no HTTP API for pausing unpausing, so you need to throw the whole config around for that. Reason for that is that the mux we use now does not support extracting arguments from the path which would be the right way to do it /folder/{x}/pause etc. We'll leave that for the future. |
lib/config/deviceconfiguration.go
Outdated
| Introducer bool `xml:"introducer,attr" json:"introducer"` | ||
| SkipIntroductionRemovals bool `xml:"skipIntroductionRemovals,attr" json:"skipIntroductionRemovals"` | ||
| IntroducedBy protocol.DeviceID `xml:"introducedBy,attr" json:"introducedBy"` | ||
| Paused bool `xml:"paused" json:"pause"` |
|
Otherwise LGTM, let me take it for a spin as well. |
lib/model/model.go
Outdated
| if !cfg.Paused { | ||
| m.addFolderLocked(cfg) | ||
| folderType := m.startFolderLocked(cfg.ID) | ||
| l.Infoln("Restarted folder", cfg.ID, fmt.Sprintf("(%s)", folderType)) |
There was a problem hiding this comment.
These should use the cfg.Description()
| } | ||
|
|
||
| if toCfg.Paused { | ||
| l.Infoln("Pausing", deviceID) |
There was a problem hiding this comment.
Note for the future, we should have something like a deviceCfg.Description() as well with the device ID (perhaps in short form) plus device name. Not in this PR though.
|
Appears to work as designed while clicking around 👍 |
|
Addressed, merge if happy. |
|
@st-review merge the shit out of this all: Add folder pause, make pauses permanent (fixes #3407, fixes #215, fixes #3001) |
|
👌 Merged as bab7c8e. Thanks, @AudriusButkevicius! |
|
Good stuff |
|
Thank you everyone for your work on this! |
Purpose
Addresses most wanted issue numer 3.
CC: @kozec, @canton7, @Nutomic, @capi
Testing
Not much, pushed some buttons around in the UI, the UI looked the way it was supposed to, saw log messages that I expected to see.
Documentation