Back pressure, Thread managers and blocking stages/queues

Quartz <[email protected]> Wed, 17 Sep 2003 08:02:30 -0700 (PDT)
Newsgroups gmane.comp.java.seda.user
Message-ID <[email protected]>
Hi,

We say that handlers should not block.
Well, that is pretty much a valid recommendation all the time except for one very unique occasion:
when a stage cannot enqueue.

---

I started thinking why is the queue (pipe, in another aspect) not able to block.
At first it sound obvious: handlers should not block! Ok.

But why? Mostly because seda would think that a stage is not performing good, and would allocate
time/cpu for it, endlessly, and cause overload on the jvm for no good reason. Another thread
manager may actually not have anymore thread to allocate, and the system would be waiting forever.

Why does thread manager think so? Because the handler/stage does not tell them it is blocking,
right?! If some thread manager support blocking handlers, I'm sure it would appreciate to be told
when that happens.

So, I found a solution to a very common problem.

Let's say a stage B is slow and his queue gets full. Stage A that wants to enqueue in B's sink
currently must face 2 alternative:
1-it tries to enqueue but it fails with sink exception
2-it enqueues lossy.

Currently, it cannot wait/retry, this would be blocking.
It has to either loose data (lossy enqueue or discard data because of exception), or the queue
threshold must be increased to sustain extra data, causing memory to fill and eventually crashes
the JVM (much too easy to do, thrust me.)

There is no way to apply back pressure safely right now.
There is an assumption that if the cpu is properly balance, the overproducing stage will eventualy
 get lesser and lesser CPU time as other stages get more thread/time, making the seda balanced.
The problem is that it may occur very late if it ever does, and requires huge memory tolerance. No
decent system works that way.

My solution is to accept blocking but only in enqueue, while telling the thread manager that we
are not blocking because we are slow, but because we are waiting for another stage, hence giving
an even better hint to the thread manager that it is time to kick butt on some other stages.

To make it transparent to handlers, the queue implementation should have access to some
ThreadManagerIF.isBlockingSupported() and ThreadManagerIF.doBlockingAction(ActionIF)
where BlockingActionIF would be invoked by, let's say,
-doAction(Object obj):Object.

I use a visitor pattern, now, because I first though I would define
ThreadManagerIF.blockingEnter()
and ThreadManagerIF.blockingExit(), but people then to forget to use try/finally to do it right
and safe.

The ThreadManager implementation then interprets that request (and may deny it is blocking not
supported).

Thread managers simply need to find Thread.currentThread() to discover what thread is about to
block, and by association, discover what stage is concerned. I can guess that the TPSTM would tell
the size controller not do attempt resizing this stage thread pool. But other TM, like a possible
thread priority controller, would consider not changing this stage's threads priority.


What do you think, how do you deal with back pressure?
Thanks.


__________________________________
Do you Yahoo!?
Yahoo! SiteBuilder - Free, easy-to-use web site design software
http://sitebuilder.yahoo.com


-------------------------------------------------------
This sf.net email is sponsored by:ThinkGeek
Welcome to geek heaven.
http://thinkgeek.com/sf