A proposal for a receive-only folder type

(Jakob Borg) #1

Receive-Only Folder Type

Here’s a proposal for a new “receive-only” folder type. Please consider it and provide feedback on whether it handles your favorite use cases for it or not. Specifically, if you want a “receive only folder” but this is not it, explain why not.


A receive-only folder has most of the characteristics of a regular send-receive folder except local changes are not propagated to the rest of the cluster.

The purpose of a receive-only folder is to protect the rest of the cluster against changes that should not happen, and should not be propagated if they do happen.

Similar to the send-only folder’s “Override” button the receive-only folder gains a “Revert” button which does the opposite - it wipes out any local changes that differ from the cluster latest version.

Here’s a list of scenarios and the resulting behavior:

  • A file is deleted locally. The file remains deleted until it is changed remotely or “Revert” is pressed. When it changes remotely we will have a sync conflict (delete vs change) where the new version will always win and the file is resurrected.

  • A file is changed locally. The file remains changed until it is changed remotely or “Revert” is pressed. When it changes remotely we will have a sync conflict (change vs change) where the remote side will always win. A conflict copy will be created and picked up by the next scan. Which brings us to …

  • A file is added locally. The file remains until it is changed or deleted remotely (which would require it to be created somewhere remotely first), or until “Revert” is pressed. A remote create plus change results in a sync conflict and our version then becomes a conflict copy.

  • A conflict is resolved locally. (That is, two or more other devices announce conflicting versions to us and we resolve the conflict as part of syncing.) Conflict resolution happens as usual, potentially creating a conflict copy. The conflict resolution isn’t announced to anyone else though, so another device will also resolve the conflict at some point in the future. When that happens we will see a new version which is again in conflict with the one we have locally. We will accept that copy and potentially create another conflict copy.

  • On other devices that are normal send-receive folders these changes will be invisible. The receive-only device will look out of sync when it has local changes but we can’t do much about it, other than looking at what files are out of sync and manually tweaking them to trigger an update.

  • Maybe, undecided on this: On other devices that are send-only folders the “Override” button should light up when there are changes on a receive-only device. Pressing it will undo all the changes done on the receive-only folder and bring it back in line.


  • Note that wiping out local changes requires a manual action - clicking the “Revert” button. Of course, an industrious user can rig something towards the API to always revert local changes. This is fine as it’s a local policy decision and not something that’s likely to happen by mistake.

  • Locally detected changes are sent, but with the invalid bit sent. This prevents that version from becoming the latest version, but indicates to other devices that we no longer have the right version of the file.

  • When handling sync conflicts we may need to specifically ensure we always lose. We should make sure to not create conflict copies when the contents are identical on both sides, if that is not already the case.

  • If we want send-only overrides on this: Send-only folders need to take remote versions with the invalid bit into account when doing “Override”, and override those too.

  • Changing the folder type from receive-only to send-receive requires going through the index and bumping all entries that were sent as invalid previously; maybe this can easily happen as part of the scan nowadays. Going in the other direction shouldn’t require anything special.

I'm wondering about "Receive Only" folders
(Bruno) #2

I’m a little in a hurry this morning, so I’ll read deeper later, but one more question is where the behavior of receive only is set. I propose to set it at 2 levels : locally and from other send-receveirs. It would be activate if it is set AT LEAST from one of these 2 places. So a user can set (or unset) himself as receive only, or a parent can set his child to be receive only. It shouldn’t be depending of the child if the parent doesn’t allow it. Thanks.

(Jakob Borg) #3

No, this needs to be set locally. The opposite setting on the “parent” is send-only. We do not permit reconfiguration from other devices on other settings (apart from the introducer thing) and I don’t see any reason to do so here either.

(Audrius Butkevicius) #4

A conflict copy that is propagated back to the cluster, of the conflict is local only and then ends up being an extra orphaned file that automatically summons the revert button?

This means the send-only device needs to send index updates about things that it has but does not want others to download, which means a lot more cruft in the database logic layer. Sounds too complicated.

(Jakob Borg) #5

I think both of those points are covered above. We need to send index updates regardless, to have our in-sync state visible on other devices, and for them to be able to download stuff from us. That means updates-with-invalid-bit on “unauthorized” changes, also for the conflict copies. Which would then be wiped out on any “Revert” action.

No-one said it would be uncomplicated :smiley:

I’m more curious about “is this even what people want? What do people want?”.

