MeterSync new algorithm POC: Anyone want to take a look?
[email protected] Mon, 27 Jan 2020 18:55:10 +0800
| Newsgroups | gmane.comp.audio.supercollider.devel |
|---|---|
| Message-ID | <CAFniQ7UoC-+sXBm+yF-erryv5536ogxriivK6AxLDLtDTneB4A@mail.gmail.com> |
Hi all -- A few weeks ago, I reported a race condition with the new MeterSync class for LinkClock. Briefly, the problem is: if 2 or 3 LinkClocks are created at roughly the same time, they might fail to sync barlines and in that case, the algorithm that was checked in earlier would be unable to recover. The old approach was to ask all the peers about their metric alignment, and fail if they disagree. I just finished a POC of the new approach, which keeps track of the peers' IDs in order of creation, and uses that list to sync to the oldest responding peer. https://github.com/jamshark70/supercollider/commit/dd5f4c62d63407fde57b6dde115cd9310b626b1e At this stage, it passes every test I can throw at it. The most complex test case is: 1. Sclang A and B: An OSCFunc to create and meter-sync a LinkClock when receiving '/sc_startedLink' (so these two clocks should be created within milliseconds after step 2). 2. Sclang C: Start a LinkClock + MeterSync with beatsPerBar = 3, and send '/sc_startedLink'. C is the first to exist, so it should have the oldest ID; when A and B meter-sync, they should pick up 3/4 time. 3. Kill sclang C (`0.exit`). Now the oldest ID is dead (but the other two clocks are still meter-synced). 4. Relaunch sclang C. Do `l = LinkClock.new.latency_(s.latency).enableMeterSync;` -- it should sync to whichever of A or B is older (which doesn't matter, because they share the same barlines). I think it's a reasonable approach, but probably the code is not as clean as it could be. 1. Currently I'm using a classvar to watch IDs as they are created and destroyed. Is there another way? I'm also using a list of IDs in OSC replies (for recovery -- 3/ and 4/ above) but if these arrays get out of sync between different clients, then it may simply replicate the problem of which one is correct. Note that MeterSync objects on my local sclang need to be aware *before* instantiation of the IDs of any MeterSync objects elsewhere on the network -- so I used a classvar. 2. The recovery logic to collapse the list of IDs is maybe not optimal...? It was OK for a POC but I'd love to have a second eye. 3. If a peer crashes, it won't broadcast that it stopped cleanly and IDs will leak in the other peers. But IDs are supposed to be integers or symbols, and IDs in the list will be ignored if that ID is no longer answering queries. I don't think this is a serious problem, but just mentioning it. (I think this is better than continually polling the network to see has gone down -- if you have peers crashing routinely, then you have bigger problems than a growing array [and the array will stop growing when you fix the crashes], and if they are crashing only seldom, then the array will not grow out of control.) 4. I'd mentioned in an earlier e-mail that it was failing when I did not use debugging posts... that problem has magically self-resolved after updating the sources and rebuilding SC. ??? I'm posting here because I'm not sure it's ready for a PR. Wondered if anyone would like to kick the tires. Thanks, hjh _______________________________________________ sc-dev mailing list info (subscription, etc.): http://www.birmingham.ac.uk/facilities/ea-studios/research/supercollider/mailinglist.aspx archive: http://www.listarc.bham.ac.uk/marchives/sc-dev/ search: http://www.listarc.bham.ac.uk/lists/sc-dev/search/