I also released Flake 0.4.2 today which includes an important bugfix where two competing threads could have caused duplicate IDs in certain circumstances as well as a new method for deriving timestamps.
> On Jun 21, 2016, at 16:29, Max Countryman <m...@me.com> wrote: > > Brian, > > I think you make good points here, especially with regard to the size of IDs. > > I’d also like to point out that while adding the process and thread IDs > helps, it doesn’t eliminate the possibility of duplicate IDs: this is why > it’s necessary to write out the last used timestamp in a separate thread. > > Just a clarification with regard to disk persistence: we aren’t writing out > the epoch, we’re writing out the last used timestamp periodically, in its own > thread. Yes, the `init!` API is cumbersome, but it’s an important safety > valve which helps protect against duplicate IDs. > > My understanding from reading the documentation and various StackOverflow > answers is that System/nanoTime is monotonic, but I don’t know what > guarantees it makes across threads. > > > Max > > >> On Jun 21, 2016, at 10:00, Brian Platz <brian.platz@place.works >> <mailto:brian.platz@place.works>> wrote: >> >> Bruno, >> >> I think the more you can reduce the chance of collision the better and the >> thread-local capability is a good idea, but in the process you've almost >> doubled the bits. >> >> For me anyhow, an ID need to be produceable at a reasonable rate (1 million >> a second per machine is good for me), have near-zero probability of >> collision and take up the least amount of space possible. >> >> Under those criteria, I think 128 bits is a reasonable target and the >> thread-safe atom I would expect to handle such volume (although I haven't >> tested). >> >> If you need a billion per second and don't want 100 machines producing them, >> then I think you are at the point of needing to have thread independence and >> probably have to increase the bit-count, and your ideas provide a good path >> towards such a solution. >> >> Your comment on the file persistence is a good one, I wonder if the >> potential problems are real enough to warrant the risks. >> >> My other curiosity is if System/nanoTime is guaranteed to increment across >> threads. I know at least a while ago that this guarantee did not exist. >> >> -Brian >> >> >> On Tuesday, June 21, 2016 at 8:38:58 AM UTC-4, Bruno Bonacci wrote: >> >> Hi this change it is actually easier than it sounds. Looking at the code, I >> came across a couple of things which I think might be better. >> >> 1) use of filesystem persistence. >> >> Not too sure that the file based persistence is a good idea. Maybe this is a >> good idiomatic design for Erlang, but definitely it doesn't look nice in >> Clojure. >> >> In particular I'm not too sure that by storing the init time epoc we >> actually accomplish anything at all. >> I would argue that there are a number of problems there, race conditions on >> data, tmp file purged out, and still doesn't protect against the case the >> clock drift during the use. >> >> 2) use of CAS (atom) for storing the VM state. >> If if is truly decentralized then you shouldn't need an atom at all. The >> disadvantage of the CAS is that, when many thread race to the same change, >> only one will succeed and all the other ones will fail and retry. Which mean >> that if you have 100 threads (for example) only 1 will succeed all the other >> 99 will fail and retry. Again at the second round only 1 will succeed and 98 >> will retry, and so on. >> Therefore the total number of attempts will be >> >> >> <https://lh3.googleusercontent.com/-ZVELcKNoB9M/V2kxgYmlFMI/AAAAAAAAB8Q/nR6jLFjKSI0611-WiQpQHXAcY3SueVIdwCLcB/s1600/Screen%2BShot%2B2016-06-21%2Bat%2B13.21.24.png> >> >> If you want to develop a real "decentralized" id generator, I think, you >> need to drop the atom in favour of a thread local store. >> Now to do so and make collision impossible we need to add more bits: >> >> 64 bits - ts (i.e. a timestamp ) >> 48 bits - worker-id/node (i.e. MAC address) >> 32 bits - worker-id/process (pid) >> 64 bits - worker-id/thread (thread num) >> 32 bits - seq-no (i.e. a counter) >> By adding the process id (pid) and the thread id there is possibility of >> having two systems running and creating the same id at the same time. >> Finally by using thread-local storage there is no need of process level >> coordination (atom) and no risk of retries because every process is stepping >> on each others toes. >> >> With such setup 100 threads will be able to increment their own thread local >> counter independently (given that you have 100 execution cores). >> >> What do you think? >> Bruno >> >> >> >> >> -- >> You received this message because you are subscribed to the Google >> Groups "Clojure" group. >> To post to this group, send email to clojure@googlegroups.com >> <mailto:clojure@googlegroups.com> >> Note that posts from new members are moderated - please be patient with your >> first post. >> To unsubscribe from this group, send email to >> clojure+unsubscr...@googlegroups.com >> <mailto:clojure+unsubscr...@googlegroups.com> >> For more options, visit this group at >> http://groups.google.com/group/clojure?hl=en >> <http://groups.google.com/group/clojure?hl=en> >> --- >> You received this message because you are subscribed to the Google Groups >> "Clojure" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to clojure+unsubscr...@googlegroups.com >> <mailto:clojure+unsubscr...@googlegroups.com>. >> For more options, visit https://groups.google.com/d/optout >> <https://groups.google.com/d/optout>. > > > -- > You received this message because you are subscribed to the Google > Groups "Clojure" group. > To post to this group, send email to clojure@googlegroups.com > Note that posts from new members are moderated - please be patient with your > first post. > To unsubscribe from this group, send email to > clojure+unsubscr...@googlegroups.com > For more options, visit this group at > http://groups.google.com/group/clojure?hl=en > <http://groups.google.com/group/clojure?hl=en> > --- > You received this message because you are subscribed to the Google Groups > "Clojure" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to clojure+unsubscr...@googlegroups.com > <mailto:clojure+unsubscr...@googlegroups.com>. > For more options, visit https://groups.google.com/d/optout > <https://groups.google.com/d/optout>. -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.