Skip to content

Commit febb374

Browse files
committed
[UNDERTOW-1794] add configurable delay/retry on close
1 parent ffe2530 commit febb374

File tree

2 files changed

+43
-8
lines changed

2 files changed

+43
-8
lines changed

core/src/main/java/io/undertow/UndertowLogger.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -442,4 +442,8 @@ void nodeConfigCreated(URI connectionURI, String balancer, String domain, String
442442
@LogMessage(level = DEBUG)
443443
@Message(id = 5096, value = "Access Log Worker failed to reschedule.")
444444
void accessLogWorkerFailureOnReschedule();
445+
446+
@LogMessage(level = DEBUG)
447+
@Message(id = 5097, value = "Access Log Worker did not terminate cleanly.")
448+
void accessLogWorkerNoTermination();
445449
}

core/src/main/java/io/undertow/server/handlers/accesslog/DefaultAccessLogReceiver.java

Lines changed: 39 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ public class DefaultAccessLogReceiver implements AccessLogReceiver, Runnable, Cl
5858
//0 = not running
5959
//1 = queued
6060
//2 = running
61-
//3 = closing
61+
//3 = closing/closed
6262
@SuppressWarnings("unused")
6363
private volatile int state = 0;
6464

@@ -80,6 +80,8 @@ public class DefaultAccessLogReceiver implements AccessLogReceiver, Runnable, Cl
8080
private boolean initialRun = true;
8181
private final boolean rotate;
8282
private final LogFileHeaderGenerator fileHeaderGenerator;
83+
private final int closeRetryCount;
84+
private final int closeRetryDelay;
8385

8486
public DefaultAccessLogReceiver(final Executor logWriteExecutor, final File outputDirectory, final String logBaseName) {
8587
this(logWriteExecutor, outputDirectory.toPath(), logBaseName, null);
@@ -102,10 +104,10 @@ public DefaultAccessLogReceiver(final Executor logWriteExecutor, final Path outp
102104
}
103105

104106
public DefaultAccessLogReceiver(final Executor logWriteExecutor, final Path outputDirectory, final String logBaseName, final String logNameSuffix, boolean rotate) {
105-
this(logWriteExecutor, outputDirectory, logBaseName, logNameSuffix, rotate, null);
107+
this(logWriteExecutor, outputDirectory, logBaseName, logNameSuffix, rotate, null, 60, 50);
106108
}
107109

108-
private DefaultAccessLogReceiver(final Executor logWriteExecutor, final Path outputDirectory, final String logBaseName, final String logNameSuffix, boolean rotate, LogFileHeaderGenerator fileHeader) {
110+
private DefaultAccessLogReceiver(final Executor logWriteExecutor, final Path outputDirectory, final String logBaseName, final String logNameSuffix, boolean rotate, LogFileHeaderGenerator fileHeader, final int closeRetryCount, final int closeRetryDelay) {
109111
this.logWriteExecutor = logWriteExecutor;
110112
this.outputDirectory = outputDirectory;
111113
this.logBaseName = logBaseName;
@@ -114,6 +116,8 @@ private DefaultAccessLogReceiver(final Executor logWriteExecutor, final Path out
114116
this.logNameSuffix = (logNameSuffix != null) ? logNameSuffix : DEFAULT_LOG_SUFFIX;
115117
this.pendingMessages = new ConcurrentLinkedDeque<>();
116118
this.defaultLogFile = outputDirectory.resolve(logBaseName + this.logNameSuffix);
119+
this.closeRetryCount = closeRetryCount;
120+
this.closeRetryDelay = closeRetryDelay;
117121
calculateChangeOverPoint();
118122
}
119123

@@ -341,10 +345,10 @@ public void close() throws IOException {
341345
return;
342346
}
343347
// either failed race to 1->3 or we were in 2. We have to wait here sometime.
344-
// wait ~1s, if situation does not clear up, try dumping stuff
345-
for(int i=0; i<20;i++) {
348+
// wait ~3s(by default), if situation does not clear up, try dumping stuff
349+
for(int i=0; i<this.closeRetryCount;i++) {
346350
try {
347-
Thread.currentThread().sleep(50);
351+
Thread.currentThread().sleep(this.closeRetryDelay);
348352
} catch (InterruptedException e) {
349353
// TODO Auto-generated catch block
350354
e.printStackTrace();
@@ -353,7 +357,10 @@ public void close() throws IOException {
353357
break;
354358
}
355359
}
356-
this.stateUpdater.set(this, 3);
360+
final int tempEndState = this.stateUpdater.getAndSet(this, 3);
361+
if(tempEndState == 2) {
362+
UndertowLogger.ROOT_LOGGER.accessLogWorkerNoTermination();
363+
}
357364
flushAndTerminate();
358365
}
359366
}
@@ -392,6 +399,8 @@ public static class Builder {
392399
private String logNameSuffix;
393400
private boolean rotate;
394401
private LogFileHeaderGenerator logFileHeaderGenerator;
402+
private int closeRetryCount = 60;
403+
private int closeRetryDelay = 50;
395404

396405
public Executor getLogWriteExecutor() {
397406
return logWriteExecutor;
@@ -447,8 +456,30 @@ public Builder setLogFileHeaderGenerator(LogFileHeaderGenerator logFileHeaderGen
447456
return this;
448457
}
449458

459+
public int getCloseRetryCount() {
460+
return closeRetryCount;
461+
}
462+
463+
public Builder setCloseRetryCount(int closeRetryCount) {
464+
this.closeRetryCount = closeRetryCount;
465+
return this;
466+
}
467+
468+
public int getCloseRetryDelay() {
469+
return closeRetryDelay;
470+
}
471+
472+
/**
473+
* Delay in ms between retrying poll on state to check for proper termination of worker
474+
* @param closeRetryDelay
475+
*/
476+
public Builder setCloseRetryDelay(int closeRetryDelay) {
477+
this.closeRetryDelay = closeRetryDelay;
478+
return this;
479+
}
480+
450481
public DefaultAccessLogReceiver build() {
451-
return new DefaultAccessLogReceiver(logWriteExecutor, outputDirectory, logBaseName, logNameSuffix, rotate, logFileHeaderGenerator);
482+
return new DefaultAccessLogReceiver(logWriteExecutor, outputDirectory, logBaseName, logNameSuffix, rotate, logFileHeaderGenerator, closeRetryCount, closeRetryDelay);
452483
}
453484
}
454485
}

0 commit comments

Comments
 (0)