Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Race condition can leave files out of sync while syncing between local dirs #17

Closed
comex opened this issue May 10, 2022 · 2 comments · Fixed by #25
Closed

Race condition can leave files out of sync while syncing between local dirs #17

comex opened this issue May 10, 2022 · 2 comments · Fixed by #25

Comments

@comex
Copy link

comex commented May 10, 2022

To reproduce (I'm on macOS 12.3.1):

mkdir /tmp/a /tmp/b
unison /tmp/a /tmp/b -repeat watch -ui text -debug fswatch+

While this is running, try

echo $RANDOM > /tmp/a/x

I see a bunch of output, quoted below. Importantly, there is a delay between "Synchronization complete" being printed and new WAIT commands being sent. If you modify /tmp/a/x again during this interval, a second synchronization does not occur, and so /tmp/a/x and /tmp/b/x stay out of sync (until one of them is changed yet again or Unison is restarted).

I can reproduce this on Unison 2.51.5 as well as the latest master at time of writing. It doesn't occur when using Unison's built-in fsmonitor implementation on Linux.

The cause appears to be the timing of CHANGES responses. This fsmonitor implementation sends CHANGES immediately as soon as changes occur. But the built-in fsmonitor has more of a polling model, where CHANGES responses are sent only in response to WAIT commands; a CHANGE response terminates a wait, and changes that occur while not waiting should be reported at the next wait. In fact, Unison itself seems to ignore the arguments to CHANGES responses; it simply uses CHANGES as a notification that it should terminate the wait and send its own CHANGES command to request filenames of the files that changed. (Nevertheless, the built-in fsmonitor does include the hashes of changed files in its CHANGES response; there can be multiple hashes in a single response.)

Edit: To further clarify: WAIT is like select(), terminated by a CHANGES response, and CHANGES commands are like read(). They affect the same state (list of pending changes). I think.

[fswatch+] >> CHANGES d03c239c5bae8b7a9a35a6284d8a9512
Looking for changes
[fswatch+] << CHANGES d03c239c5bae8b7a9a35a6284d8a9512
[fswatch+] >> RECURSIVE x
[fswatch+] >> DONE
[fswatch+] << START d03c239c5bae8b7a9a35a6284d8a9512 /private/tmp/a x
[fswatch+] >> OK
[fswatch+] << DONE
[fswatch+] << CHANGES ee6f81089ac5b4e616740c34d688212d
[fswatch+] >> RECURSIVE x
[fswatch+] >> RECURSIVE %2Eunison%2Ex%2Eee6f81089ac5b4e616740c34d688212d%2Eunison%2Etmp
[fswatch+] >> DONE
[fswatch+] << START ee6f81089ac5b4e616740c34d688212d /private/tmp/b x
[fswatch+] >> OK
[fswatch+] << DONE
Reconciling changes
changed  ---->            x  
a            : changed file       modified on 2022-05-09 at 19:05:43  size 6         rw-r--r--
b            : unchanged file     modified on 2022-05-09 at 19:05:39  size 6         rw-r--r--
Propagating updates
Unison 2.51.5 (ocaml 4.12.1) started propagating changes at 19:05:44.67 on 09 May 2022
[BGN] Updating file x from /private/tmp/a to /private/tmp/b
[END] Updating file x
Unison 2.51.5 (ocaml 4.12.1) finished propagating changes at 19:05:44.67 on 09 May 2022, 0.001 s
Saving synchronizer state
Synchronization complete at 19:05:44  (1 item transferred, 0 skipped, 0 failed)
[fswatch+] >> CHANGES ee6f81089ac5b4e616740c34d688212d
[fswatch+] >> CHANGES ee6f81089ac5b4e616740c34d688212d
[fswatch+] >> CHANGES ee6f81089ac5b4e616740c34d688212d
[fswatch+] << WAIT d03c239c5bae8b7a9a35a6284d8a9512
[fswatch+] << WAIT ee6f81089ac5b4e616740c34d688212d
@autozimu
Copy link
Owner

Thank you very much for reporting! Will have a closer look as soon as I can.

@autozimu autozimu changed the title Race condition can leave files out of sync Race condition can leave files out of sync while syncing between local dirs Sep 22, 2022
@chrisblossom
Copy link

Has there been any updates on this issue? I want to use this with unison to sync two local directories on my MacBook but am hesitant to try because this issue is still open.

Either way, thank you for all of your work on this. Much appreciated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants