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