Skip to content

all: Add folder pause, make pauses optionally permanent (fixes #3407, fixes #215, fixes #3001)#3520

Closed
AudriusButkevicius wants to merge 10 commits intosyncthing:masterfrom
AudriusButkevicius:pfolder
Closed

all: Add folder pause, make pauses optionally permanent (fixes #3407, fixes #215, fixes #3001)#3520
AudriusButkevicius wants to merge 10 commits intosyncthing:masterfrom
AudriusButkevicius:pfolder

Conversation

@AudriusButkevicius
Copy link
Copy Markdown
Member

@AudriusButkevicius AudriusButkevicius commented Aug 16, 2016

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

  • Removal of DevicePaused/Unpaused events
  • Removal of /pause, /resume REST endpoints
  • Removal of 'paused' in connection info
  • Addition of unpaused command line option
  • Addition of UnpauseOnStart option
  • Addition of Paused attribute on Folder/Device segments

@AudriusButkevicius
Copy link
Copy Markdown
Member Author

AudriusButkevicius commented Aug 16, 2016

+122 −116 - 2 features in 6 lines. If we'd exclude the test changes, that'd be less.

@canton7
Copy link
Copy Markdown
Contributor

canton7 commented Aug 16, 2016

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!

@AudriusButkevicius
Copy link
Copy Markdown
Member Author

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.

@canton7
Copy link
Copy Markdown
Contributor

canton7 commented Aug 16, 2016

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.

@AudriusButkevicius
Copy link
Copy Markdown
Member Author

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.

@calmh
Copy link
Copy Markdown
Member

calmh commented Aug 17, 2016

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

@canton7
Copy link
Copy Markdown
Contributor

canton7 commented Aug 17, 2016

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.

@Nutomic
Copy link
Copy Markdown
Contributor

Nutomic commented Aug 17, 2016

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:

  • To pause Syncthing globally, I will have to iterate over all folders in the config and pause them, right?
  • Can I add a folder in paused state? So that people can add folders while Syncthing is paused, without transferring data.

@AudriusButkevicius
Copy link
Copy Markdown
Member Author

AudriusButkevicius commented Aug 17, 2016

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.

@Nutomic
Copy link
Copy Markdown
Contributor

Nutomic commented Aug 17, 2016

Sounds perfect!

@AudriusButkevicius
Copy link
Copy Markdown
Member Author

AudriusButkevicius commented Aug 17, 2016

Added backwards compatibility. I guess it will be easy just to revert that once we decide to drop 0.15.
Yet pauses are still permanent unlike before, mentioning since something might need to be done from @canton7's side

@AudriusButkevicius AudriusButkevicius changed the title all: Add folder pause, make pauses optionally permanent (fixes #3407, fixes #215, ref #3001) all: Add folder pause, make pauses optionally permanent (fixes #3407, fixes #215, fixes #3001) Aug 17, 2016

"github.com/thejerf/suture"

_ "net/http/pprof"
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the STPROFILER=":9090" doesn't work if this is not imported.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, I had mentally deprecated that, woops

@calmh
Copy link
Copy Markdown
Member

calmh commented Aug 18, 2016

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:

  • Pausing a folder required a reconnect, which caused an index resend and consumed data. Not an issue any more.
  • A paused folder should not receive index updates, so it doesn't consume data for that reason. We can handle this easily by setting a paused flag in the cluster config and the other side won't start an index sender. Not sure if the diff does this?
  • A paused folder should not receive requests. We can handle this in the same way, by remembering that flag and filtering out the device in the Available() check. Not sure if implemented?

@AudriusButkevicius
Copy link
Copy Markdown
Member Author

Paused folders simply stop existing. So nothing is received, nothing is sent (absent from CC), and nothing is scanned.

@calmh
Copy link
Copy Markdown
Member

calmh commented Aug 18, 2016

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 Paused bool in the protocol that the other side knows to mean "do not send indexes; do not request files"?

@AudriusButkevicius
Copy link
Copy Markdown
Member Author

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

@calmh
Copy link
Copy Markdown
Member

calmh commented Aug 18, 2016

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?

@AudriusButkevicius
Copy link
Copy Markdown
Member Author

folderSharedWith checks m.deviceFolders, which gets populated as folders are started. Paused folders are not started.

@calmh
Copy link
Copy Markdown
Member

calmh commented Aug 18, 2016

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.

@AudriusButkevicius
Copy link
Copy Markdown
Member Author

Yes, requests will go out, but will not be answered, i guess that should be addressed.

@AudriusButkevicius
Copy link
Copy Markdown
Member Author

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?

@AudriusButkevicius
Copy link
Copy Markdown
Member Author

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?

@calmh
Copy link
Copy Markdown
Member

calmh commented Aug 20, 2016

old clients will ignore the fact that it's paused and keep sending requests. Is that fine?

I think that's fine

@AudriusButkevicius
Copy link
Copy Markdown
Member Author

Actually it's fairly trivial, so I've "just added another map"™ to the soup.
Question, if I have A and B, and B connects paused, yet B has previously advertised to A that it has some files that A doesn't? Will A go into berserk mode trying to download from nowhere?

@calmh
Copy link
Copy Markdown
Member

calmh commented Aug 21, 2016

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

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"`
Copy link
Copy Markdown
Member

@calmh calmh Aug 21, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

@canton7
Copy link
Copy Markdown
Contributor

canton7 commented Dec 15, 2016

so you'll soon have won by wearing me down to a point where I don't really care what API looks like any more

No! Think of the other API consumers! We're relying on you!

@AudriusButkevicius
Copy link
Copy Markdown
Member Author

AudriusButkevicius commented Dec 18, 2016

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.

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"`
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

paused/pause?

@calmh
Copy link
Copy Markdown
Member

calmh commented Dec 21, 2016

Otherwise LGTM, let me take it for a spin as well.

if !cfg.Paused {
m.addFolderLocked(cfg)
folderType := m.startFolderLocked(cfg.ID)
l.Infoln("Restarted folder", cfg.ID, fmt.Sprintf("(%s)", folderType))
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These should use the cfg.Description()

}

if toCfg.Paused {
l.Infoln("Pausing", deviceID)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@calmh
Copy link
Copy Markdown
Member

calmh commented Dec 21, 2016

Appears to work as designed while clicking around 👍

@AudriusButkevicius
Copy link
Copy Markdown
Member Author

Addressed, merge if happy.

@calmh
Copy link
Copy Markdown
Member

calmh commented Dec 21, 2016

@st-review merge the shit out of this

all: Add folder pause, make pauses permanent (fixes #3407, fixes #215, fixes #3001)

@st-review
Copy link
Copy Markdown

👌 Merged as bab7c8e. Thanks, @AudriusButkevicius!

@st-review st-review closed this Dec 21, 2016
st-review pushed a commit that referenced this pull request Dec 21, 2016
@calmh
Copy link
Copy Markdown
Member

calmh commented Dec 21, 2016

Good stuff

@tobiastom
Copy link
Copy Markdown
Contributor

Thank you everyone for your work on this!

@scienmind scienmind mentioned this pull request Dec 23, 2016
@calmh calmh mentioned this pull request Feb 7, 2017
@st-review st-review added the frozen-due-to-age Issues closed and untouched for a long time, together with being locked for discussion label Dec 22, 2017
@syncthing syncthing locked and limited conversation to collaborators Dec 22, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

frozen-due-to-age Issues closed and untouched for a long time, together with being locked for discussion

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants