On 07/17/2013 11:22 AM, Tanu Kaskinen wrote: > On Wed, 2013-07-17 at 09:27 +0200, David Henningsson wrote: >> On 07/16/2013 03:20 PM, Tanu Kaskinen wrote: >>> Yes, automatic use of the combine module is planned (the combining >>> functionality would move to the core, because what's the point of having >>> code in a module if the core directly depends on that code). >> >> Okay, so combine stuff would then not have its own node or set of nodes, >> but essentially be as integrated as mixing is today? > > Yes. Or well, I wouldn't say that it's as integrated as mixing, since it > would still create a separate combine sink, which is a bit ugly, but as > you said, the sink and the intermediate sink inputs wouldn't show up as > nodes. I think it would make sense to make combining really as > integrated as mixing, but that's not a high priority. Ok. >>>> - Can there be more than one edge between the same nodes? E g, one >>>> default connection and one explicit connection? Or how does this work? >>> >>> Yes, there can be both an explicit and a default connection between two >>> nodes, or it can be also thought as being one connection that is both >>> explicit and default. I don't know what is a better way to think about >>> it, but perhaps it doesn't matter anyway. >> >> I would prefer the latter way. I would then see "default" and "explicit" >> as a property of the edge. > > I agree about that, at a conceptual level. Would you perhaps like to > have it this way also at the code level, i.e. have connection objects > with "default" and "explicit" fields instead of storing the information > in the nodes? Good question. Actually one option could be to store the connections as global list-like matrix instead of lists on the individual node objects. After all, you'll need the connection on both sides, and unless you want to duplicate information, you'll have to do a global search on one of the sides anyway. Since the number of nodes < 100, I don't think this would matter from a performance standpoint. You would end up with a global list with entries looking something like: struct pa_node_connection_t { pa_node *from_node; pa_node *to_node; bool default; bool explicit; bool explicitly_disabled; }; Where there is only one entry for every from_node/to_node combination, explicit and explicitly_disabled cannot both be true, and there is a connection if and only if (!explictitly_disabled) && (explicit || default). And no list entry for a node combination, is the same as all three bools being false. >>>> - Can edges have properties, e g, a volume? >>> >>> I don't know. Currently I'm not aware of a requirement to have >>> properties on the connections. My current thinking regarding volume >>> specifically is that we shouldn't attach volume to nodes: let's keep the >>> nodes for routing only. >> >> Ok, that makes sense. >> >>>> * As for possible node operations, a move operation would be the same >>>> as a "batched remove + add" operation. Maybe therefore the batch >>>> solution would be better, i e, the client API inputs an array of node >>>> operations? >>> >>> I don't like the idea that if a client wants to move a stream, it has to >>> break the operation down to "remove + add", and then the server tries to >>> guess what the client really meant. Having a "move" operations keeps the >>> client intention obvious. >> >> Fair point, although the move can be on both sides, whereas one type of >> move would be "I want node A to take data from C instead of B" and the >> other type would be "I want node A to output data to node C instead of B". > > These both are served by the move operation. In the RFC you only have pa_context_move_node_connection, which serves the latter case only. The former case is from "C -> A" to "B -> A", the typical example would be a client wanting to move a recording stream from one source to another. >> Or perhaps you want to swap, so that if you're currently on "A -> B and >> C -> D" and you want "A -> D and B -> C" and you want to do all of this >> atomically. The number of operations you want to do might grow out of >> hand unless you have a "batch mode". > > The core doesn't currently have a concept of atomic swapping, so I don't > see the need for a separate swap command, but the core has a concept of > atomic moving. Well, IIRC, we have move_start and move_finish commands? A swap command would just be two move_starts and then two move_finish. > If you think applications need to be able to swap connections in one go > (even though the server will execute the commands sequentially), I'm not > opposed at all to having a batch mode. > >>> >>>> * The operations on changing the default connections does not make >>>> sense to me. If the definition for default connections are those made >>>> automatically by the routing system, if you change them then you broke >>>> the definition...? >>> >>> What operations do you mean? Moving or removing a default connection is >>> not supported as such, but if the client tries that anyway, we can >>> implicitly convert the connection to an explicit one and disable default >>> connections, or we can require the client to do these operations >>> explicitly, but I think the latter would be too inconvenient for the >>> client. >> >> Ok, I think I didn't read the proposal well enough. Having done that, I >> understand that you're suggesting a global switch "default connections >> on/off" only. Or is it a per-node switch? > > It is a per-node switch. > >> I have another idea that might be worth considering: how about that the >> "explicit" layer can both enable and disable connections? So that there >> could be a default connection between A and B, but there is also some >> sort of explicit override that disables it. This would be more flexible >> than a more global on/off switch. > > I'm not sure what you mean. Do you perhaps mean that the default > connection on/off switch should be per-node (which it already is in my > proposal), or that it should be per-connection (so that if there are > multiple default from node A, it's possible to disable only a subset of > those)? > > I didn't make make it possible to disable individual default > connections, because I had a feeling that it would have very messy > semantics. If default connection from A to B is disabled, what is the > routing code supposed to do when conditions change and the default > routing is re-evaluated? Can it ever reactivate the connection between A > and B again? Is the per-connection disabling handled as a blacklist of > connections that must never be automatically activated? If the A -> B route is explicitly_disabled, that overrides any default connections the routing system tries to make. -- David Henningsson, Canonical Ltd. https://launchpad.net/~diwic