On 12/14/2012 06:00 PM, Jiří Stránský wrote:
On 14.12.2012 13:52, Martyn Taylor wrote:
On 12/13/2012 04:44 PM, Jiří Stránský wrote:
On 11.12.2012 12:41, Martyn Taylor wrote:
Gentlemen,
We discussed how to model state transitions in the ReST API in the
Tech Cabal and also offline for those who had particularly strong
views. One of the objections brought forward was how to
distinguish between clients (end users or applications) requesting
state changes. For example: A developer decides he wants to
terminate his running instances and system services that are used
to notify conductor of when an instance has changed state. For
example db-o-matic wants to tell conductor that the instance has
now started.
After some deliberation offline between myself and sseago and
without objections from the Tech Cabal. We decided that the
services and the end users should access different APIs and we
should not add complexity into the end user API in order to support
these system services.
This (and the detailed explanation what Scott wrote) makes perfect
sense to me.
With this behind us. We then were able to move forward to make a
decision on how to handle requests from a user to transition
between states. Like in the developer example above.
It was agreed that treating the State on an instance as simply an
attribute on the resource (and not an action) was more inline with
the ReST principal (Since adding actions breaks ReST principal of
having a unified interface - in our case the unified interface is
defined by HTTP).
So, this now brings us to how we should represent these resources.
I think this is something that can and should be decided on list.
I have included below my opinion on how this should be represented,
please add in your own comments.
==
So in my opinion we should model a state machine as an independent
resource. When client wants to change the state of an instance,
it looks at the state machine to figure out what are the possible
states I can move to now. The instance can hold a reference to it's
current state and the state machine.
A simple example here: https://gist.github.com/4257951
I wonder whether we really need to model it in such detailed/complex
way.
* Modeling states as full resources with IDs assigned feels a bit
forced to me.
* Do we want/need to expose the full state machines to clients? Is,
and will it be in future, that current state is the only variable
that influences current possible state transitions? Should the
conditions get more complex than this, then exposing the full state
machine correctly as XML might become quite difficult. I don't think
we want to sign up for this unless there is a use case for it that I
fail to imagine now. I kinda hope that exposing the currently
available transitions on each instance should be enough. (CIMI also
doesn't expose more information than currently available
transitions, unless I overlooked it.)
I understand you intent here, looking to see how others do things is
a good way to do a bit of research. However, just because CIMI,
GitHub or DeltaCloud do something one way, it does not mean it is
right or a good fit for our project. CIMI uses a different approach
for representing state transitions, it actually has an "action"
resource, which is just a hacky way of getting round the Unified
Interface principal of ReST.
To answer your state machine question.
There are a couple of advantages of expressing the state machine as a
separate entity over simply adding state transitions to an instance.
* Since the state machine is consistent across conductor.
- The client only needs to download it once.
- We do not need to return this information on every single instance.
* Having a state machine allows clients to look more than one state
ahead.
- The client can inspect the state machine and immediately figure
out what it can do.
- The client does not have to start an instance to figure out what
it can do.
Another advantage of representing state as a resource in the gist I
provided, is that the state machine is also optional. If the client
decides it wants to inspect the instance and work that way it can do
so, since the state is referenced from the instance object.
The thing I'm worried about the most is that your model (and the
"client only needs to download it once" approach) assumes that for a
given state, there's always the same set of available transitions. I'm
kinda worried this might not be the general case in future. (Say, you
might have an instance in some "failed" state, and sometimes the
instance might be startable, sometimes not. <-- I don't know if this
exact example can happen or not, please take it just as an example :))
There are two things to consider here:
1) Is it one of the goals of Aeolus to create a single workflow/state
machine for all clouds? If so then it would make sense to have 1 state
machine. (I'm sure I've heard this discussed in the past)
2) It depends on where this state machine lives. If we do decide to
allow different workflows depending on the Cloud provider then we can
simply have 1 state machine per provider, per realm or whatever makes sense.
I think that we don't even have the possible transitions from a given
state defined in Conductor, I think they are fetched from the provider
through Deltacloud [1,2] each time they are needed. (Not sure about
it, the code around instances is vast and I only had little time to
study, but it seems to me that way.) If that's correct, it would mean
that controlling what state transitions are available at a point in
time is out of our scope of influence, not to mention "looking more
than one state ahead". Therefore constructing a state machine that
could be fetched once and used from that point on might not be even
possible.
Have a nice weekend,
J.
[1]
https://github.com/jistr/conductor/blob/4f8ceda803d6d7eee84a06475fc9cefad5ca0b55/src/app/models/instance.rb#L166
[2]
https://github.com/aeolusproject/conductor/blob/f1192ed2ac52d68aece808eb9d5ffdea7965eb23/src/app/models/instance_task.rb#L71