Dynamic Management: Dynamically modifying the hierarchy
So far we saw that DIET’s hierarchy was mainly static: once the shape of the hierarchy chosen, and the hierarchy deployed, the only thing you can do is kill part of the hierarchy, or add new subtrees to the already hierarchy. But whenever an agent is killed, the whole underlying hierarchy is lost. This has several drawbacks: some SeD will become unavailable, and if you want to reuse the machines on which those SeD (or agents) are, you need to kill the existing DIET element, and redeploy a new subtree. Another problem due to this static asignement of the parent/children links is that if you have an agent that is overloaded, you cannot move part of its children to an underloaded agent somewhere else in the hierarchy without once again killing part of the hierarchy, and deploying once again.
And thus it began to evolve
Hence, DIET also has a mode in which you can dynamically modify its shape using CORBA calls. For this, you need to compile DIET with the option DIET_USE_DYNAMICS. In this mode, if a DIET element cannot reach its parent, when initializing, it won’t exit, but will wait for an order to connect itself to a new parent. Hence, you do not need to deploy DIET starting from the MA down to the SeD, you can launch all the elements at once, and then, send the orders for each element to connect to its correct parent (you do not even need to follow the shape of the tree, you can start from the bottom to the tree up to the root, or use a random order, the service tables will be correctly initialized.)
You now have access to the following CORBA methods:
- long bindParent(in string parentName): sends an order to a SeD or agent to bind to a new parent having the name
parentName » if this parent can be contacted, otherwise the element keeps its old parent. If the element already has a parent, it unsubscribes itself from the parent, so that this latter is able to update its service table and list of children. A null value is returned if the change occured, otherwise a value different from 0 is returned if a problem occured.
- disconnect(): sends an order to disconnect an element from its parent. This does not kill the element, but merely removes the link between the element and its parent. Thus, the underlying hierarchy will be unreachable until the element is connected to a new parent.
- long removeElement(): sends an order to a SeD to kill itself. The SeD first unsubscribe from its parent before ending itself properly.
- long removeElement(in boolean recursive): same as above but for agents. The parameter
\verb|recursive| » if true also destroys the underlying hierarchy, otherwise only the agent is killed.
Now, what happens if during a request submission an element receives an order to change its parent? Actually, nothing will change, as whenever a request is received a reference to the parent from which the request originates is locally kept. So if the parent changes before the request is sent back to the parent, as we keep a local reference on the parent, the request will be sent back to the correct
parent ». Hence, for a short period of time, an element can have multiple parents.
WARNING: currently no control is done on whether or not you are creating loops in the hierarchy when changing a parent.
Dynamic Management: Changing offered services
A SeD does not necessarily need to declare all its services initially, before launching the SeD via diet_SeD(...). One could want to initially declare a given set of services, and then, depending on parameters, or external events, one could want to modify this set of services. An example of such usage is to spawn a service that is in charge of cleaning temporary files when they won’t be needed nor by this SeD, nor by any other SeD or clients, and when this service is called, it cleans whatever needs to be cleaned, and then this service is removed from the service table.
Adding a service using diet_service_table_add(...) you can easily add a new service (be it before running the SeD or within a service). Well, removing a service is as easy, you only need to call one of these methods:
int diet_service_table_remove(const diet_profile_t* const profile);
int diet_service_table_remove_desc(const diet_profile_desc_t* const profile);
So basically, when you want to remove the service that is called, you only need to pass the diet_profile_t you receive in the solve function to diet_service_table_remove. If you want to remove another service, you need to build its profile description (just as if you wanted to create a new service), and pass it to diet_service_table_remove_desc.