diff --git a/common/src/main/java/ctbrec/recorder/Statistics.java b/common/src/main/java/ctbrec/recorder/Statistics.java index 61583164..c9cd229c 100644 --- a/common/src/main/java/ctbrec/recorder/Statistics.java +++ b/common/src/main/java/ctbrec/recorder/Statistics.java @@ -10,6 +10,8 @@ public class Statistics { public ReadWriteLock statsLock = new ReentrantReadWriteLock(); public CircularFifoBuffer stats = new CircularFifoBuffer(100); + public long errorCount = 0; + public void add(Object val) { statsLock.writeLock().lock(); try { diff --git a/common/src/main/java/ctbrec/recorder/download/hls/MergedFfmpegHlsDownload.java b/common/src/main/java/ctbrec/recorder/download/hls/MergedFfmpegHlsDownload.java index 5bea39db..12c3249d 100644 --- a/common/src/main/java/ctbrec/recorder/download/hls/MergedFfmpegHlsDownload.java +++ b/common/src/main/java/ctbrec/recorder/download/hls/MergedFfmpegHlsDownload.java @@ -6,8 +6,11 @@ import ctbrec.OS; import ctbrec.Recording; import ctbrec.io.HttpClient; import ctbrec.recorder.FFmpeg; +import ctbrec.recorder.SimplifiedLocalRecorder; import ctbrec.recorder.download.ProcessExitedUncleanException; import ctbrec.recorder.download.hls.SegmentPlaylist.Segment; +import lombok.Getter; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -16,6 +19,7 @@ import java.io.File; import java.io.IOException; import java.io.OutputStream; import java.nio.file.Files; +import java.time.Duration; import java.time.Instant; import java.util.concurrent.*; import java.util.concurrent.locks.Lock; @@ -25,7 +29,7 @@ import java.util.regex.Pattern; public class MergedFfmpegHlsDownload extends AbstractHlsDownload { private static final Logger LOG = LoggerFactory.getLogger(MergedFfmpegHlsDownload.class); - + protected File targetFile; protected FFmpeg ffmpeg; protected Process ffmpegProcess; @@ -34,7 +38,15 @@ public class MergedFfmpegHlsDownload extends AbstractHlsDownload { protected Lock ffmpegStreamLock = new ReentrantLock(); public String getStats() { - String text = (running ? "RUN" : "stp") + String.format(" %d: ", queue.size()); + // check if lock is held + var locked = ffmpegStreamLock.tryLock(); + if (locked) ffmpegStreamLock.unlock(); + + String text = (running ? "RUN" : "stp") + + String.format(" lag=%6dms lock=%b %d: ", + Duration.between(lastSegmentDownload, Instant.now()).toMillis(), + !locked, + queue.size()); for (var elem : queue) { text += elem.isDone() ? "|" : "-"; } @@ -148,7 +160,12 @@ public class MergedFfmpegHlsDownload extends AbstractHlsDownload { @Override protected void execute(SegmentDownload segmentDownload) { - queue.add(segmentDownloadService.submit(segmentDownload)); + try { + queue.add(segmentDownloadService.submit(segmentDownload)); + } catch (Exception e) { + SimplifiedLocalRecorder.STATS.errorCount++; + throw e; + } LOG.trace("Enqueuing segment for file {}", targetFile); } diff --git a/server/src/main/java/ctbrec/recorder/server/DebugServlet.java b/server/src/main/java/ctbrec/recorder/server/DebugServlet.java index d0a069b3..2c75031f 100644 --- a/server/src/main/java/ctbrec/recorder/server/DebugServlet.java +++ b/server/src/main/java/ctbrec/recorder/server/DebugServlet.java @@ -69,15 +69,18 @@ public class DebugServlet extends AbstractCtbrecServlet { resp.setContentType("text/plain"); sendResponse(resp, SC_OK, box.text); } else if ((m = URL_PATTERN_DEBUG_STATS.matcher(requestURI)).matches()) { - String text = ""; + // + String text = ""; text += String.format("GLOBAL_HTTP_CONN_POOL: connectionCount=%d, idleConnectionCount=%d\n", HttpClient.getGLOBAL_HTTP_CONN_POOL().connectionCount(), HttpClient.getGLOBAL_HTTP_CONN_POOL().idleConnectionCount()); + var rlock = SimplifiedLocalRecorder.STATS.statsLock.readLock(); rlock.lock(); try { text += String.format("Time between download iterations = %s\n", SimplifiedLocalRecorder.STATS.stats.toString()); + text += String.format("Error count: %d\n", SimplifiedLocalRecorder.STATS.errorCount); } finally { rlock.unlock(); } @@ -88,7 +91,7 @@ public class DebugServlet extends AbstractCtbrecServlet { for (var rec : recorder.getRecordings()) { var proc = rec.getRecordingProcess(); if (proc == null) continue; - text += String.format("%s%s\n", proc.getModel().getDisplayName(), proc.getStats()); + text += String.format("%s%s\n", proc.getModel().getDisplayName(), proc.getStats().replace(" ", " ")); } text += "";