[KCP] Thoughts on adding system changes and refactoring ChangeSet

Stephen Pair stephen at pairhome.net
Wed Jun 25 03:23:22 UTC 2003


Andreas Raab wrote:

>Stephen,
>
>  
>
>>If the operation puts a heavy load on the system, then I 
>>don't think you should force that on a user no matter what 
>>the auto-update mechanism is.  Better to use a "refresh" 
>>button in those cases (or name the button "Run Query" if 
>>"refresh" is a turn off ;)).  When I accept a method, I 
>>wouldn't want that to take an extra 20 seconds because it's 
>>told 10 different GUIs to update long and complicated queries.
>>
>>(Keep in mind that a polling solution (such as morphic) can 
>>dynamically adjust the polling interval based on how long a 
>>cycle takes to compute)
>>    
>>
>
>So can an event driven mechanism. It just has to measure how long it takes.
>

Yes, in that case you need an event system that is designed to drop 
events (when they arrive too fast to be handled).

>>One thing that bothers me about notification systems is that 
>>you have to anticipate in advance what events someone might 
>>be interested in.
>>    
>>
>
>Unless, of course, you can derive the events dynamically - which in fact is
>*very* doable up to a certain point. After which you can still fall back on
>polling and do this invisibly if you want. What you really need here is an
>understanding of where the tradeoffs for events vs. polling are - if you
>have some sort of "uncertainty principle" (e.g., you cannot observe when
>EXACTLY something happened) then polling and events are interchangeable and
>can be treated uniformly. Up to the point that you can use a condition as an
>event.
>

Yes!  Exactly...this uncertainty principle is key...you must accept up 
front that you can *never* be instantly notified when an event 
happens...you can only be told that some event happened at some point in 
the past.  To many systems seem to gloss over that fact.

>>I've seen this taken to an extreme in some 
>>systems to the point where every setter in the system 
>>triggers an event.
>>    
>>
>
>And they should! A state change of some property or other is about the first
>thing you want to watch for (in Tweak all variable stores generate an event
>- this happens automatically so the programmer isn't burdened by it and you
>can simply say "do this when that variable changes its value").
>

Yes...I agree.  A system should allow you to observe any arbitrary 
property of any object...the key phrase is that the programmer musn't be 
burdened by it (which isn't the case with the systems to which I was 
referring).  If a programmer has to decide up front what properties 
someone might be interested in, then I think you lose a lot (in terms of 
having independent systems that can be freely combined to create new 
systems).

>>As these systems grow more complex, you 
>>start to run into very complex event timing scenarios, 
>>endless event propogation loops, and the like.  It would be 
>>nice if we could come up with a more general, loosly coupled, 
>>and good performing system.
>>    
>>
>
>Do you have any first-hand experience with those problems? I'd be
>interesting in chatting about this a little more. So far, the only real
>issue I've found was "delayed state propagation" and I'm going to do
>something about this (it's quite simple, I just haven't got around doing
>it).
>

Yes...as best I can remember, here are some challenges that I encountered:

 - process safety issues - as you mentioned before, you want event 
notification to happen asynchronously...if you push these events to the 
end of some process, and the process is long running, you end up with 
non-responsive UIs (i.e., a process takes 5 minutes run, you want to use 
events to observe its progress and display a progress bar, events pile 
up and are pushed to the end of the process, progress bar starts at 0%, 
stays there for 5 minutes, then instantly jumps to 100%)...to alleviate 
that, you start processing the events in background processes...now you 
get into process safety issues (which is not a fault of the event scheme 
itself, but of the overall lack of process safety in the system).

 - events propogating in endless loops - you have to be very diligent to 
ensure that events don't trigger behavior that ultimately triggers the 
original event again.  Example: you have a Person object and a 
PersonMorph for displaying/editing that person...a nice design to keep 
these two objects synchronized, yet loosely coupled is to have an 
abstraction of the internal structures of these two objects (essentially 
creating a flattened view of each of them, exposing some properties of 
each network of objects)...you then "wire" the zipcode property of the 
Person to the zipcode property of the PersonMorph (internally, the zip 
code would be properly factored into separate objects of course)...if 
the zipcode property of either changes, the zipcode of the other is 
updated...however, you must take great care to ensure that the "wire" 
prevents event back propogation (ie. zipcode of the Morph changes, 
notifies zipcode property of Person, it changes, notifies zipcode 
property of the Morph....and so on).

- tools, tools, and more tools - what we ended up really needing were 
tools that help you visualize event propogation and to construct and 
manage "value networks" (a VW term).  We did exactly that and it did 
help, but we could have used even more tools (particularly some debugger 
enhancements would have helped).  We had the concept of a component that 
was a flattened view of a network of objects...we had a syntax that 
would allow you to describe the structure of a network of objects 
(starting with one subject object)...from that description, we would 
construct a value net (and we had a richer set of adapters in our value 
net than many other systems) that was basically a mirror image of the 
objects behind the subject object.  Different properties of the network 
of objects would be exposed by the component as if they were properties 
of its own (and which also supported event registration).  This would 
allow users of the component to be very decoupled from the underlying 
structure of the subject object.  I've seen some of these same ideas in 
several GUI frameworks, but none of them really did them well...some of 
them used a lot of code generation, others just didn't go far enough to 
make it really useful (including ours).

This in combination with a transactional system (each component could 
have a transactional context) enabled us to create UIs with very little 
work and in a very short period of time.  The framework would allow us 
to open two UIs on the same system of objects and have every aspect of 
the two UIs fully synchronized (text boxes, scroll bars, check 
boxes...everything)...if you wanted to keep the two UIs in isolation, 
you simply opened them in the context of separate transactions (OK and 
Cancel translated directly into Commit and Abort).

- Stephen




More information about the Squeak-dev mailing list