how to set up the speed limit for a session ?

2010-12-20 Thread Сергей Григорьев
Hello All,
My company is evaluating MINA  for building a content-delivery system. I am
in charge of creaing a pilot project. The prototype is a simple HTTP proxy
which stands between the clients and a heavy-loaded web server. I've found
an example of proxy in MINA souces, then tried it. It didn't work, because
the connection between the client and proxy is relatively slow, and
connection between proxy and the web server is very fast, so it consumed
2GBytes of memory. So we ended up with a proxy with a  lot of queued
messages from web server waiting to be delivered to the client. Then I
decided to create a filter which watches for the number of messages in write
queue (from proxy to the clients), and if the number is greater than 2,
then the filter tells the other session (from proxy to server) to suspend
reading, otherwise resumeReading.  It ended up with all worker threads
blocked:

pool-5-thread-593" prio=10 tid=0x2aab387cf000 nid=0x451f waiting for
monitor entry [0x6d91c000]
java.lang.Thread.State: BLOCKED (on object monitor)
at sun.nio.ch.EPollArrayWrapper.setInterest(EPollArrayWrapper.java:151)

   - waiting to lock <0x2aaab3988d48> (a java.util.LinkedList)
   at sun.nio.ch.EPollSelectorImpl.putEventOps(EPollSelectorImpl.java:164)
   at
   
sun.nio.ch.SocketChannelImpl.translateAndSetInterestOps(SocketChannelImpl.java:799)
   at sun.nio.ch.SelectionKeyImpl.nioInterestOps(SelectionKeyImpl.java:87)
   at sun.nio.ch.SelectionKeyImpl.interestOps(SelectionKeyImpl.java:65)
   at
   
org.apache.mina.transport.socket.nio.NioProcessor.setInterestedInWrite(NioProcessor.java:207)
   at
   
org.apache.mina.transport.socket.nio.NioProcessor.setInterestedInWrite(NioProcessor.java:42)
   at
   
org.apache.mina.core.polling.AbstractPollingIoProcessor.updateTrafficControl(AbstractPollingIoProcessor.java:1041)
   at
   
org.apache.mina.core.polling.AbstractPollingIoProcessor.updateTrafficControl(AbstractPollingIoProcessor.java:66)
   at
   
org.apache.mina.core.service.SimpleIoProcessorPool.updateTrafficControl(SimpleIoProcessorPool.java:259)
   at
   
org.apache.mina.core.service.SimpleIoProcessorPool.updateTrafficControl(SimpleIoProcessorPool.java:77)
   at
   
org.apache.mina.core.session.AbstractIoSession.resumeRead(AbstractIoSession.java:660)
   at com.pmstation.mina.ThrottleFilter.throttle(ThrottleFilter.java:44)
   at com.pmstation.mina.ThrottleFilter.messageSent(ThrottleFilter.java:17)
   at
   
org.apache.mina.core.filterchain.DefaultIoFilterChain.callNextMessageSent(DefaultIoFilterChain.java:462)
   at
   
org.apache.mina.core.filterchain.DefaultIoFilterChain.access$1300(DefaultIoFilterChain.java:46)
   at
   
org.apache.mina.core.filterchain.DefaultIoFilterChain$EntryImpl$1.messageSent(DefaultIoFilterChain.java:802)
   at
   org.apache.mina.core.filterchain.IoFilterEvent.fire(IoFilterEvent.java:80)
   at org.apache.mina.core.session.IoEvent.run(IoEvent.java:63)
   at
   
java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
   at
   
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
   at java.lang.Thread.run(Thread.java:619)


I was assuming that suspending reading or resuming reading affects the
session only, and from the stack trace I can see that tries to resume
reading on the NIO channel which serves many sessions.  What approach should
I take to balance the speed of incoming and outgoing  channels ?

public class ThrottleFilter extends IoFilterAdapter {

  private static final long MAX__QUEUED__MESSAGES = 2;


  @Override
  public void messageSent(NextFilter nextFilter, IoSession session,
WriteRequest writeRequest) throws Exception {
throttle(session);
super.messageSent(nextFilter, session, writeRequest);

  }

  @Override
  public void sessionClosed(NextFilter nextFilter, IoSession session) throws
Exception {
super.sessionClosed(nextFilter, session);
  }

  @Override
  public void sessionIdle(NextFilter nextFilter, IoSession session,
IdleStatus status) throws Exception {
throttle(session);
super.sessionIdle(nextFilter, session, status);
  }

  @Override
  public void filterWrite(NextFilter nextFilter, IoSession session,
WriteRequest writeRequest) throws Exception {
throttle(session);
super.filterWrite(nextFilter, session, writeRequest);
  }

  private void throttle(IoSession session) {
IoSession otherSesion = Utils.getPeerSession(session);
if (otherSesion == null)
  return;
if (session.getScheduledWriteMessages() <  MAX__QUEUED__MESSAGES) {
  otherSesion.resumeRead();
} else {
  otherSesion.suspendRead();
}
  }


Re: when serializing an HttpRequest into byte stream "Cookie:" headers are replaced with "Set-cookie". The fixing patch is attached

2010-12-11 Thread Сергей Григорьев
Well, for now it is not a big issue  because my proxy doesn't parse response
, it just feeds the response bytes  back to the client without any  parsing.

On Sat, Dec 11, 2010 at 5:04 PM, Emmanuel Lécharny wrote:

>
> Btw, looking at the DefaultHttpResponse code, I see :
>public void addCookie(String headerValue) {
>// TODO Implement addCookie(String headerValue)
>throw new UnsupportedOperationException("Not implemented yet");
>}
>
> which miht be a problem for you, right ?
>
>
> --
> Regards,
> Cordialement,
> Emmanuel Lécharny
> www.iktek.com
>
>


Re: when serializing an HttpRequest into byte stream "Cookie:" headers are replaced with "Set-cookie". The fixing patch is attached

2010-12-11 Thread Сергей Григорьев
I suppose that the server should not set cookies on an HttpRequest, it
should set cookies on an HttpResponse, do you agree ?


when serializing an HttpRequest into byte stream "Cookie:" headers are replaced with "Set-cookie". The fixing patch is attached

2010-12-09 Thread Сергей Григорьев
Hello All,

I have developed an HTTP proxy with Mina and detected that cookies from
browser are lost. This must be a typo error.
Index: DefaultHttpRequest.java
===
--- DefaultHttpRequest.java (revision 1043657)
+++ DefaultHttpRequest.java (working copy)
@@ -423,7 +423,7 @@
 
 buf.append(';');
 
-addHeader(HttpHeaderConstants.KEY_SET_COOKIE, buf.toString());
+addHeader(HttpHeaderConstants.KEY_COOKIE, buf.toString());
 }
 }