On 26.04.2011 17:37, Igor Stasenko wrote:
On 26 April 2011 15:11, Henrik Sperre Johansen
<henrik.s.johan...@veloxit.no>  wrote:
On 24.04.2011 12:05, Stéphane Ducasse wrote:
i am puzzled. You wanna to be sure that ensure block are executed?
It is.
I want to write a test that shows and tests the withOrganizer:do:
semantics.
In particular that the ensure is executed and that the context set by the
withOrganizer: is only present
in the do: block.

In other words, another use case probably written more cleanly using the
non-existing
Announcer>>  #suspend: subscriber while: aBlock

What is potential implementation?

Announcer>>suspend: subscriber while: aBlock
  | subscriptions |

subscriptions := OrderedCollection new.

registry subscriptionsOf: subscriber do: [:each |
   subscriptions add: each
].
registry removeSubscriber: subscriber.

^ aBlock ensure: [ subscriptions do: [:ea | registry add: ea ] ]


The problem is that its not doing exactly what is said:
  - it suspends existing subscriptions instead of suspending subscriber.

The difference between those are subtle but important:
   a suspended subscriber should not receive any announcements during
block evaluation,
even if it may want to subscribe to new ones during given block evaluation.
And the code above not handling this case , as well as it doesn't
handling the case when subscriber may want
to occasionally unsubscribe from some announcements during block evaluation.

So, for doing this correctly, a subscription registry should keep a
list of suspended subscribers somewhere,
and then in #deliver:
it should check if subscription's subscriber are not in that list, and
only then let it deliver an announcement.

The problem is that delivery time will slowdown considerably, because
for every subscription you should check
if it's subscriber are not in 'suspended subscribers' list.


So, it is really depends on intent. Suspending a concrete subscription
will require adding 'suspended' flag to subscription state.
But suspending a concrete subscriber and to guarantee that it won't
receive any announcements (even if it will subscribe for
a new ones during suspension time), can't be solved by having
'suspended' ivar on subscription. You have to manage suspended
subscribers list separately.

That'a a rather farfetched usecase it'd be nice to note in a method comment is NOT supported at the moment, nothing more imho :)
Simply providing something like:

suspend(SubscriptionsOf): subscriber while: aBlock
|oldSubs|
oldSubs := subscriptionRegistry removeSubscriber: subscriber.
aBlock ensure: [oldSubs do: [ :each | subscriptionRegistry add: each]]

is better than nothing.

Cheers,
Henry

Reply via email to