I still think our notification story is pretty awkward -- it's confusing
to know when to use a monitor, when to use a notification, what is
synchronous, what is asynchronous, and what kind of changes cause which
kinds of notificaitons/monitors to fire and what the performance trade
offs are. I'm petty sure I don't have all the details straight in my
mind, so I suspect other people will be confused also.
Andi Vajda wrote:
Maybe we should get rid collection notifications and use monitors
instead since notification don't do what we need -- what do you think?
I think collection notifications fill a specific need and monitors
another more general need.
- Ted and you invented collection notifications because you wanted to
know
whenever an item belonging to a collection changed and you wanted
code to
react to these changes when the system was ready - asynchronously, for
example when idle.
Collection notifications are sent out when polling for changes.
It's confusing that some notifications are synchronous and some are
asynchronous (requiring polling). I'd prefer to always have synchronous
notifications -- because you can always turn them into asynchronous
notification if you want. Nothing about the way notificaitons works
today is UI specific -- it's only that the UI is a client of notifications.
- Monitors are more general, are synchronous and don't depend on the
UI. A
monitor method is told about an attribute value change synchronously,
immediately after it occurred. No polling is necessary. Monitors are
dispatched by operation - 'set', 'remove', 'schema' at the moment -
and by
attribute name.
Both devices have drawbacks:
- Misusing or abusing collection notifications is going to cause us
to create
more collections than needed and is going to create unmet
expectations as
these are sent out from the UI only, asynchronously. UI-less unit
tests,
for example will not have them.
- On the other hand, abusing monitors is going to slow down the
system as all
monitors for a given (op, attributeName) tuple are invoked for
every change
to an attribute's value.
I think both devices serve a purpose and should be used sparingly as
they are both hard to debug and trace. Monitors fire sometimes when
you least expect it and can be recursive. Collection notifications
will sometimes not fire, also when you least expect it.
Yet, both patterns, allow for some pretty convenient and powerful
constructs, so, in a word, buyer beware, use the right tool for the
right task.
Now, to Alec's question. If I understood it right, Alec was asking to
be told when the color of a colored collection changed, not when the
color of an item in that collection changed, something quite
different. Unless that collection - an item itself - belongs to a
collection too, no collection notification is going to fire for that
change. It seems that a simple monitor would be very well suited for
this task.
I'd like to have the option to get notified about these kinds of changes.
Yet another way to do solve Alec's problem is instead of defining a
'color'
attribute on a collection item - I've argued many times in the past
that it didn't belong there - one could use a mixin kind defining that
attribute along with a mixin class with relevant code to react to
changes to that 'color' attribute in an onValueChanged() hook method.
This approach is by far the most efficient from an execution path
standpoint.
It also seems that PJE's annotation API would make this trivial to
implement from a developer's point of view.
I recently remembered that collections are contentItems because they are
displayed in the UI, consequently, they have UI attributes, like
displayName. I suspect it's going to be rare to have a collection that
would never be displayed in the UI
Andi..
John
Andi Vajda wrote:
John/Ted -
So right now the way notifications work is if any items in a
collection
get modified/etc, then a notification goes out to subscribers.
In the case of color, I'm actually interested in getting notified when
the 'color' attribute on the collection itself, not a member of the
collection, is changed. I can change it via a menu right now, but the
calendar code doesn't know the color changed, so it doesn't know to
redraw.
what would you guys think about making notifications fire for both the
collection items, as well as changes to the collection itself?
Don't use notifications for that, use a monitor.
For example:
class AlecsItem(Item):
def aColorChangedSomewhere(self, op, item, attribute):
if op == 'set' and isCollection(item) and attribute ==
'color':
print 'gosh, a colored collection changed to', item.color
Attach the monitor:
Monitors.attach(alecsItemInstance, 'aColorChangedSomewhere',
'set', 'color')
Et voila. Monitors are persistent so you only need to set this up once.
Collection notifications, as implemented today, are a UI-only device
fired from the wx event loop's OnIdle() method. They are
asynchronous and rather heavy as they are broadcast all subscribers
of a set, indiscriminately.
Monitors are synchronous and broadcast only to items monitoring the
given op/attribute combination.
Andi..
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
Open Source Applications Foundation "Dev" mailing list
http://lists.osafoundation.org/mailman/listinfo/dev