View Javadoc

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