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/