Added close hints when the connection is shutdown
This commit is contained in:
parent
73a5af7a95
commit
615e224292
@ -690,6 +690,11 @@ class ConnectionImpl extends ChannelInboundHandlerAdapter implements CryptoConne
|
|||||||
closeLatch.countDown();
|
closeLatch.countDown();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final void
|
||||||
|
forceClose() {
|
||||||
|
this.channelWrapper.close(this, this.sessionManager, true);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Closes the connection, but does not remove any listeners
|
* Closes the connection, but does not remove any listeners
|
||||||
*/
|
*/
|
||||||
@ -757,7 +762,7 @@ class ConnectionImpl extends ChannelInboundHandlerAdapter implements CryptoConne
|
|||||||
synchronized (this.channelIsClosed) {
|
synchronized (this.channelIsClosed) {
|
||||||
if (!this.channelIsClosed.get()) {
|
if (!this.channelIsClosed.get()) {
|
||||||
// this will have netty call "channelInactive()"
|
// this will have netty call "channelInactive()"
|
||||||
this.channelWrapper.close(this, this.sessionManager);
|
this.channelWrapper.close(this, this.sessionManager, false);
|
||||||
|
|
||||||
// want to wait for the "channelInactive()" method to FINISH ALL TYPES before allowing our current thread to continue!
|
// want to wait for the "channelInactive()" method to FINISH ALL TYPES before allowing our current thread to continue!
|
||||||
try {
|
try {
|
||||||
|
@ -122,7 +122,7 @@ class ChannelLocalWrapper implements ChannelWrapper, ConnectionPoint {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public
|
public
|
||||||
void close(ConnectionImpl connection, ISessionManager sessionManager) {
|
void close(ConnectionImpl connection, ISessionManager sessionManager, boolean hintedClose) {
|
||||||
long maxShutdownWaitTimeInMilliSeconds = EndPoint.maxShutdownWaitTimeInMilliSeconds;
|
long maxShutdownWaitTimeInMilliSeconds = EndPoint.maxShutdownWaitTimeInMilliSeconds;
|
||||||
|
|
||||||
this.shouldFlush.set(false);
|
this.shouldFlush.set(false);
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
package dorkbox.network.connection.wrapper;
|
package dorkbox.network.connection.wrapper;
|
||||||
|
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
import dorkbox.network.connection.ConnectionPoint;
|
import dorkbox.network.connection.ConnectionPoint;
|
||||||
@ -69,12 +70,26 @@ class ChannelNetwork implements ConnectionPoint {
|
|||||||
return channel.eventLoop().newPromise();
|
return channel.eventLoop().newPromise();
|
||||||
}
|
}
|
||||||
|
|
||||||
public
|
void close(final int delay, final long maxShutdownWaitTimeInMilliSeconds) {
|
||||||
void close(long maxShutdownWaitTimeInMilliSeconds) {
|
|
||||||
shouldFlush.set(false);
|
shouldFlush.set(false);
|
||||||
if (channel.isActive()) {
|
if (channel.isActive()) {
|
||||||
|
if (delay > 0) {
|
||||||
|
// for UDP, we send a hint to the other connection that we should close. While not always 100% successful, this helps
|
||||||
|
// clean up connections on the remote end. So we want to wait a short amount of time for this to be successful
|
||||||
|
channel.eventLoop()
|
||||||
|
.schedule(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public
|
||||||
|
void run() {
|
||||||
|
channel.close()
|
||||||
|
.awaitUninterruptibly(maxShutdownWaitTimeInMilliSeconds);
|
||||||
|
}
|
||||||
|
}, delay, TimeUnit.MILLISECONDS);
|
||||||
|
}
|
||||||
|
else {
|
||||||
channel.close()
|
channel.close()
|
||||||
.awaitUninterruptibly(maxShutdownWaitTimeInMilliSeconds);
|
.awaitUninterruptibly(maxShutdownWaitTimeInMilliSeconds);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
@ -154,24 +154,29 @@ class ChannelNetworkWrapper implements ChannelWrapper {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public
|
public
|
||||||
void close(final ConnectionImpl connection, final ISessionManager sessionManager) {
|
void close(final ConnectionImpl connection, final ISessionManager sessionManager, boolean hintedClose) {
|
||||||
long maxShutdownWaitTimeInMilliSeconds = EndPoint.maxShutdownWaitTimeInMilliSeconds;
|
long maxShutdownWaitTimeInMilliSeconds = EndPoint.maxShutdownWaitTimeInMilliSeconds;
|
||||||
|
|
||||||
if (this.tcp != null) {
|
if (this.tcp != null) {
|
||||||
this.tcp.close(maxShutdownWaitTimeInMilliSeconds);
|
this.tcp.close(0, maxShutdownWaitTimeInMilliSeconds);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.udp != null) {
|
if (this.udp != null) {
|
||||||
|
if (hintedClose) {
|
||||||
|
// we already hinted that we should close this channel... don't do it again!
|
||||||
|
this.udp.close(0, maxShutdownWaitTimeInMilliSeconds);
|
||||||
|
}
|
||||||
|
else {
|
||||||
// send a hint to the other connection that we should close. While not always 100% successful, this helps clean up connections
|
// send a hint to the other connection that we should close. While not always 100% successful, this helps clean up connections
|
||||||
// on the remote end
|
// on the remote end
|
||||||
try {
|
try {
|
||||||
this.udp.write(new DatagramCloseMessage());
|
this.udp.write(new DatagramCloseMessage());
|
||||||
this.udp.flush();
|
this.udp.flush();
|
||||||
Thread.yield();
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
this.udp.close(maxShutdownWaitTimeInMilliSeconds);
|
this.udp.close(200, maxShutdownWaitTimeInMilliSeconds);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// we need to yield the thread here, so that the socket has a chance to close
|
// we need to yield the thread here, so that the socket has a chance to close
|
||||||
|
@ -53,7 +53,7 @@ interface ChannelWrapper {
|
|||||||
*/
|
*/
|
||||||
String getRemoteHost();
|
String getRemoteHost();
|
||||||
|
|
||||||
void close(ConnectionImpl connection, ISessionManager sessionManager);
|
void close(ConnectionImpl connection, ISessionManager sessionManager, boolean hintedClose);
|
||||||
|
|
||||||
int id();
|
int id();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user