Closed bjhargrave closed 12 years ago
Comment author: david.savage@paremus.com
Discussion on bug BZ#2088 uncovered (hopefully) a final ambiguity in the current API. What is the expected result of resolving a resource which appears in the wiring.
The scenario discussed on the conf call on 25/08/11 was the following:
Start Wiring: Empty Resolve: Resource A Environment.isEffective = resolve Result: Wiring A (map contains Resource A)
Now resolve same Resource A again
Start Wiring: Wiring A Resolve: Resource A Environment.isEffective = resolve + test Result: ?
In this case the resolver is being asked to resolve a resource that is already found in wiring A but with different effective requirements.
Three options I can think of:
1) Result is the new wires that are created, or empty map if no new wires are created 2) Result is the empty map as the wiring already contained resource A 3) Throw exception - attempt to resolve already wired resource
I'd been thinking along the lines of 1) but this didn't match with Tom's expectations, I could live with the other options too (preference for 3) but we should decide which it is to be.
Comment author: Richard Hall <heavy@ungoverned.org>
I'd say (2) since the resolver's job is done. We cannot spec that people implement additive resolver algorithms, I don't think. It seems to complicate things because now the resolver cannot know whether something is resolved by just looking in the wire map, it has to check to make sure that no new requirements were added.
What would then prevent an Environment from wanting to add requirements incrementally to a resource? For example, each time some other requirement selected the resource as a candidate, the Environment could expose even more requirements on the Resource.
Besides, there is already a way to do this if you want: implement a environment that allows you to batten down the candidates to a previously calculated result and then re-run from scratch with the new effective time.
Comment author: @bjhargrave
What would then prevent an Environment from wanting to add requirements incrementally to a resource? For example, each time some other requirement selected the resource as a candidate, the Environment could expose even more requirements on the Resource.
I think we need to define objects of the o.o.framework.resource package types as effectively final such that, once they are created, calls to their methods must return the same result every time. This is critical with respect to the equality contract (see bug BZ#2091).
Comment author: @bjhargrave
effectively final
I meant effectively immutable.
Comment author: david.savage@paremus.com
What would then prevent an Environment from wanting to add requirements incrementally to a resource? For example, each time some other requirement selected the resource as a candidate, the Environment could expose even more requirements on the Resource.
I think we need to define objects of the o.o.framework.resource package types as effectively final such that, once they are created, calls to their methods must return the same result every time. This is critical with respect to the equality contract (see bug BZ#2091).
Yep I agree, I'm not sure we can prevent people doing stupid things with the API but we should at least say the results are undefined if the Environment or Resource objects change during a resolve operation. This was part of the reason why I was against isEffective, but hey ho life goes on :)
However the issue I was originally raising is slightly different. Here the model is immutable during a resolve operation but the Environment.isEffective is different between subsequent resolve operations so immutability still doesn't fix this problem.
Comment author: david.savage@paremus.com
I'd say (2) since the resolver's job is done. We cannot spec that people implement additive resolver algorithms, I don't think. It seems to complicate things because now the resolver cannot know whether something is resolved by just looking in the wire map, it has to check to make sure that no new requirements were added.
So this makes me quite nervous, this means that if I want to re-resolve an existing wiring with new effective states I can't do this? I need to start again from scratch. What if I just want to transition a wiring from effective=resolve to effective=resolve+test this may only bring in one extra requirement in the entire graph but I now need to blow away my framework and start again - seems wrong but I could be missing something.
On the plus side of this approach I agree there's an optimisation for the resolver if it can just ignore existing resources it finds in the wiring map.
What would then prevent an Environment from wanting to add requirements incrementally to a resource? For example, each time some other requirement selected the resource as a candidate, the Environment could expose even more requirements on the Resource.
Besides, there is already a way to do this if you want: implement a environment that allows you to batten down the candidates to a previously calculated result and then re-run from scratch with the new effective time.
Agreed, assuming you have the previous iteration still available, if not you need to manually unpick the existing wiring and call it again. If we go this route for a client to unpick an existing wired resource is a case of following the transitive dependencies and removing all the wires from the map. Not impossible but seems to be a duplication of code used by the resolver.
Comment author: Richard Hall <heavy@ungoverned.org>
So this makes me quite nervous, this means that if I want to re-resolve an existing wiring with new effective states I can't do this? I need to start again from scratch. What if I just want to transition a wiring from effective=resolve to effective=resolve+test this may only bring in one extra requirement in the entire graph but I now need to blow away my framework and start again - seems wrong but I could be missing something.
Not sure why this approach bothers you, we've already agreed that this is what you'd need to do for dynamic imports and for greedy fragment attachment.
On the plus side of this approach I agree there's an optimisation for the resolver if it can just ignore existing resources it finds in the wiring map.
Optimization, sure, and simplification of the algorithm.
Agreed, assuming you have the previous iteration still available, if not you need to manually unpick the existing wiring and call it again. If we go this route for a client to unpick an existing wired resource is a case of following the transitive dependencies and removing all the wires from the map. Not impossible but seems to be a duplication of code used by the resolver.
Not sure what you mean. If you have a resource with its wires, then you have everything you need. Just tell your environment that this is the "initial state", so whenever it is asked to find a provider for a Requirement from the given Resource, it only answers the already selected Capability from the already selected provider Resource.
Comment author: Richard Hall <heavy@ungoverned.org>
Agreed, assuming you have the previous iteration still available, if not you need to manually unpick the existing wiring and call it again. If we go this route for a client to unpick an existing wired resource is a case of following the transitive dependencies and removing all the wires from the map. Not impossible but seems to be a duplication of code used by the resolver.
Not sure what you mean. If you have a resource with its wires, then you have everything you need. Just tell your environment that this is the "initial state", so whenever it is asked to find a provider for a Requirement from the given Resource, it only answers the already selected Capability from the already selected provider Resource.
For the case of "unpicking", I would assume it is only necessary to not return the undesired provider for the top level requirement. But if you had a whole bunch of unpicking you wanted to do, I don't see how this is any more difficult that creating a blacklist in your Enviroment that you use to filter specific providers for specific requirements and then re-running.
Comment author: Tim Diekmann <tdiekman@tibco.com>
eeg call 02/29/12, agreed to close
Original bug ID: BZ#2089 From: david.savage@paremus.com Reported version: R5