Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [buckminster-dev] Action properties [WAS Action output?]

Generally speaking I'm feeling we're continually speaking past each other. My gripe isn't really hooked up to how variability should work or not or inherited props or a lot of the other stuff we seem to drift into. I describe a use-case that as things work today will yield a behavior I consider wrong. Nothing more, nothing less. I try to detail that last.

I'm a bit confused here. Are you saying that C also has a coolselector?

Yes, that was the intent. A was just an explicit user of B and hence implicit of C.
But there are other variations on the theme that highlights the problem...

If that's the case, then surely the author of B must address that since B uses a property with the same name. In some respect that's part of B's responsibility to encapsulate C.

True. Though B maybe hasn't even realized the problem and when the situation
reaches A it could become A's problem so to speak. But sure, that's perhaps farfetched. OTOH, it's nice to be able to be protected from innocent mistakes.

Unless A has a direct dependency to C, it should not know anything about it. If it has a direct dependency then it must follow the property redirect rules stipulated (and made public) by B. I don't see a fundamental problem, nor any workarounds.

Right. But here's a variation that becomes a problem:

The dependency chain still exists. A doesn't know about C. But A now happens to use a 'coolselector' and when a user is attempting to set it for A, unwittingly we have a problem. Yes, A could change and not use coolselector as a name. But that still isn't always possible: 1) removal of that name might for some reason cause untold grief downstream making A very reluctant to change it, or, perhaps more probable, 2) shift the dependency chain a bit - Z is now the changeable part and it depends on an unchangeable A which *implicitly* depends on C through B. No one has up to now even seen the problem but it suddenly surfaces.

Farfetched? Hmm, not really - it's a boundary condition, but a valid outcome with the type of support we're discussing (unless we take steps now to prevent this type of unintentional problems).

What I mean is uncommon is the case where you need to pass different *runtime* properties to different actions in the same invocation.

Uncommon, yes, but we're already defining that it is *possible* to run several actions with one invocation; the first is natural caused by dependencies, the second is made possible to, among other things, invoke actions for >1 top component in a given workspace, i.e. for two completely different chains. In especially the second case, it's probably completely wrong to pass in the same set of properties to both cases, regardless.

We do need to introduce the variability that and the ability to qualify requirements that we outlined in the diagram but I'm perfectly happy to make that the next step and to postpone the discussion about runtime injection into such variables. Once that's in place, perhaps we have another view of the need to influence the mechanism in runtime.


So I'm saying we need to define how it works now, rather than just 'accidentally' allow some way it works, and later get problems redefining that when people have already established ways of dealing with it.

There's a lot more to it, and that we can talk about later, but not the fundamental isolation I'm after.

As for component isolation, yes absolutely. Passing of 'properties', 'arguments', or 'variables' must be a very controlled process and it cannot use arbitrary names either. The variability will be about things like operating system, java version, debug versus optimized, etc. They will be part of (and indeed modify) the requirement (and hence the expected import) so that if A and B are both dependent on C but uses different variables in their requirements, then C must be built twice and cater for that it's output ends up in different sub-folders (just an example that highlights the need for more elaborated design details).

Situations where name conflicts occur may of course arise anyway so whatever we come up with must be able to deal with that.

But the whole point is to minimize or even remove the possibiliy of *unintended* name conflicts. It's as simple as that.


An attempt to conclude (for now):
When we say 'properties' henceforth, can we agree that it's a fairly crude way of passing arguments to a build process

Absolutely! But that realization is completely irrelevant to the issue at hand. We have selected to support properties as the means of communicating variable information to a *generic* actor at this time, so that's what we have to work with. At a later date I could imagine a more advanced actor definition that makes use of more structured information of course.

and perhaps also agree that there's only one global property set and that the context/action properties will act as overlays on that set?

Hmm, no, can't agree to that as it's not correct as to how it works right now.

What 'global' properties are you talking about? I'm guessing that it is the set generated by Buckminster for pointing to the home (and where we started, the output root) etc. If so, that is not overlaid, quite the contrary. Or, perhaps you're referring to what I below call 'runtime properties'. If so, it is used to overlay, not be overlaid. Anything else is not there right now?

Starting from the most outward point: IPerformManage.perform(). Into this we can pass a list of component/action pairs, right? (doing so will currently yield an NotImplementedYetException, but but let's assume it is implemented).

The second thing we pass in is a *single* set of properties. This is frequently empty, but with a command line (or its UI 'equivalent') of 'perform -D foo=bar C1#A C2#B' the set will contain the single pair of foo=bar, correct? Let's call this set the 'runtime properties'.

Let's assume that component 1 (C1) and 2 (C2) are two top components to two completely separate chains. Assume that both the A and B action use the 'ant' actor.

Eventually the actor for A will get called with the runtime properties in the perform context.

Among all the things the Ant actor code does (and we have already established that this should really be moved to a more general place, but that is beside the point right now) is to: 1) populate an empty map with any properties defined in the cspec for that action 2) It then populates the same map with the runtime properties (so this overlays any 'foo=...' that was present in the cspec) 3) Finally, we overlay the map with a number of Buckminster generated properties (we do this last specifically so they can't be overridden).

(somewhere in all this is where inherited properties might come in etc etc, but it doesn't change the issue)

The final map is now reflected in the Ant build script for A, and presumably the script makes references using '${foo}'.

All good. But eventually the PerformManager code will start the B action. And here's the whole point: *any* action (and actor) invoked, including dependencies to A and B, will get a copy of the same runtime properties. I think this is wrong - it does not give isolation. At best it's completely benign (B doesn't care about 'foo' one way or another), at worst B get's hopelessly confused by the content of foo. There's no way to solve this by declaring anything in A since they are not in the same chain. Your argument might be 'well, so invoke A and B in separate perform calls'. Sure - but then we should forbid the usage I describe, it isn't forbidden now.

The outermost interface simply doesn't give us a way to pass in multiple runtime properties appropriate for the multiple given actions. I think it should. That would make it completely possible to call A with one set, appropriate for it, and B with another set, appropriate for that. No possible 'leakage' between them. In general, all other property interaction between actions is controlled by all the fancy rules of inheritance, variability etc. The downside is of course that the headless command must allow for expressing all this...

It's debatable whether it should be possible to inject runtime props to actions not specifically listed in the call (i.e. for actions called as a result of dependencies).

There is obviously solutions to all this, but everything has a benefit and a drawback. We need to select the design, and then work with the consequences.

ken1


Back to the top