[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.

I agree, I think good progress has been made over the past week or two, 
with similar progess this week we might be able to close by the next HCE 
meeting.

> 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.

I would think that they still refer to separate instances.  I can't 
think of a case where a client would have a good reason to get a a list 
of all the variables and then get the structure separately (if need be 
it could build a list from the structure without the expense of a second 
transaction).  If it cares about the structure it should just get the 
structure.  If it doesn't then it can ignore it and just do 
getAllVariables.  In the case where you might have a client that exposes 
variables to the UI AND uses them programatically then you've still 
really got two clients using their own handles to the variables.  The UI 
will update its values as it sees fit and the programmatic client may 
tell the UI to update as necessary, e.g. when it changes a value and it 
wants the change to be reflected in the UI.  Sharing instances doesn't 
get you automatic updates to the UI, it just gets you values changing 
randomly underneath either 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.

I get your point but sometimes a spec can recommend behaviour as being a 
good and safe default rather than mandate it.

> 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.

I agree, we don't gain much from sending the value back in the error 
case - the client was trying to set the value anyway so it shouldnt care 
about the current value.  I also agree about the client caching - its 
basically up to the client to manage the value that is in their Variable 
proxy.  If they don't want the extra code to manage it they need only do 
a getVariableValue call to update it.

I'll send round an updated version of the document today.

Antony
 
> 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
> 
> 
> _______________________________________________
> hyades-dev mailing list
> hyades-dev@xxxxxxxxxxx
> http://dev.eclipse.org/mailman/listinfo/hyades-dev
>