I have a directory watcher which uses FSEvents API on Mac OS X and also polls local or remote directories on mounted server volumes for changes. It works great, and I can make an NSSet of directory URLS which have been changed and need to be traversed. It has a callback mechanism I use to feed an array of changed URLS to whatever client.
I have a particular scenario that I cant wrap my head around thats been happening with a mounted AFP or SMB volume - which tells me I have a misapprehension about something.
1 - Directory Watcher correctly notices directory content has changed (I moved something manually), it traverses the top level directories within the watch folder and returns an array of NSURLs* that are new. In my debugging this list has never been inaccurate.
2 - My App, a client of the Directory Watcher then enumerates each URL in the above array. If the URL exists (which it should I enumerated it moments ago) copies it to a temp folder for processing.
Code :
Directory Watcher: https://github.com/Synopsis/Synopsis-Framework/blob/master/Synopsis/Synopsis/Utilities/SynopsisDirectoryWatcher.m
Client App call that sometimes fails: https://github.com/Synopsis/Synopsis-Analyzer/blob/master/Synopsis/Synopsis/AppDelegate.m#L497
I've been getting issues where the directory I just was notified changed, and successfully enumerated, and can see in the Finder, is unable to be copied because it doesnt exist by according to NSFileManager. Step 2 fails ~3 out of 4 times if, and only if, the directory is on a remotely mounted file server (Mac Mini, Mac OS 10.10, a touch out of date and slow). For local changes, I have no issues, and for many other servers ive not seen this issue at all.
Here's a log:
Note that the folder Watch folder is enumerated correctly, the SESSION_1 folder is found.
A copy is attempted, and NSFileManager now says SESSION_1 at the same path is not found.
The security information logging is due to HFS+ extended attributes not being copied over this version of AFP. The copy is successful 3 out of 4 times.
How can NSFileManager directory Enumerator return valid, existing folder structure, and then NSFileManager copyItemAtURL tell me URL is not valid?
- I am using the same instance of an NSFileManager ive alloc inited.
- I am a delegate of my file manager, and handle copy errors/continuation
- I have tried waiting some time between directory watcher and evoking the callback so the mounted file system can settle down.
- I have been able to check NSURL resource attributes on the folders in question prior to the copy, and am able to retrieve correct values.
- I have tried using NSFIleCoordinate with NSFileCoordinatorReadingWithoutChanges
Some questions:
Are Move operations atomic on remotely mounted file systems? Ie, if I move a directory with a ton of content from /Volumes/Mount/Parent1/child_a to /Volumes/Mount/Parent2/child_a - is the directory content ever in an inconsistent state?
Is there a way to "sync" NSFileManager to force an update?
Lower level apis I should use?
Thank you!