[Pharo-project] Announcement real problems - please read and comment.

Henrik Johansen henrik.s.johansen at veloxit.no
Mon Apr 4 17:23:13 CEST 2011


On Apr 4, 2011, at 5:06 16PM, Igor Stasenko wrote:

> On 4 April 2011 16:38, Henrik Johansen <henrik.s.johansen at veloxit.no> wrote:
>> 
>> On Apr 4, 2011, at 1:16 29PM, Igor Stasenko wrote:
>> 
>>> On 4 April 2011 12:55, Stéphane Ducasse <stephane.ducasse at inria.fr> wrote:
>>>> 
>>>>>>>> Henrik what is your answer to problem 1
>>>>>>>> 
>>>>>>>> Problem 1
>>>>>>>>    - the second announcement was never sent, because the first one broke the second was blocked.
>>>>>>>>    >>   we should make sure that if an announcement leads to an error, other annoucements on the same emit should pass
>>>>>>>> 
>>>>>>>> Because we can get the system down just because one guy can register a bug.
>>>>>>> http://forum.world.st/Another-finalization-concern-error-handling-td2989615.html
>>>>>>> 
>>>>>>> It's basically the same.
>>>>>> ??
>>>>> Same basic problem, same solutions apply.
>>>>> I'd rather not repeat the exact same discussion.
>>>>> Just exchange "finalization" with "announcement delivery" when reading the thread
>>>> 
>>>> Igor what was exactly the summary?
>>>> 
>>> 
>>> Summary, in short, is following:
>>> 
>>> we want to iterate over some arbitrary collection and perform an
>>> action per each element, like:
>>> 
>>> collection do: [:each | each doSomeAction ]
>>> 
>>> but the problem here is that if one action triggers an error, then
>>> your loop are interrupted and no other actions performed
>>> for the remaining elements of collection.
>>> 
>>> So, we need such behavior , that guarantees that:
>>> a) all elements , except errorneous get processed
>>> b) if an error is unhandled by action , then show a debugger window
>>> 
>>> in terms of implementation this means that we should run each action
>>> in separate forked process (and Eliot described a clever scheme how to
>>> avoid most overhead of forking).
>>> 
>>> So then, even if some action will trigger an error, it won't interrupt
>>> the loop and error could be handled in debugger
>> 
>> Or instead of forking each action, simply:
>> (changed to make OC copy)
>> deliver: anAnnouncement
>>        | cls copy |
>>        cls := anAnnouncement class.
>> 
>>        "using a copy, so subscribers can unsubscribe from announcer "
>>        "Use OrderedCollection , so unwind protection is easier"
>>        self protected: [ copy := subscriptions as: OrderedCollection ].
>>        self deliver: anAnnouncement to: copy
>> 
>> (private category)
>> deliver: anAnnouncement to: subs
>> 
>>        subs do:
>>                [:each |
>>                [each deliver: anAnnouncement]
>>                        ifCurtailed: [self deliver: anAnnouncement to: (subs after: each)]]
>> 
> 
> then probably you can do it in right place - in subscription>>deliver:
> put ifCurtailed: handler.

You don't have access to the remaining subscriptions in the subscription instances.
ifCurtailed: sort of means "I'm about to terminate you (well, or do a non-local return, but that's never the case here), wanna do anything first?", so in my mind, the correct answer is the Registry saying "Hold on a bit, let me deliver to the remaining subscribers as well"

> 
>> 
>> This has the added benefits of:
>> - No thread creation overhead (Not sure if how it's written avoids creating a block for argument to each ifCurtailed call though)
>> - Reproducibility.
>>        Especially in the case Stephane gave, if you forking in separate threads, his code would appear to work when stepping in debugger.
>>        There'd be mucho frustration and grumbling over announcements failing one second, but working the next. :)
>> 
>> Downside is ofc that rest of subscribers won't be notified until you proceed/exit the debugger, but compared to reproducibility, that's a small price to pay imho.
>> 
> 
> Its really depends on use case, what is preferable behavior. For
> instance if you stall in debugger when delivering UI events, then no
> new events could be handled and you dead,
> so in cases like this you cannot afford to stop handler from
> processing events and wait for user intervention.

Oh I agree.
I'd argue that is the exceptional exception case (:D) where you'd want a specialized announcer rather than the other way around though. :)
Prolly just me, but even in this case I'd favor a stacktrace which makes sense over a system which kinda sorta keeps on working when I do something horribly wrong.

> Also, i think it would be nice to disable a subscription, so it won't
> receive any new announcements if it stopped under debugger, because if
> you don't do that, and new announcements are flowing at some constant
> rate, then you will have a tons of debugger
> windows popping out and no way to stop that :)

You'd definitely need an Error handler for that, yeah. It not mutually exclusive with using ifCurtailed: protection though.

Cheers,
Henry





More information about the Pharo-project mailing list