Re: DataContext delegate?

From: Andrus Adamchik (andru..bjectstyle.org)
Date: Fri Oct 03 2003 - 01:42:45 EDT

  • Next message: Giulio Cesare Solaroli: "Re: I am missing Expression architecture..."

    On Thursday, October 2, 2003, at 04:29 AM, Dirk Olmes wrote:

    > When EOF saves changes to the database, all peer EditingContexts are
    > notified and try to merge the changes written to database back into
    > their existing
    > EOs. To ensure object graph consistency this notification has to be
    > delivered
    > synchronously because if it was delivered from a different thread the
    > point
    > in time that object graph synchronization occurred was undefined.

    Actually my primary motivation for asynchronous notifications was to
    use it for the newly developed snapshot cache. In scenario when
    DataContext #1 commits changes, it synchronizes committed snapshots
    with parent snapshot cache (not via events, but simply via a method
    call), and then snapshot cache sends an asynchronous change event to
    all child contexts #2, #3, etc., allowing all children to update their
    objects state, and without having the calling DataContext wait till all
    events are processed.

    Now that you've mentioned the same scenario as an example of the
    opposite approach... it got me thinking... And it looks like the main
    problem is not so much synchronization within single event dispatch
    timeframe, but rather avoiding race conditions when multiple events
    come at almost the same time. This may result in a newer event being
    processed by some listeners before an older event arrives, thus leading
    to unpredictable (and surely inconsistent) object state.

    First thing that comes to mind is having an event queue similar to AWT
    event queue (see some discussion on that below).

    > So I guess we have to rework the existing notification mechanism to be
    > able
    > to work in both modes: synchronous and asynchronous, right?

    Yeah, looks like we will need to do some changes. But with all the
    analysis above, two main requirements seem to be the following:

    1. Immediately unblock the calling thread that generated the event.
    2. Dispatch events coming from multiple threads in some predictable
    order.

    Third requirement (multithreaded dispatch of a *single* event) doesn't
    seem right to me now. Such dispatch can result in an uncontrollable
    spawning of threads, and generally serves very little purpose. If it
    happens that each listener takes an extended period of time to process
    the event, thus holding this particular dispatch, I guess it will be up
    to the listener to fork a new thread... At least for now we can live
    without (3).

    Also, I don't know if we have a case for turning (1) into a synchronous
    dispatch? I hope not.

    So back to dispatch flow. Assuming we have multiple "post" threads and
    a single "dispatch" thread, I can see the following steps:

    1. "Post" thread calls "EventManager.postEvent"
    2. EventManager appends the event to the queue (which is of course
    FIFO) and releases "post" thread, notifying "dispatch" thread.
    3. "Dispatch" thread awakes (or finishes processing previous entry),
    takes the first entry in the queue and dispatches to listeners,
    4. If queue is not empty, "dispatch" thread goes to step 3, otherwise
    it goes to sleep.

    Should be rather simple to implement - a big while loop with a
    queue.wait() in it, everything is synchronized on a list representing
    the queue.

    Now the question is - how do we organize such queues within
    Eventmanager? I guess by EventSubject?

    Andrus

    P.S. My discussion of snapshot updates has one gaping hole (though not
    directly related to event dispatch mechanism, just to commit
    concurrency in general). If DC2 commits its changes after DC1 (and
    potentially overriding some of DC1 changes), this doesn't guarantee
    that snapshot event from DC2 gets dispatched after to the one from DC1,
    since we are not locking the stack for commit.... I guess this was one
    of the reasons EOF was always single threaded :-)... Anyway, just
    wanted to post this problem for the record... The solution would
    require some sort of write lock or smart merging algorithm... Then
    there is remote snapshot notifications... :-)



    This archive was generated by hypermail 2.0.0 : Fri Oct 03 2003 - 01:42:32 EDT