411340 SpdyConnection make executeOnFillable configurable and default to true

This commit is contained in:
Thomas Becker 2013-06-21 14:44:58 +02:00
parent b119bdfa24
commit 918632d408
6 changed files with 208 additions and 151 deletions

View File

@ -54,32 +54,32 @@
<!-- for all configuration that may be set here. -->
<!-- =========================================================== -->
<New id="pushStrategy" class="org.eclipse.jetty.spdy.server.http.ReferrerPushStrategy">
<!-- Uncomment to blacklist browsers for this push strategy. If one of the blacklisted Strings occurs in the
user-agent header sent by the client, push will be disabled for this browser. This is case insensitive" -->
<!--
<Set name="UserAgentBlacklist">
<Array type="String">
<Item>.*(?i)firefox/14.*</Item>
<Item>.*(?i)firefox/15.*</Item>
<Item>.*(?i)firefox/16.*</Item>
</Array>
</Set>
-->
<!-- Uncomment to blacklist browsers for this push strategy. If one of the blacklisted Strings occurs in the
user-agent header sent by the client, push will be disabled for this browser. This is case insensitive" -->
<!--
<Set name="UserAgentBlacklist">
<Array type="String">
<Item>.*(?i)firefox/14.*</Item>
<Item>.*(?i)firefox/15.*</Item>
<Item>.*(?i)firefox/16.*</Item>
</Array>
</Set>
-->
<!-- Uncomment to override default file extensions to push -->
<!--
<Set name="PushRegexps">
<Array type="String">
<Item>.*\.css</Item>
<Item>.*\.js</Item>
<Item>.*\.png</Item>
<Item>.*\.jpg</Item>
<Item>.*\.gif</Item>
</Array>
</Set>
-->
<Set name="referrerPushPeriod">5000</Set>
<Set name="maxAssociatedResources">32</Set>
<!-- Uncomment to override default file extensions to push -->
<!--
<Set name="PushRegexps">
<Array type="String">
<Item>.*\.css</Item>
<Item>.*\.js</Item>
<Item>.*\.png</Item>
<Item>.*\.jpg</Item>
<Item>.*\.gif</Item>
</Array>
</Set>
-->
<Set name="referrerPushPeriod">5000</Set>
<Set name="maxAssociatedResources">32</Set>
</New>
<!-- =========================================================== -->
@ -121,6 +121,10 @@
<Arg name="config">
<Ref refid="httpConfig"/>
</Arg>
<!-- Set the initial window size for this SPDY connector. -->
<!-- See: http://www.chromium.org/spdy/spdy-protocol/spdy-protocol-draft3#TOC-2.6.8-WINDOW_UPDATE -->
<Set name="initialWindowSize">65536</Set>
<!-- Uncomment to enable the push strategy with id "pushStrategy" -->
<!-- <Arg name="pushStrategy"><Ref refid="pushStrategy"/></Arg> -->
</New>
</Item>
@ -131,6 +135,9 @@
<Arg name="config">
<Ref refid="httpConfig"/>
</Arg>
<!-- Set the initial window size for this SPDY connector. -->
<!-- See: http://www.chromium.org/spdy/spdy-protocol/spdy-protocol-draft3#TOC-2.6.8-WINDOW_UPDATE -->
<Set name="initialWindowSize">65536</Set>
</New>
</Item>

View File

