Introduce dependency resolution at deployment time
Nowadays, the keyword "import" defines a dependency between two Roboconf components. This dependency is resolved at start-up time. Both components can be deployed concurrently, without dependency resolution.
In some case, for example Petals Virtual Container, the dependency resolution is required at deployment time: a service assembly can be deployed only if the required Petals component are already deployed. A workaround could be to realize the deployment on the start-up phase of Roboconf life-cyle, but I think that it's not the right way.
The requirement of the dependency resolution could be expressed in graph on the keyword "import" through the optional keyword "on-deployment" used as the keyword "optional".
Example:
PetalsSEActiviti {
imports: PetalsSLPostgreSQL.* (on-deployment), ActivitiPgSQLDatabase.*;
}
I don't consider that an issue: "start" is called when all dependencies are resolved, and it's the only meaning of the "start" phase.
Ok, it is called "start", which may suggest the only thing to do there is "starting" something... but not necessarily: the real meaning of the "start" phase is "your dependencies are resolved, now".
So, leaving deploy() empty and deploying in the start() phase is perfectly legitimate, if that's what you need...
Le 12/06/2015 17:27, Christophe DENEUX a écrit :
Nowadays, the keyword "import" defines a dependency between two Roboconf components. This dependency is resolved at start-up time. Both components can be deployed concurrently, without dependency resolution.
In some case, for example Petals Virtual Container, the dependency resolution is required at deployment time: a service assembly can be deployed only if the required Petals component are already deployed. A workaround could be to realize the deployment on the start-up phase of Roboconf life-cyle, but I think that it's not the right way.
The requirement of the dependency resolution could be expressed in graph on the keyword "import" through the optional keyword "on-deployment" used as the keyword "optional".
Example:
|PetalsSEActiviti { imports: PetalsSLPostgreSQL.* (on-deployment), ActivitiPgSQLDatabase.*; } |
— Reply to this email directly or view it on GitHub https://github.com/roboconf/roboconf-platform/issues/331.
In a user point of view:
- "deploy" means "deploys my component",
- and "start" "starts my component", not "deploys my component" or other.
So it is not clear at all to write a startup script that includes the deployment on its first invocation and to keep an empty script for "deploy". Moreover, as user, I expect that stop/undeployment is symmetrical to the deployment/startup. As I can't include undeployment in the script "stop", the undeployment is located into the script "undeploy".
If your terms are not the right ones, please change them to be more user-friendly.
The more I think about it, the less I think we will support it. Considering...
- ... the current state flow to resolve dependencies for the start.
- ... the support of #332, which is relevevant IMO.
- ... the fact we can find workarounds with #515 to deploy some components before others.
This leads to the conclusion it is worth providing tailored commands for this use case rather than modifying the graph DSL. Modifying the graph for this use case would...
- ... severly complexify the state change flow.
- ... probably force us to modify our API and all the underlying principles of Roboconf.
- ... add new keywords in our DSL, with the risks of becoming incomprehensible.
- ... not guarantee (from a mathematical point of view) that the deployed application can land on its feet at the end, no matter in which order things were deployed. Today, our verifications garantee that everything will be able to start (no dead-lock, no live-lock, no glitch...).
In any case, supporting it would raise a lot of questions and require months of prototyping to (maybe) support it. That would be 95% of development efforts for less than 5% of use cases. And these few uses cases would workaround with...
- ... deploying in the start script. :ghost:
- ... group the management of some artifacts together. :skull:
- ... using a custom command (Roboconf script) in place of deploy and start all. :beers: This command could deploy critical components first, and then let Roboconf perform the easy part after.
This is just my thinkings about it for the moment. There might be also leads to resolve such a requirement with TOSCA (#163). But again, we do not have dev' resources for this, for the moment.
I'll keep on thinking about it (in background)...
OK. I have thought about it while going back home. :snail: And there may be a simple solution to this. At first, we think agents need to have all the information (about who needs what and so on).
In fact, we do not have to that complicated. Right now, we know a dependency has started since it published its variables. But we can do differently. It will result in more messages, but it will work.
In fact, when an agent publishes the variables of an instance, it should publish its state too. Variables should be published on deployment and on starting. Only deployed and/or started instances should reply to requests.
Then, to deploy an instance, we should verify deploy dependencies are resolved AND that the associated instances are correct (either deployed or started). Concerning the start dependencies, we keep the same solution than today. Not only all the dependencies must be resolved, but all the associated instances must be deployed and started.
In terms of code, the modifcations are limited. In termes of proof (everything will land on its feet), we keep the same rules than today. What applies to start is also true for deploy. It relies on the absence of cycles in runtime dependencies.
In terms of notation, we could either indicate a global property on the component (resolution-scope: deploy) or put the declaration on imported variables. I think defining this on imported variables is better.
A {
exports: ip, port;
}
B {
exports: ip, port;
}
C {
exports: ip, port;
}
D {
imports: A.*; # "start" dependencies
imports: @ds B.*; # dependencies must be resolved at "deploy time" and instances must be started
imports: @dd B.*; # dependencies must be resolved at "deploy time" and instances must be deployed and/or started
}
These two prefixes, @dd and @ds can be mixed with (optional) and external attributes.
The default behavior would be @ss, except we won't introduce a new keyword for it.
It's very interesting, your proposal is that I expected in terms of use cases.
The difference between @dd and @ds is not really clear. I think, in your example that:
-
@dsimplies the dependencyBmust be deployed and started before to deploy the current instance, - and
@ddimplies the dependencyBmust be just deployed before to deploy the current instance.
What do you mean with @ss ?
* `@ds` implies the dependency `B` must be deployed and started before to deploy the current instance
* `@dd` implies the dependency `B` must be just deployed before to deploy the current instance
That's right. First d = deployment Second d = deployed The s = started
ss = start - started
Which is the current case. We won't introduce sd which makes no sense. Start dependencies must all be deployed and started.
Nice. It's ok for me.
Perhaps can you change how to specify attributes of dependencies to use the same way for (optional), external, @ds, @dd, for example (optional, external, ds | dd | ss) ? Perhaps can you also find a better name for ds, dd ?