muellmusik/Utopia — pull request #4 by muellmusik (2013-12-20 13:13:18+00:00)
Title: Rework Addressing

This is a draft of a new addressing approach for comment and consideration. Sorry this has taken so long! Details:

- Peer now spoofs a NetAddr
- Add PeerGroup, an Array subclass with NetAddr send methods
- Add ServerRegistry, a class which allows peers to share server info; both one per Peer and other configs
- Add PeerGroupManager, a class for syncing groups of Peers or Servers
- Add examples file for above

A few comments:

The complication with Server sharing was to make it generalizable. Basically ServerRegistry needed to know both the info for the shared servers, and the Peers it was sharing to. The current implementation aims to allow for both common cases (each Peer shares a local server with everyone else), and more exotic ones (e.g. 10 peers share 4 servers running on non-Peer machines). (I think there's one bug in ServerRegistry somewhere, but I'm out of time now, sorry, and wanted to make this public.)

PeerGroup ended up as an Array subclass. This means PeerGroups can be used in list patterns, and understand common collection methods. They can also spoof a NetAddr, as they understand sendMsg, sendBundle, etc. (In an initial version I had groups lazily resolved, but I think that is easily accomplished in other ways and would have made the implementation rather complicated.)

Examples:

```
~reg = ServerRegistry(~addrBook, 0); // set an appropriate client ID
~reg.addMyServer;
~gm = PeerGroupManager(~reg, '/serverGroups');

~gm.add(\us, [\scottw, \soctt]); // my laptop and test machine; use your own names

~reg.keys

Synth(\default, target:~reg[\soctt]) // pick a server

// we can use any method that Array understands, since PeerGroup is an Array subclass
Synth(\default, target:~gm[\us].choose)

// we can use any list pattern with a PeerGroup, since it is an Array
Pbind(\server, Pseq(~gm[\us], inf)).play

~addrBook.peers; // a PeerGroup with everybody
~addrBook.others; // a PeerGroup with everybody else
~addrBook.onlinePeers; // a PeerGroup with everybody currently online
```

With a combination of groups, array methods and list patterns, I think most of the Republic resolveWhere behaviour can be easily and concisely duplicated. The address by index from myself approach could be done with a custom pattern for example. If a \where key is needed I think that might be most cleanly done by either supplementing the default event or a custom event type, but I think it's probably possible to do everything simply without that.

To be resolved if this is to be merged:

- Maybe Peer should be a NetAddr subclass rather than spoofing one
- LocalNetAddr is no longer needed
- PeerGroup has a 'name' instance var, but I don't think that's needed.
- ServerRegistry could allow for sharing of ServerOptions as well
- Some way of automating client ID.

The last one could possibly be a general reworking of the client ID approach. I would like the Bus and Buffer stuff (or something that makes the allocators work, anyway!) from Shared Server to be added to Common. It might be worth considering having scsynth itself provide clients with IDs. This would be much simpler than the current situation.

Signed-off-by: Scott Wilson