Class QuicheTripConnectionPool
- All Implemented Interfaces:
Pool<Connection>
All pooled connections are streams multiplexed over a single QUIC connection. Since that connection is
discarded silently by both peers as soon as it stays idle for longer than the QUIC max idle timeout
(see QuicheTripTransport.getMaxIdleSeconds()), which is much shorter than the pool's idle
timeout, it is kept alive by sending ack-eliciting packets. Otherwise, the pool would hand out
connections belonging to a QUIC connection that is long gone.
Because each pooled connection holds one of the streams the peer allows for the whole time it is in the
pool, the pool's maximum size defaults to QuicheTripTransport.getMaxStreams() instead of being
unlimited. Should the peer nevertheless grant fewer streams, opening another one fails at once with a
temporary TripRuntimeException.
The QUIC connection is established right away when the pool is created, which in turn happens when the transport hands out its first client connection. The server's host name is resolved only then, once for the lifetime of the pool.
The QUIC connection migrates to a new source port when its path stalls (see
QuicheTripTransport.getMigrationProbeTimeouts()). If it is lost anyway, it is re-established on
a new endpoint, i.e., from a fresh source port as well: the one the lost connection used may well be
what got it stuck. That happens when the next connection is requested from the pool, see
restoreMinimumSize(int).
A lent connection holds a lease on the QUIC connection (see QuicheConnection.acquire()), since a
call is in flight on it. A QUIC connection that cannot migrate any further, because a migration used up
the server's spare connection IDs, is therefore given up on as soon as no call is in flight anymore, and
replaced with the next get() by one with a full set of connection IDs, before its path stalls
again.
-
Field Summary
FieldsModifier and TypeFieldDescriptionstatic final intThe default connect timeout in seconds, applied if the URI does not specifyconnecttimeout. -
Constructor Summary
ConstructorsConstructorDescriptionQuicheTripConnectionPool(QuicheTripTransport transport, Dictionary dictionary) Creates a QUIC connection pool and establishes the QUIC connection. -
Method Summary
Modifier and TypeMethodDescriptionprotected voidCloses the QUIC connection if there is one.
Closing is best effort: the connection may be gone already.protected voidconnect()Establishes the QUIC connection all pooled connections are multiplexed over.
A previously established connection is closed first, together with its endpoint: the new connection gets an endpoint of its own, and with it a fresh source port.protected PoolSlot<Connection> createSlot(int slotNumber) Creates a new slot.get()Gets a resource from the pool.
The pool is enlarged if all resources are in use.voidput(Connection connection) Returns a resource to the pool.protected voidrestoreMinimumSize(int num) Brings the pool back to its minimum size.voidshutdown()Shuts down the pool.
Closes all resources.Methods inherited from class AbstractConnectionPool
createException, createException, getDictionary, getTransportMethods inherited from class AbstractPool
createSlots, getIdleMinutes, getIncrementSize, getInitialSize, getMaximumSize, getMinimumSize, getName, getShutdownTimeout, getSize, getSlotCountPerThread, getUsageMinutes, isCreatingSlotsConcurrently, isShutdown, isSlotRemovable, logSlotCountPerThread, monitor, removePoolable, removeSlotIndex, setIdleMinutes, setIncrementSize, setMaximumSize, setMinimumSize, setShutdownTimeout, setUsageMinutes, toString, unusePoolable
-
Field Details
-
DEFAULT_CONNECT_TIMEOUT
public static final int DEFAULT_CONNECT_TIMEOUTThe default connect timeout in seconds, applied if the URI does not specifyconnecttimeout.This is the timeout for establishing the QUIC connection, i.e., the handshake with the server, not for the individual streams created per pool slot.
- See Also:
-
-
Constructor Details
-
QuicheTripConnectionPool
Creates a QUIC connection pool and establishes the QUIC connection.- Parameters:
transport- the transport associated with this pooldictionary- the dictionary associated with this pool- Throws:
IllegalArgumentException- if the URI has no port > 0, orconnecttimeoutis not > 0TripRuntimeException- if a URI parameter is invalid or the QUIC connection cannot be established
-
-
Method Details
-
shutdown
public void shutdown()Shuts down the pool.
Closes all resources.Deliberately not synchronized:
AbstractPool.shutdown()closes the pooled connections without holding the pool's monitor, on purpose, since it waits for each of them. Only accessing the QUIC connection needs the monitor.- Specified by:
shutdownin interfacePool<Connection>- Overrides:
shutdownin classAbstractPool<Connection>
-
get
Gets a resource from the pool.
The pool is enlarged if all resources are in use.Overridden to take a lease on the QUIC connection for the call the connection is lent for. Not synchronized: the lease is lock-free, and taking the pool's monitor here would serialize all calls.
- Specified by:
getin interfacePool<Connection>- Overrides:
getin classAbstractPool<Connection>- Returns:
- the resource, never null
-
put
Returns a resource to the pool.Notice: returning a resource more than once is allowed.
Returning a closed resource removes it from the pool. Returning a resource to a pool that is shut down closes the resource.Overridden to release the lease taken by
get().- Specified by:
putin interfacePool<Connection>- Overrides:
putin classAbstractPool<Connection>- Parameters:
connection- the resource
-
restoreMinimumSize
protected void restoreMinimumSize(int num) Brings the pool back to its minimum size.Invoked by
AbstractPool.monitor()with the pool's monitor held, i.e., usually from thePoolTimeoutThreadall pools share. The default implementation creates the missing slots. A pool whose resources cannot be created without blocking for long — because they depend on something that is gone and has to be re-established first — should override this and leave the pool below its minimum size instead:AbstractPool.get()creates the resources as soon as they are needed.Overridden to do nothing while the QUIC connection is gone. Creating a slot would re-establish it first, which waits for the handshake for as long as
connecttimeoutallows if the server is not reachable — with the pool's monitor held, on the thread that monitors all pools, and again with every round. The connection is re-established by the nextget()instead, i.e., when it is needed.- Overrides:
restoreMinimumSizein classAbstractPool<Connection>- Parameters:
num- the number of slots missing
-
createSlot
Description copied from class:AbstractPoolCreates a new slot.- Specified by:
createSlotin classAbstractPool<Connection>- Parameters:
slotNumber- the slot number, starting at 0- Returns:
- the slot
-
connect
protected void connect()Establishes the QUIC connection all pooled connections are multiplexed over.
A previously established connection is closed first, together with its endpoint: the new connection gets an endpoint of its own, and with it a fresh source port. -
closeConnection
protected void closeConnection()Closes the QUIC connection if there is one.
Closing is best effort: the connection may be gone already.
-