View Javadoc

1   //========================================================================
2   //Copyright 2011-2012 Mort Bay Consulting Pty. Ltd.
3   //------------------------------------------------------------------------
4   //All rights reserved. This program and the accompanying materials
5   //are made available under the terms of the Eclipse Public License v1.0
6   //and Apache License v2.0 which accompanies this distribution.
7   //The Eclipse Public License is available at
8   //http://www.eclipse.org/legal/epl-v10.html
9   //The Apache License v2.0 is available at
10  //http://www.opensource.org/licenses/apache2.0.php
11  //You may elect to redistribute this code under either of these licenses.
12  //========================================================================
13  
14  package org.eclipse.jetty.spdy;
15  
16  import java.util.concurrent.TimeUnit;
17  
18  import org.eclipse.jetty.spdy.api.DataInfo;
19  import org.eclipse.jetty.spdy.api.Stream;
20  import org.eclipse.jetty.spdy.frames.WindowUpdateFrame;
21  
22  public class SPDYv3FlowControlStrategy implements FlowControlStrategy
23  {
24      private volatile int windowSize;
25  
26      @Override
27      public int getWindowSize(ISession session)
28      {
29          return windowSize;
30      }
31  
32      @Override
33      public void setWindowSize(ISession session, int windowSize)
34      {
35          int prevWindowSize = this.windowSize;
36          this.windowSize = windowSize;
37          for (Stream stream : session.getStreams())
38              ((IStream)stream).updateWindowSize(windowSize - prevWindowSize);
39      }
40  
41      @Override
42      public void onNewStream(ISession session, IStream stream)
43      {
44          stream.updateWindowSize(windowSize);
45      }
46  
47      @Override
48      public void onWindowUpdate(ISession session, IStream stream, int delta)
49      {
50          if (stream != null)
51              stream.updateWindowSize(delta);
52      }
53  
54      @Override
55      public void updateWindow(ISession session, IStream stream, int delta)
56      {
57          stream.updateWindowSize(delta);
58      }
59  
60      @Override
61      public void onDataReceived(ISession session, IStream stream, DataInfo dataInfo)
62      {
63          // Do nothing
64      }
65  
66      @Override
67      public void onDataConsumed(ISession session, IStream stream, DataInfo dataInfo, int delta)
68      {
69          // This is the algorithm for flow control.
70          // This method may be called multiple times with delta=1, but we only send a window
71          // update when the whole dataInfo has been consumed.
72          // Other policies may be to send window updates when consumed() is greater than
73          // a certain threshold, etc. but for now the policy is not pluggable for simplicity.
74          // Note that the frequency of window updates depends on the read buffer, that
75          // should not be too smaller than the window size to avoid frequent window updates.
76          // Therefore, a pluggable policy should be able to modify the read buffer capacity.
77          int length = dataInfo.length();
78          if (dataInfo.consumed() == length && !stream.isClosed() && length > 0)
79          {
80              WindowUpdateFrame windowUpdateFrame = new WindowUpdateFrame(session.getVersion(), stream.getId(), length);
81              session.control(stream, windowUpdateFrame, 0, TimeUnit.MILLISECONDS, null, null);
82          }
83      }
84  }