1

I'm trying to understand how to use the kFSEventStreamEventFlagEventIdsWrapped event flag with FSEvents.

According to the documentation, the flag is sent to registered instances when the event id counter wraps around, thus rendering previous event id obsolete.

Now let's imagine the following scenario:

  • I register for FSEvents in my application;
  • When done processing FSEvents (my application quits for instance), I save the last event id encountered while processing events to be able to replay changes from that id;
  • While my application is not running, the event id counter wraps around.

My question is: How am I supposed to know the counter wrapped around? (Thus requiring me to re-scan the whole directory structure.)

Frizlab
  • 846
  • 9
  • 30

3 Answers3

1

I now have an answer directly from Apple.

The scenario was wrong to begin with. When saving the last event id treated, you must also save with it the UUID of the event stream. An event id is valid only for a given event stream, which is identified by its UUID (see FSEventsCopyUUIDForDevice()).

Whenever the event id counter wraps around, a new event stream UUID is generated. So if you relaunch the app after the event id counter wrapped around, your stored last event id won’t be valid anymore, and you’ll know it as the event stream UUID won’t be the same.

If you encounter the kFSEventStreamEventFlagEventIdsWrapped flag, it means the counter wrapped around while your app was open. However, there’s nothing particular to be done. You should just be sure to get the new event stream UUID if you want to save the last event id.

Frizlab
  • 846
  • 9
  • 30
0

EDIT:

Event IDs do not wrap.

Here is why: Suppose your machine generates 1 filesystem event per millisecond. This means it will generate ms_per_year=31536000000 filesystem events per year. So it will take more than 500 million years before the counter will wrap around the 64bit boundary.

>>> ms_per_year = 1000*60*60*24*365
>>> d64 = 2**64
>>> d64/ms_per_year
584942417L
Michael
  • 6,451
  • 5
  • 31
  • 53
  • I’m aware Event IDs are _very_ unlikely to wrap; you don’t answer the question. I’m just trying to understand how to _fully_ use the `FSEvents` API. (Also, if Events Ids do not wrap, why create the `kFSEventStreamEventFlagEventIdsWrapped` flag?) You said in your answer before edition I should not save Event IDs to disk. Would you care to elaborate? (The doc seems to disagree: `FSEventStreamGetLatestEventId() -> […] Clients can store this value persistently as long as they also store the UUID for the device`). Thanks for your time. – Frizlab Apr 02 '14 at 11:46
  • well, i think the wrapped flag is there because some apple engineer didn't really grasp the huge space of 64 bit integers. maybe you *can* save the event ID, but maybe it wraps twice, while your app is not running, what do you do then? i mean really, come on, it just does not wrap. Just print out a few event IDs, they are something like 123_000_000, on a computer that ran for years. Even if you found a way to handle event ID wrapping... how would you test it realistically? are you sure the apple engineers have really tested if this flag really works? if yes, how have they? – Michael Apr 02 '14 at 21:52
  • The fact is you can save the event ID, but you must also save the event stream UUID with it as an event ID is valid only for a given event stream. The event stream UUID is changed when the counter wraps around. See my accepted answer for more infos. – Frizlab Oct 09 '14 at 14:43
  • And btw Apple can have tested the wrap very easily by manually setting the event ID to 2**64-42 ;) I sure hope they did; it’s basic coding 101 to test anything that you code. – Frizlab Oct 09 '14 at 14:46
  • @Frizlab: it wraps only if you try to test the wrap-around. practically, it will never wrap around (unless you believe that there will be OS X in 500000000 years...) – Michael Oct 10 '14 at 13:12
  • Yeah I know. But the number of bugs that happened because “The value is so mindbogglingly enormous that it will never be reached” is… mindbogglingly enormous too. Better be safe than sorry! (We never know, maybe one day the disks will generate thousands events per ms, or anything else. Anything’s possible.) – Frizlab Oct 11 '14 at 14:06
  • @Frizlab - they would have to generate more than 10 million FS-events per second on average, for this to become a problem within the next 50000 years. and then only if you have computers that are actually active for more than 50000 years. If you exchange the computer every 100 years, there will be no problem. Additionally, you have to assume that there will still be OS X in 50000 years. BTW, faster disks not necessarily produce more FS-events. Write 10bytes to disk with one fwrite() -> 1 FS-evnet. Write 512kB to disk with 1 fwrite() -> also 1 FS-event. lol – Michael Oct 12 '14 at 18:05
  • @Frizlab - checking the UUID is probably a good idea anyways, because you might migrate the program to a different computer. But not because it actually wraps, IMHO. – Michael Oct 12 '14 at 18:07
  • So it’s been a while, but on High Sierra, my current event id is 18427041933606892295. I have no idea why it’s so high, but one should never assume values are too high for them never to happen. – Frizlab Jul 07 '18 at 09:51
  • @Frizlab: wow, only 624000 years left to go until wraparound ;) Anyhow, I would do as the accepted anser suggests and use `FSEventsCopyUUIDForDevice()`. Then it doesn't really matter wether it wraps or not. – Michael Jul 07 '18 at 10:03
  • If I would have enough time I would like to check the fsevents binary to see if the wraparound code is ever triggered. I wouldn't be too surprised if they have put the flag into the API but never actually implemented it. – Michael Jul 07 '18 at 10:06
0

If kFSEventStreamEventFlagEventIdsWrapped is set, it means the 64-bit event ID counter wrapped around. As a result, previously-issued event ID's are no longer valid arguments for the sinceWhen parameter of the FSEventStreamCreate() functions.[1]

Next time your should use kFSEventStreamEventIdSinceNow for FSEventStreamEventId and you must rescan all directory.

Parag Bafna
  • 22,812
  • 8
  • 71
  • 144
  • Thank you for quoting the documentation (without referencing it…), but as you can guess I did read the doc. The question is how do I know the counter wrapped around when the app is launched if it wrapped when the app was not launched? – Frizlab Oct 08 '14 at 10:15
  • 1
    @Frizlab If solution is not present in the docs then you should try fsevent on 2000 exabytes of storage and let us know how to use this flag. – Parag Bafna Oct 08 '14 at 16:09
  • I would if I could! :D In the mean time, I’m asking Apple directly, see what they say about it :) – Frizlab Oct 09 '14 at 07:17
  • Got an answer from Apple ;) – Frizlab Oct 09 '14 at 14:47