(Audrius Butkevicius) #6

What about non-content changes, such as mtimes? I guess this is the same boat as send only handles that, but I suspect a lot of people bitching about them not changing things yet getting a Revert button…

(Jakob Borg) #7

Yeah business as usual I guess. Not related to this, but I could see the point of an “ignore mtimes” mode, where we remember and compare the mtime for change detection purposes but ignore it for in sync purposes.

(Audrius Butkevicius) #8

If we are feeling bored, can we perhaps put the argument on it’s head and discuss a different permissioning model?

For each folder remote device combo we set wether we allow them to add, modify, delete files. We ourselves also set our detected adds modifications and deletions as propagated or non-propagated back (propagated but with invalid bit set). Send only, send receive and receive only becomes just a different combination of these.

I guess we could then hide the knobs behind the folder type dropdown options, but I suspect the implementation could be more manageable.

If you have any of the self checkboxes unchecked you gain a revert button, if you have all of the devices with no permissions you gain override, and we scrap ignore deletes flag.

(Jakob Borg) #9

I’d be fine with something like that. One issue I see is that it’s easy to restrict updates A->B on B when it has a direct relationship to A - but when there is also a path A->C->B it becomes trickier to contain A.

(Bruno) #10

Do you mean ?

 A ----> C


 B <---- C

Is C receive only or not ?

(Jakob Borg) #11
A ---- B
 \    /
  \  /

“A” should be receive only. With the advanced suggestion we could do it on A itself (“do not propagate changes”) which is about equivalent to my topmost proposal. Or it could be done on B/C but then it needs to be done identically on both to make sense. Maybe this is fine and the usual way to set it up would be to set the flags on A, but the filters could be implemented on B & C as well for extra safety or something.

(Audrius Butkevicius) #12

I understand you can’t mitigate that, hence why it would be an advanced option other than the dropdowns potentially with a good chapter of docs covering pitfalls.

(Simon) #13

As the current model does not allow any control at “cluster level” and the ensuing pitfalls, I kind of like the current choices where you can only set restrictions on the local folder/behaviour. It makes it pretty clear that you cannot control what happens outside of the device/how other devices behave, only what your device does about what happens outside.

(Bruno) #14

For a question of locating the place where this decision is set, and following my response #2 in this thread, I would then prefer to set locally that “I don’t want to be locally disturbed by any changes occuring on that only particular other device” if I cannot set it remotely to be receive only. It’s not a way arround to keep saying it, but a way to conceptualize the relation between these devices. Thanks :slight_smile:


For me that behaviour would make sense.

Note that before reading that topic, I had another idea how to solve this kind of scenario: New Folder type: Receive Only

My idea would require more configuration (multiple “send-only” devs instead of one “receive-only” dev). However, to protect nodes of the cluster, it is more intuitive to “setup shields” on the nodes to be protected instead on the “intruder”.

(Bruno) #16

Hi @Martchus; would you please read this and give a feed back. Thanks. https://forum.syncthing.net/t/im-wondering-about-receive-only-folders/9229/20?u=brunod


@brunod Sorry, but that sounds way more complicated than necessary. I like my approach more because it solves the “receive-only” use case without even introducing a new folder type. I’ve also read @AudriusButkevicius answer and agree.

(Bruno) #18

Thanks for your answer. No sorry, we all just try to progress :slight_smile:

But, at present time, what happens when there are 2 “send only” devices/folders with different contents at the same time among other “send receive” devices/folders ?

If we add a status “receive only” as requested, how should it behave if there is, among usual “send-receivers”, a “send only” device/folder ?

These are the case I wanted to handle.

Thanks, BD

(Kluppy) #19

The problem with this is that Syncthing works as a cluster… Unless every device in the cluster is set the same way the changes will propose through the cluster. Example, 3 devices A, B and C. A is set to ignore B as you suggested but C isn’t. Something Changes on B and it announces the changes. A ignores B. C accepts the changes and syncronises. Then C updates it’s state with A. A sees C has a newer state and syncronises the changes.

This does not scale well at all, I only manage 6 devices but over all of the folders there would be too many places I could make a mistake in one of the configuration options.

(Bruno) #20

I know, that’s why I wanted in first place to set it remotely on the ignored device; but that’s against syncthing policy. So I don’t know where else it could be set… Because if it depends of the ignored device itself, it’s like closing your door with the key on the outside.