Re: Spurious failure of RequestQueueTst

From: Andrus Adamchik (andru..bjectstyle.org)
Date: Mon Dec 16 2002 - 18:24:12 EST

  • Next message: Andrus: "Website search"

    Holger, Craig,

    Just saw Holger's check in email. Thanks for taking care of this!

    Andrus

     

    Holger Hoffstätte writes:
    >
    > Guys,
    >
    > I've spent some more time with the infamous RequestQueue failure and can
    > confirm that Craig's comment below really describes the cause of the
    > spurious failures:
    >
    >> I think I've figured out what's wrong, but not how to fix
    >> it. If you turn on debug in log4j, it turns out that
    >> "thread-4" is getting started before "thread-3", or rather,
    >> the particulars of timing means that thread-4 gets a go at
    >> executing before thread-3. For a failed test, the following
    >> (..)
    >> So, I *think* I know the fix, but not how to do it. After
    >> starting thread-3, the test needs to wait for that thread to
    >> be properly enqueued (loop waiting for
    >> RequestQueue.getSize() to return >0 maybe?).
    >
    > Yes, this will stop the test from failing and is a good quick fix for both
    > testQueueFull() and testWaitTimedOut(). I added the following to all tests
    > after the first thread start():
    >
    > while (testCase1.getQueue().getSize() == 0) {
    > Thread.yield(); // same as sleep(reallySmallAmount)
    > }
    >
    > and ran everything several hundred thousand times now without a single
    > failure. In order to fix the test this might really be the quickest and
    > safest solution. Unfortunately I don't think it solves the root of the
    > problem. :(
    >
    > IMHO everything should work without this manual caretaking - what if I
    > really want to start() a couple of threads in quick succession and the
    > queue is full? The current enqueueThread() method IMHO does two unrelated
    > things (accepting/rejecting initial requests & synchronizing) so that got
    > me thinking.
    >
    > I tried to redesign the threads' start() method and the dequeue handling
    > in RequestQueue.enqueueThread() to better handle the initial
    > synchronization by splitting up enqueueThread() between both
    > synchronized(..) blocks: the first one went into a separate
    > getRequestDequeue(String threadName) method, which will return a dequeue
    > token with initial ENQUEUED status (new) or the usual QUEUE_FULL
    > otherwise. enqueueThread() gets the dequeue to wait for as parameter. In
    > the threads' run() method the dequeue is obtained by non-blockingly
    > getting it from the queue, and enqueueThread() is subsequently only called
    > if the returned dequeue isEnqueued(), otherwise the method returns without
    > doing anything else. This prevents waiting for nonexisting/lingering
    > threads and 'gate crashing' due to successive start()s and IMHO is more in
    > line with regular token handling. Unfortunately it also changes the
    > semantics of some of the other parts of the tests (result null/!null etc.)
    > or introduce yet another race and therefore might need some more thinking
    > through; comments very welcome. Maybe it's a dumb idea and I missed
    > something essential.
    >
    > So, for a quick fix the manual waiting is IMHO OK and should be applied
    > ASAP since the occasionally failing test really does not build confidence.
    >
    > all IMHO :)
    > Holger
     



    This archive was generated by hypermail 2.0.0 : Mon Dec 16 2002 - 18:24:23 EST