Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
RE: [hyades-dev] Notes on Choreography document

Thanks for all the replies on variables. Coupled with today's meeting I 
think we're close to convergence.

Regarding multiple instances of the Variable objects: I wasn't concerned 
with multiple clients sharing an instance. I was thinking of a single 
client, which might use getVariables() to learn what variables exist, then 
getRootVariableGroup to learn their UI layout structure. Now there are two 
places in the client with references to Variable instances: the array 
returned by the first call, and the array in the structure returned by the 
second. Do those references refer to a single Variable instance on the 
heap, or do they refer to separate instances? If they refer to the same 
instance, then calling getVariableValue() on either of them will update 
the single "value" Object seen through both references; if not, then it 
won't. I don't think we should leave this as an implementation-defined 
detail, because it has an impact on how you write the client.

On another subject (the exact topic doesn't matter), you wrote: "
Ultimately this is up to the agent." I don't agree. We should remember 
that we're here to write a spec. The spec is useless if it leaves too many 
things up to the implementation. A complete spec describes EVERYTHING that 
is visible to the user of the API, so NOTHING with a client-visible impact 
is left up to the implementer. A compromise from that Platonic ideal is to 
document those things that are left up to the implementation (and just how 
much freedom the implementation has), but we want to use those with care.

Regarding setVariableValue calls that fail - that is, where the agent 
throws BadValueException. You said you'd want the agent to send the old, 
unchanged value back as part of the response to a failing setVariableValue 
call. I think we should consider possible dangers with this system: if the 
old value is large (e.g. a big XML object dump), this can cause a lot of 
traffic on the wire. That traffic is wasted if the client doesn't care 
what the old value was. Maybe we should leave it up to the client to cache 
the old value, or explicitly request the value by calling getVariableValue 
after a BadValueException, if it wants to resynchronize the Variable after 
a failed setVariableValue call. And when I say "the client can cache the 
old value" I mean the client of the API we're describing here, not the 
client-side implementation of this API.

In the case where the value was changed by the agent as part of the 
setVariableValue call (for instance, to clip it to a legal maximum), then 
I agree the agent should send back the value that was actually set. 

As an exercise, I wrote a little Java function that detects and reports 
all four possible outcomes of setVariableValue, and keeps the local 
Variable instance up to date with the value it has on the agent. It's 
instructive to see how much code a client has to write to keep its head 
straight:

        // Tries to set a variable; returns a string saying what happened.
        String set(Variable v, Object newValue) {
                String result;
                Object oldValue = v.value();
                v.value = newValue;
                try {
                        hceAPI.setVariableValue(v);
                        // If that didn't throw an exception,
                        // it might still have set it to a different value
                        if ( v.value.equals(newValue) ) {
                                result = "set succeeded";
                        }
                        else {
                                result = "set modified " + newValue + " to 
" + v.value;
                        }
                }
                catch (BadValueException bve) {
                        v.value = oldValue;
                        result = "set failed: bad new value " + newValue;
                }
                catch (BadTypeException bte) {
                        v.value = oldValue;
                        result = "set failed: bad type " + newValue;
                }
                return result;
        }

-- Allan Pratt, apratt@xxxxxxxxxx
Rational software division of IBM




Antony.Miguel@xxxxxxxxxxxxx 
Sent by: hyades-dev-admin@xxxxxxxxxxx
08/26/2004 03:40 AM
Please respond to
hyades-dev


To
hyades-dev@xxxxxxxxxxx
cc

Subject
RE: [hyades-dev] Notes on Choreography document






My comments:

> ...There are five ways to get an instance of a 
> Variable: from getRootVariableGroup, from getVariableGroup, and from 
> getAllVariables and its two friends. Will all these 
> mechanisms return the 
> same Variable instance for a given variable? The document 
> doesn't say. But 
> it matters: if one piece of code uses getRootVariableGroup 
> and another 
> uses getVariable, and either piece uses getVariableValue, 
> will the other 
> piece see its value change? If I *want* that behavior, but 
> the Variable 
> instances can be different, then I need to do some processing 
> to coalesce 
> multiple instances with the same id into a single instance.

I've been thinking in terms of every time the variable is returned, to 
whatever client, through whatever means, it is always a unique instance 
- a new proxy to the variable on the agent.  If you have variables 
shared across clients then you have to start thinking about 
synchronisation and how different clients act when two clients are 
speaking to the same agent.  I think its much cleaner just to let Client 
A have a unique set of proxies to the agents' variables and Client B 
have a unique set of its own.  Then you don't have to worry about them 
modifying each others data.

There is nothing that says a variable proxy is supposed to be in sync 
with an agent - its only ever a snapshot really - so there is nothing to 
be gained from sharing two proxies.  The variable proxies that Client A 
holds are only ever modified by Client A and always represent the 
snapshot that Client A thinks they represent, rather than a snapshot 
potentially updated at random points by other clients.

> What are the possible error conditions for setVariableValue? 
> I see the 
> declaration that it throws BadTypeException but I think we need a 
> BadValueException too. 

OK, a BadTypeException would be thrown when the client asks to set a 
variable and specifies the wrong type and BadValueException could be 
thrown by the agent for any reason.  The agent should specify the reason 
for the bad value as some human readable string. 

I don't think we should go any further than this for specifying what is 
and what is not a valid value.  What I don't want is for us to add 
anything like attributes to specify the range of an integer or anything 
- if an agent requires this it should either make do with detailed 
BadValueExceptions or it should use the mechanisms already defined in 
XSD.

> Does setVariableValues act as a transaction, throwing an 
> exception and 
> applying none of the changes if there is any error? The 
> alternative is to 
> set those which have legal values, and leave the others 
> alone; but this 
> can result in an inconsistent configuration. In either case, does the 
> exception report which variable(s) in the array had bad 
> values? Remember, 
> we're driving a generic UI, so we don't have client-side 
> verification of 
> values, so we need to use the exception to provide user 
> feedback as to 
> what's wrong.

Ultimately this is up to the agent but I definitely don't think we want 
to set some values and ignore others.  The purpose of setting multiple 
variable values at once is partially because you might want to set them 
atomically to protect against inconsistent configurations, so I think we 
want to fail the entire atomic operation and return as much detail about 
problem as possible - such as which variables failed and why.
 
> I see a problem that is caused by setVariableValue taking a 
> Variable as 
> its argument, with its new "value" object already in place. 
> What if that 
> value is invalid? Remember, we've got a generic UI that 
> doesn't know what 
> range of values is valid for a Variable. If the user enters 
> an invalid 
> value and clicks "Apply," the UI will write the new value into the 
> Variable object and call setVariableValue. This can throw 
> BadValueException, but now the old value is lost. I guess the 
> UI should 
> keep the old value(s) around and restore them if setVariableValue(s) 
> throws an exception. This should be noted in the document as 
> guidance to 
> UI writers.

The UI doesn't need to do this - this can be done in the implementation 
under the interface.  There would be two things the implementation could 
do:

                 1. cache the most recent value received for this variable 
and store 
that in the Variable object upon failure
                 2. the agent returns the current value of the variable as 
part of 
the return message when a failure to set occurs,
                                 this is then stored in the Variable 
object

My preference here would be 2.  (1) it saves managing a cache.  (2) i 
think it would probably be good if an agent always returned the new 
value anyway.  This gives the agent freedom to intelligently set a 
variable based on its own logic (e.g. if a client sets an integer 
variable to 110 but the agent knows the max is 100, it could accept the 
variable set but change it to 100, returning the new value as 100. 
Alternatively it could accept it and throw an exception as a warning, 
alternatively it could leave it alone and throw an exception).  So to be 
clear, what I'm suggesting here is that a variable set is also always a 
variable get.

> I think the description of "event_based" is too fuzzy. This 
> spec will be 
> useless if it doesn't describe the behavior more exactly, so 
> agent writers 
> and UI writers know what to expect. Otherwise a client writer 
> and an agent 
> writer can have different ideas about the result of calling a 
> variable 
> "event based." I think you could say "when the event_based 
> flag is true, 
> that indicates that the UI should render the Variable as a button: 
> pressing it causes a setVariableValue call, but the actual value is 
> immaterial: the fact that the value is being set causes the 
> agent to take 
> some action." We could have more than one type of event_based 
> button: one 
> is as I just described, and another is rendered as a 
> pushbutton that's 
> "in" or "out" - a toggle. When false, say, the button is "out," and 
> pushing it sets it to true and changes the UI state. By contrast, a 
> Boolean variable could be rendered as a checkmark and not take effect 
> until the user hits an "Apply" button, which causes all 
> changes to be sent 
> at once.

This is useful but I don't want to get caught up specifying a UI here - 
it's good that we give hints to UI writers about how things should work 
but I don't want to mandate anything.  Also, I think the value of the 
variable is not necessarily immaterial.  I can imagine a complex XSD 
type describing a set of filters that works as an event-based variable. 
The client would set the filters in the variable, then hit the button to 
get a snapshot.  The agent would then get a snapshot based on the 
filters described in the complex XSD type.

> <UI design aside regarding the need for an "Apply" button>
> 
> On one call Antony described his imagined UI this way: for an integer 
> variable, the user can type a new value, and "when they click 
> away" the 
> new value is sent. In my opinion that is not a good user 
> experience. The 
> first reason is that it leaves users wondering what to do to 
> make their 
> change take effect, while an Apply button is explicit. The 
> second reason 
> is that two changes can get commingled: if a Boolean is rendered as a 
> checkmark, I suppose you'd send the change as soon as I 
> clicked in the 
> square. If I also had a pending integer change, they would 
> both be sent. 
> If the integer change was invalid, the experience is that I 
> click on a 
> checkmark and see an error message about an integer.

The experience I tried to describe was that of setting values in any 
Table widget. You enter a value, then (generally) you either hit return 
or move focus to set the value, or hit escape to exit without change.  I 
don't think that this is a big problem but I think we should recommend 
that a generic UI has an Apply button just so that a user can make 
multiple changes and then set them atomically if they deem it necessary.

One minor problem I have here is that its not a great way to get 
immediate feedback.  Attaching a slider to a control variable is a nice 
way to alter it and get smooth immediate feedback.  However, this really 
isn't necessary for a generic UI - its a specific case, so I would go 
for the Apply button which works in the general case.

I'll try and update the document and get it sent out before the HCE call 
today.

Antony

_______________________________________________
hyades-dev mailing list
hyades-dev@xxxxxxxxxxx
http://dev.eclipse.org/mailman/listinfo/hyades-dev




Back to the top