@ -60,6 +60,7 @@ public class SPDYClient
private volatile SocketAddress bindAddress;
private volatile long idleTimeout = -1;
private volatile int initialWindowSize;
private volatile boolean executeOnFillable;
protected SPDYClient(short version, Factory factory)
{
@ -125,6 +126,16 @@ public class SPDYClient
this.initialWindowSize = initialWindowSize;
}
public boolean isExecuteOnFillable()
{
return executeOnFillable;
}
public void setExecuteOnFillable(boolean executeOnFillable)
{
this.executeOnFillable = executeOnFillable;
}
protected String selectProtocol(List<String> serverProtocols)
{
String protocol = "spdy/" + version;

View File

@ -45,7 +45,7 @@ public class SPDYClientConnectionFactory
Parser parser = new Parser(compressionFactory.newDecompressor());
Generator generator = new Generator(bufferPool, compressionFactory.newCompressor());
SPDYConnection connection = new ClientSPDYConnection(endPoint, bufferPool, parser, factory);
SPDYConnection connection = new ClientSPDYConnection(endPoint, bufferPool, parser, factory, client.isExecuteOnFillable());
FlowControlStrategy flowControlStrategy = client.newFlowControlStrategy();
@ -66,9 +66,10 @@ public class SPDYClientConnectionFactory
{
private final Factory factory;
public ClientSPDYConnection(EndPoint endPoint, ByteBufferPool bufferPool, Parser parser, Factory factory)
public ClientSPDYConnection(EndPoint endPoint, ByteBufferPool bufferPool, Parser parser, Factory factory,
boolean executeOnFillable)
{
super(endPoint, bufferPool, parser, factory.getExecutor());
super(endPoint, bufferPool, parser, factory.getExecutor(), executeOnFillable);
this.factory = factory;
}

View File

@ -44,20 +44,21 @@ public class SPDYConnection extends AbstractConnection implements Controller, Id
private volatile ISession session;
private volatile boolean idle = false;
public SPDYConnection(EndPoint endPoint, ByteBufferPool bufferPool, Parser parser, Executor executor)
public SPDYConnection(EndPoint endPoint, ByteBufferPool bufferPool, Parser parser, Executor executor,
boolean executeOnFillable)
{
this(endPoint, bufferPool, parser, executor, 8192);
this(endPoint, bufferPool, parser, executor, executeOnFillable, 8192);
}
public SPDYConnection(EndPoint endPoint, ByteBufferPool bufferPool, Parser parser, Executor executor, int bufferSize)
public SPDYConnection(EndPoint endPoint, ByteBufferPool bufferPool, Parser parser, Executor executor,
boolean executeOnFillable, int bufferSize)
{
// Since SPDY is multiplexed, onFillable() must never block
// while calling application code. In fact, onFillable()
// always dispatches to a new thread when calling application
// code, so here we can safely pass false as last parameter,
// and avoid to dispatch to onFillable().
super(endPoint, executor, !EXECUTE_ONFILLABLE);
super(endPoint, executor, executeOnFillable);
this.bufferPool = bufferPool;
this.parser = parser;
onIdle(true);

View File

@ -8,128 +8,150 @@
<!-- ============================================================= -->
<Configure id="Server" class="org.eclipse.jetty.server.Server">
<!-- =========================================================== -->
<!-- Enables NPN debugging on System.err -->
<!-- ===========================================================
<Set class="org.eclipse.jetty.npn.NextProtoNego" name="debug" type="boolean">true</Set>
-->
<!-- =========================================================== -->
<!-- Create a push strategy which can be used by reference by -->
<!-- individual connection factories below. -->
<!-- -->
<!-- Consult the javadoc of o.e.j.spdy.server.http.ReferrerPushStrategy -->
<!-- for all configuration that may be set here. -->
<!-- =========================================================== -->
<New id="pushStrategy" class="org.eclipse.jetty.spdy.server.http.ReferrerPushStrategy">
<!-- Uncomment to blacklist browsers for this push strategy. If one of the blacklisted Strings occurs in the
user-agent header sent by the client, push will be disabled for this browser. This is case insensitive" -->
<!--
<Set name="UserAgentBlacklist">
<Array type="String">
<Item>.*(?i)firefox/14.*</Item>
<Item>.*(?i)firefox/15.*</Item>
<Item>.*(?i)firefox/16.*</Item>
</Array>
</Set>
<!-- =========================================================== -->
<!-- Enables NPN debugging on System.err -->
<!-- ===========================================================
<Set class="org.eclipse.jetty.npn.NextProtoNego" name="debug" type="boolean">true</Set>
-->
<!-- Uncomment to override default file extensions to push -->
<!--
<Set name="PushRegexps">
<Array type="String">
<Item>.*\.css</Item>
<Item>.*\.js</Item>
<Item>.*\.png</Item>
<Item>.*\.jpg</Item>
<Item>.*\.gif</Item>
</Array>
</Set>
-->
<Set name="referrerPushPeriod">5000</Set>
<Set name="maxAssociatedResources">32</Set>
</New>
<!-- =========================================================== -->
<!-- Create a push strategy which can be used by reference by -->
<!-- individual connection factories below. -->
<!-- -->
<!-- Consult the javadoc of o.e.j.spdy.server.http.ReferrerPushStrategy -->
<!-- for all configuration that may be set here. -->
<!-- =========================================================== -->
<New id="pushStrategy" class="org.eclipse.jetty.spdy.server.http.ReferrerPushStrategy">
<!-- Uncomment to blacklist browsers for this push strategy. If one of the blacklisted Strings occurs in the
user-agent header sent by the client, push will be disabled for this browser. This is case insensitive" -->
<!--
<Set name="UserAgentBlacklist">
<Array type="String">
<Item>.*(?i)firefox/14.*</Item>
<Item>.*(?i)firefox/15.*</Item>
<Item>.*(?i)firefox/16.*</Item>
</Array>
</Set>
-->
<!-- =========================================================== -->
<!-- Add a SPDY/HTTPS Connector. -->
<!-- Configure an o.e.j.server.ServerConnector with connection -->
<!-- factories for TLS (aka SSL), NPN, SPDY and HTTP to provide -->
<!-- a connector that can accept HTTPS or SPDY connections. -->
<!-- -->
<!-- All accepted TLS connections are initially wired to a NPN -->
<!-- connection, which attempts to use a TLS extension to -->
<!-- negotiation the protocol. If NPN is not supported by -->
<!-- the client, then the NPN connection is replaced by a HTTP -->
<!-- connection. If a specific protocol version (eg spdy/3) is -->
<!-- negotiated by NPN, then the appropriate connection factory -->
<!-- is used to create a connection to replace the NPN connection-->
<!-- -->
<!-- The final result is a SPDY or HTTP connection wired behind -->
<!-- a TLS (aka SSL) connection. -->
<!-- -->
<!-- Consult the javadoc of o.e.j.server.ServerConnector and the -->
<!-- specific connection factory types for all configuration -->
<!-- that may be set here. -->
<!-- =========================================================== -->
<Call id="spdyConnector" name="addConnector">
<Arg>
<New class="org.eclipse.jetty.server.ServerConnector">
<Arg name="server"><Ref refid="Server" /></Arg>
<Arg name="factories">
<Array type="org.eclipse.jetty.server.ConnectionFactory">
<!-- Uncomment to override default file extensions to push -->
<!--
<Set name="PushRegexps">
<Array type="String">
<Item>.*\.css</Item>
<Item>.*\.js</Item>
<Item>.*\.png</Item>
<Item>.*\.jpg</Item>
<Item>.*\.gif</Item>
</Array>
</Set>
-->
<Set name="referrerPushPeriod">5000</Set>
<Set name="maxAssociatedResources">32</Set>
</New>
<!-- SSL Connection factory with NPN as next protocol -->
<Item>
<New class="org.eclipse.jetty.server.SslConnectionFactory">
<Arg name="next">npn</Arg>
<Arg name="sslContextFactory"><Ref refid="sslContextFactory" /></Arg>
</New>
</Item>
<!-- =========================================================== -->
<!-- Add a SPDY/HTTPS Connector. -->
<!-- Configure an o.e.j.server.ServerConnector with connection -->
<!-- factories for TLS (aka SSL), NPN, SPDY and HTTP to provide -->
<!-- a connector that can accept HTTPS or SPDY connections. -->
<!-- -->
<!-- All accepted TLS connections are initially wired to a NPN -->
<!-- connection, which attempts to use a TLS extension to -->
<!-- negotiation the protocol. If NPN is not supported by -->
<!-- the client, then the NPN connection is replaced by a HTTP -->
<!-- connection. If a specific protocol version (eg spdy/3) is -->
<!-- negotiated by NPN, then the appropriate connection factory -->
<!-- is used to create a connection to replace the NPN connection-->
<!-- -->
<!-- The final result is a SPDY or HTTP connection wired behind -->
<!-- a TLS (aka SSL) connection. -->
<!-- -->
<!-- Consult the javadoc of o.e.j.server.ServerConnector and the -->
<!-- specific connection factory types for all configuration -->
<!-- that may be set here. -->
<!-- =========================================================== -->
<Call id="spdyConnector" name="addConnector">
<Arg>
<New class="org.eclipse.jetty.server.ServerConnector">
<Arg name="server">
<Ref refid="Server"/>
</Arg>
<Arg name="factories">
<Array type="org.eclipse.jetty.server.ConnectionFactory">
<!-- NPN Connection factory with HTTP as default protocol -->
<Item>
<New class="org.eclipse.jetty.spdy.server.NPNServerConnectionFactory">
<Arg name="protocols"><Array type="String">
<Item>spdy/3</Item>
<Item>spdy/2</Item>
<Item>http/1.1</Item>
</Array></Arg>
<Set name="defaultProtocol">http/1.1</Set>
</New>
</Item>
<!-- SSL Connection factory with NPN as next protocol -->
<Item>
<New class="org.eclipse.jetty.server.SslConnectionFactory">
<Arg name="next">npn</Arg>
<Arg name="sslContextFactory">
<Ref refid="sslContextFactory"/>
</Arg>
</New>
</Item>
<!-- SPDY/3 Connection factory -->
<Item>
<New class="org.eclipse.jetty.spdy.server.http.HTTPSPDYServerConnectionFactory">
<Arg name="version" type="int">3</Arg>
<Arg name="config"><Ref refid="sslHttpConfig" /></Arg>
<!-- Uncomment to enable ReferrerPushStrategy -->
<!--<Arg name="pushStrategy"><Ref refid="pushStrategy"/></Arg>-->
</New>
</Item>
<!-- NPN Connection factory with HTTP as default protocol -->
<Item>
<New class="org.eclipse.jetty.spdy.server.NPNServerConnectionFactory">
<Arg name="protocols">
<Array type="String">
<Item>spdy/3</Item>
<Item>spdy/2</Item>
<Item>http/1.1</Item>
</Array>
</Arg>
<Set name="defaultProtocol">http/1.1</Set>
</New>
</Item>
<!-- SPDY/2 Connection factory -->
<Item>
<New class="org.eclipse.jetty.spdy.server.http.HTTPSPDYServerConnectionFactory">
<Arg name="version" type="int">2</Arg>
<Arg name="config"><Ref refid="sslHttpConfig" /></Arg>
</New>
</Item>
<!-- SPDY/3 Connection factory -->
<Item>
<New class="org.eclipse.jetty.spdy.server.http.HTTPSPDYServerConnectionFactory">
<Arg name="version" type="int">3</Arg>
<Arg name="config">
<Ref refid="sslHttpConfig"/>
</Arg>
<!-- Set the initial window size for this SPDY connector. -->
<!-- See: http://www.chromium.org/spdy/spdy-protocol/spdy-protocol-draft3#TOC-2.6.8-WINDOW_UPDATE -->
<Set name="initialWindowSize">65536</Set>
<!-- Uncomment to enable ReferrerPushStrategy -->
<!--<Arg name="pushStrategy"><Ref refid="pushStrategy"/></Arg>-->
</New>
</Item>
<!-- HTTP Connection factory -->
<Item>
<New class="org.eclipse.jetty.server.HttpConnectionFactory">
<Arg name="config"><Ref refid="sslHttpConfig" /></Arg>
</New>
</Item>
</Array>
<!-- SPDY/2 Connection factory -->
<Item>
<New class="org.eclipse.jetty.spdy.server.http.HTTPSPDYServerConnectionFactory">
<Arg name="version" type="int">2</Arg>
<Arg name="config">
<Ref refid="sslHttpConfig"/>
</Arg>
<!-- Set the initial window size for this SPDY connector. -->
<!-- See: http://www.chromium.org/spdy/spdy-protocol/spdy-protocol-draft3#TOC-2.6.8-WINDOW_UPDATE -->
<Set name="initialWindowSize">65536</Set>
</New>
</Item>
<!-- HTTP Connection factory -->
<Item>
<New class="org.eclipse.jetty.server.HttpConnectionFactory">
<Arg name="config">
<Ref refid="sslHttpConfig"/>
</Arg>
</New>
</Item>
</Array>
</Arg>
<Set name="host">
<Property name="jetty.host"/>
</Set>
<Set name="port">
<Property name="jetty.spdy.port" default="8443"/>
</Set>
<Set name="idleTimeout">30000</Set>
</New>
</Arg>
<Set name="host"><Property name="jetty.host" /></Set>
<Set name="port"><Property name="jetty.spdy.port" default="8443" /></Set>
<Set name="idleTimeout">30000</Set>
</New>
</Arg>
</Call>
</Call>
</Configure>

View File

@ -69,6 +69,7 @@ public class SPDYServerConnectionFactory extends AbstractConnectionFactory
private final short version;
private final ServerSessionFrameListener listener;
private int initialWindowSize;
private boolean executeOnFillable = true;
private final Queue<Session> sessions = new ConcurrentLinkedQueue<>();
public SPDYServerConnectionFactory(int version)
@ -103,14 +104,15 @@ public class SPDYServerConnectionFactory extends AbstractConnectionFactory
Generator generator = new Generator(connector.getByteBufferPool(), compressionFactory.newCompressor());
ServerSessionFrameListener listener = provideServerSessionFrameListener(connector, endPoint);
SPDYConnection connection = new ServerSPDYConnection(connector, endPoint, parser, listener, getInputBufferSize());
SPDYConnection connection = new ServerSPDYConnection(connector, endPoint, parser, listener,
executeOnFillable, getInputBufferSize());
FlowControlStrategy flowControlStrategy = newFlowControlStrategy(version);
StandardSession session = new StandardSession(getVersion(), connector.getByteBufferPool(),
connector.getExecutor(), connector.getScheduler(), connection, endPoint, connection, 2, listener,
generator, flowControlStrategy);
session.setWindowSize(getInitialWindowSize());
session.setWindowSize(initialWindowSize);
parser.addListener(session);
connection.setSession(session);
@ -140,6 +142,17 @@ public class SPDYServerConnectionFactory extends AbstractConnectionFactory
this.initialWindowSize = initialWindowSize;
}
@ManagedAttribute("Execute onFillable")
public boolean isExecuteOnFillable()
{
return executeOnFillable;
}
public void setExecuteOnFillable(boolean executeOnFillable)
{
this.executeOnFillable = executeOnFillable;
}
protected boolean sessionOpened(Session session)
{
// Add sessions only if the connector is not stopping
@ -177,9 +190,11 @@ public class SPDYServerConnectionFactory extends AbstractConnectionFactory
private final ServerSessionFrameListener listener;
private final AtomicBoolean connected = new AtomicBoolean();
private ServerSPDYConnection(Connector connector, EndPoint endPoint, Parser parser, ServerSessionFrameListener listener, int bufferSize)
private ServerSPDYConnection(Connector connector, EndPoint endPoint, Parser parser,
ServerSessionFrameListener listener, boolean executeOnFillable, int bufferSize)
{
super(endPoint, connector.getByteBufferPool(), parser, connector.getExecutor(), bufferSize);
super(endPoint, connector.getByteBufferPool(), parser, connector.getExecutor(),
executeOnFillable, bufferSize);
this.listener = listener;
}