Improve start of binary file timing

Code to better get binary files to start right on the hour when processing files offline rather than half a sec or so later.
This commit is contained in:
Douglas Gillespie 2024-06-10 13:03:18 +01:00
parent f0aca0c83f
commit 74759cb576
4 changed files with 92 additions and 25 deletions

View File

@ -2952,6 +2952,23 @@ public class PamController implements PamControllerInterface, PamSettings {
return pamConfiguration; return pamConfiguration;
} }
/**
* Gets called on a timer when NOT processing from files.
* OR if processing files, gets called whenever the Calendar session start time or file time millis gets updated.
* @param timeInMillis
*/
public void updateMasterClock(long timeInMillis) {
/*
* this needs to notify binary stores that time has changed since the BS doesn't subscribe
* to anything, so doesn't get other clock updates.
*/
ArrayList<PamControlledUnit> bs = findControlledUnits(BinaryStore.class);
for (PamControlledUnit aBS : bs) {
BinaryStore binStore = (BinaryStore) aBS;
binStore.getBinaryStoreProcess().checkFileTime(timeInMillis);
}
}
} }

View File

@ -25,6 +25,7 @@ import java.text.ParseException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.ZoneOffset; import java.time.ZoneOffset;
import java.util.ArrayList;
import java.util.Calendar; import java.util.Calendar;
import java.util.Date; import java.util.Date;
import java.util.Locale; import java.util.Locale;
@ -32,6 +33,7 @@ import java.util.TimeZone;
import PamController.PamController; import PamController.PamController;
import PamUtils.time.CalendarControl; import PamUtils.time.CalendarControl;
import binaryFileStorage.BinaryStore;
/** /**
@ -85,7 +87,7 @@ public class PamCalendar {
* viewPositions which is the number of milliseconds from the sessionsStartTime. * viewPositions which is the number of milliseconds from the sessionsStartTime.
*/ */
private static long viewPosition; private static long viewPosition;
/** /**
* If files are being analysed, return the time based on the file * If files are being analysed, return the time based on the file
@ -880,14 +882,18 @@ public class PamCalendar {
*/ */
public static void setSessionStartTime(long sessionStartTime) { public static void setSessionStartTime(long sessionStartTime) {
PamCalendar.sessionStartTime = sessionStartTime; PamCalendar.sessionStartTime = sessionStartTime;
PamController.getInstance().updateMasterClock(getTimeInMillis());
} }
/** /**
* *
* @param soundFileTimeMillis The start time of a sound file * Relative time within a sound file. This is always just added to sessionStartTime
* to give an absolute time.
* @param soundFileTimeMillis The relative time of a sound file.
*/ */
public static void setSoundFileTimeInMillis(long soundFileTimeMillis) { public static void setSoundFileTimeInMillis(long soundFileTimeMillis) {
PamCalendar.soundFileTimeInMillis = soundFileTimeMillis; PamCalendar.soundFileTimeInMillis = soundFileTimeMillis;
PamController.getInstance().updateMasterClock(getTimeInMillis());
} }
/** /**

View File

@ -228,6 +228,7 @@ PamSettingsSource, DataOutputStore {
super.pamToStart(); super.pamToStart();
prepareStores(); prepareStores();
openStores(); openStores();
binaryStoreProcess.checkFileTimer();
} }
@Override @Override
@ -245,9 +246,9 @@ PamSettingsSource, DataOutputStore {
* Called from the process to close and reopen each datastream in * Called from the process to close and reopen each datastream in
* a new file. Probably gets called about once an hour on the hour. * a new file. Probably gets called about once an hour on the hour.
*/ */
protected void reOpenStores(int endReason) { protected synchronized void reOpenStores(int endReason, long newFileTime) {
long dataTime = PamCalendar.getTimeInMillis(); long dataTime = newFileTime;//PamCalendar.getTimeInMillis();
long analTime = System.currentTimeMillis(); long analTime = System.currentTimeMillis();
BinaryOutputStream dataStream; BinaryOutputStream dataStream;
for (int i = 0; i < storageStreams.size(); i++) { for (int i = 0; i < storageStreams.size(); i++) {
@ -536,7 +537,7 @@ PamSettingsSource, DataOutputStore {
*/ */
if (immediateChanges) { if (immediateChanges) {
if (storesOpen) { if (storesOpen) {
reOpenStores(BinaryFooter.END_UNKNOWN); reOpenStores(BinaryFooter.END_UNKNOWN, PamCalendar.getTimeInMillis());
} }
} }
@ -2601,5 +2602,11 @@ PamSettingsSource, DataOutputStore {
public DataIntegrityChecker getInegrityChecker() { public DataIntegrityChecker getInegrityChecker() {
return new BinaryIntegrityChecker(this); return new BinaryIntegrityChecker(this);
} }
/**
* @return the binaryStoreProcess
*/
public BinaryStoreProcess getBinaryStoreProcess() {
return binaryStoreProcess;
}
} }

View File

@ -7,37 +7,43 @@ import PamUtils.PamCalendar;
import PamguardMVC.PamProcess; import PamguardMVC.PamProcess;
public class BinaryStoreProcess extends PamProcess { public class BinaryStoreProcess extends PamProcess {
private BinaryStore binaryStore; private BinaryStore binaryStore;
private long startTime; private long startTime;
private long nextFileTime; private long nextFileTime;
private Timer timer; private Timer timer;
private Object timerSynch = new Object();
public BinaryStoreProcess(BinaryStore binaryStore) { public BinaryStoreProcess(BinaryStore binaryStore) {
super(binaryStore, null); super(binaryStore, null);
this.binaryStore = binaryStore; this.binaryStore = binaryStore;
} }
@Override @Override
public String getProcessName() { public String getProcessName() {
return "Binary store file control"; return "Binary store file control";
} }
public synchronized void checkFileTime() { public synchronized void checkFileTime(long masterClockTime) {
// if (binaryStore.binaryStoreSettings.autoNewFiles &&
// PamCalendar.getTimeInMillis() >= nextFileTime) {
// startNewFiles();
// }
if (binaryStore.binaryStoreSettings.autoNewFiles && if (binaryStore.binaryStoreSettings.autoNewFiles &&
PamCalendar.getTimeInMillis() >= nextFileTime) { masterClockTime >= nextFileTime) {
startNewFiles(); startNewFiles(masterClockTime);
} }
} }
private synchronized void startNewFiles() { private synchronized void startNewFiles(long masterClockTime) {
nextFileTime += binaryStore.binaryStoreSettings.fileSeconds * 1000; nextFileTime += binaryStore.binaryStoreSettings.fileSeconds * 1000;
binaryStore.reOpenStores(BinaryFooter.END_FILETOOLONG); binaryStore.reOpenStores(BinaryFooter.END_FILETOOLONG, masterClockTime);
} }
@ -46,24 +52,55 @@ public class BinaryStoreProcess extends PamProcess {
startTime = PamCalendar.getTimeInMillis(); startTime = PamCalendar.getTimeInMillis();
long round = binaryStore.binaryStoreSettings.fileSeconds * 1000; long round = binaryStore.binaryStoreSettings.fileSeconds * 1000;
nextFileTime = (startTime/round) * round + round; nextFileTime = (startTime/round) * round + round;
// System.out.println("Next file start at " + PamCalendar.formatDateTime(nextFileTime)); // System.out.println("Next file start at " + PamCalendar.formatDateTime(nextFileTime));
timer = new Timer(); }
timer.schedule(new FileTimerTask(), 1000, 1000);
public void checkFileTimer() {
boolean needTimer = PamCalendar.isSoundFile() == false;
if (needTimer) {
startTimer();
}
else {
stopTimer();
}
} }
private void startTimer() {
synchronized (timerSynch) {
if (timer == null) {
timer = new Timer();
timer.schedule(new FileTimerTask(), 1000, 1000);
}
}
}
private void stopTimer() {
synchronized (timerSynch) {
if (timer != null) {
timer.cancel();
timer = null;
}
}
}
// @Override
// public void masterClockUpdate(long timeMilliseconds, long sampleNumber) {
// super.masterClockUpdate(timeMilliseconds, sampleNumber);
// checkFileTime(timeMilliseconds);
// }
class FileTimerTask extends TimerTask { class FileTimerTask extends TimerTask {
@Override @Override
public void run() { public void run() {
checkFileTime(); checkFileTime(PamCalendar.getTimeInMillis());
} }
} }
@Override @Override
public void pamStop() { public void pamStop() {
if (timer != null) { stopTimer();
timer.cancel();
}
} }
} }