This is the mail archive of the frysk@sources.redhat.com mailing list for the frysk project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: the status automation machine graph for frysk


Hi Mark,

Thanx for all the observations. It looks like we share alot of the same concerns about
the TaskState state machine. I added some comments to yours and some conclusions
that I came up with. Please correct me if am wong.
- There is no good overview of all the possible states:
Agreed :). Well there probably is, but not all the classes follow it which makes it hard
to deduce.
- Some are defined as static (inner) inner classes
I would say that the (inner) inner classes are/should be for transitional states. So for example
if I need to Attach and there are several stages to that, then each stage is represented by an (inner)
inner class.
- Others are defined as anonymous inner classes
Hmm.. Cagney can probably give a better answer to this. My conclusion from previous code
is that leaf states (which are {not/not mean to be}inhereted from) are anonymous inner classes and parent classes
are proper classes. One thing to be noted is that some states are sharable ie they dont save any
information about the current state, and so one instance can be used.
- There are a couple of State classes that are never actually used
themselves, but that are only used to derive more specific (inner)
State classes from but that aren't marked abstract.
These should be made abstract.
This means that some states are visible in the api docs, while others
are not and that some that do exist are never actually used.

- Some state transitions depend on and manipulate "external state" like
the Task.blockers list field.
Yup
It isn't immediately clear whether these fields can or cannot be
manipulated outside an state transition between TaskStates. Or if a
Tasks state is really defined by the TaskStates or whether there is some
other parts of state for a Task and Proc that might or might not be
visible/used by the TaskStates when handling state transitions.
I dont think the state is religiously described by TaskState. Some information is
orthogonal to what TaskState is trying to keep track of. Observers, blockers, pid
of parent class etc.
- Some methods like handleAddObserver() and handleDeleteObserver()
always do the same thing and never actually do any state transition.

This adds a lot of (duplicate) code without being clear what it has to
do with with the actual state machine.
Duplicate code worries me too. Inheritance is a solution but as Cagney as mentioned
before: the flat code is easier to read. Also I would much prefer that I accedentaly forget
to implement a function casing frysk to crash than accidentally pick up a function from a
parent and do incorrect handling.
Just thought I would write these observations and send them to the list
for others studying this part of the code and maybe to get some feedback
on some if the design because I still don't have a very good feeling for
the real working of the task state machine.
All the bad code I think is probably a reslut of the fact that the state machine is desigen bottom
to top as oppose to top to bottom. I.e. i find that I am missing a so I go and add it somewhere possibly
with only a partial view of the big picture. The good news is that the state machine is easy to refactor
and we have a test sweat in place that insures that refactoring does not break frysk.


Here is a general overview of the TaskState machine as i understand it for what its worth :)

Ignoring all the bad code and state machine crud, the TaskState machine is concerned with add/removing
observers, notifying those observers, blocking/continuing the task if the user requests that. All these states
are trying to service those needs. One simple circle for example is that a task is running it recieves a signal
event it notifies observers of the signal event from there the task can go back to running or go to blocking
each one of those is represented by a state. Running just continues to run waiting for the next event. Blocking
expects to be unblocked by the observer which blocked it sending it back to the running state.


Thanx for all the observations. The state machine is certainly not in its final state and could use a lot of refactoring.
The best way to understand it I found is to write a test case and start hacking :)


Happy hacking :)
 Sami


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]