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;
}
/**
* 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.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
@ -32,6 +33,7 @@ import java.util.TimeZone;
import PamController.PamController;
import PamUtils.time.CalendarControl;
import binaryFileStorage.BinaryStore;
/**
@ -85,7 +87,7 @@ public class PamCalendar {
* viewPositions which is the number of milliseconds from the sessionsStartTime.
*/
private static long viewPosition;
/**
* 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) {
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) {
PamCalendar.soundFileTimeInMillis = soundFileTimeMillis;
PamController.getInstance().updateMasterClock(getTimeInMillis());
}
/**

View File

@ -228,6 +228,7 @@ PamSettingsSource, DataOutputStore {
super.pamToStart();
prepareStores();
openStores();
binaryStoreProcess.checkFileTimer();
}
@Override
@ -245,9 +246,9 @@ PamSettingsSource, DataOutputStore {
* Called from the process to close and reopen each datastream in
* 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();
BinaryOutputStream dataStream;
for (int i = 0; i < storageStreams.size(); i++) {
@ -536,7 +537,7 @@ PamSettingsSource, DataOutputStore {
*/
if (immediateChanges) {
if (storesOpen) {
reOpenStores(BinaryFooter.END_UNKNOWN);
reOpenStores(BinaryFooter.END_UNKNOWN, PamCalendar.getTimeInMillis());
}
}
@ -2601,5 +2602,11 @@ PamSettingsSource, DataOutputStore {
public DataIntegrityChecker getInegrityChecker() {
return new BinaryIntegrityChecker(this);
}
/**
* @return the binaryStoreProcess
*/
public BinaryStoreProcess getBinaryStoreProcess() {
return binaryStoreProcess;
}
}

View File

@ -7,37 +7,43 @@ import PamUtils.PamCalendar;
import PamguardMVC.PamProcess;
public class BinaryStoreProcess extends PamProcess {
private BinaryStore binaryStore;
private long startTime;
private long nextFileTime;
private Timer timer;
private Object timerSynch = new Object();
public BinaryStoreProcess(BinaryStore binaryStore) {
super(binaryStore, null);
this.binaryStore = binaryStore;
}
@Override
public String getProcessName() {
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 &&
PamCalendar.getTimeInMillis() >= nextFileTime) {
startNewFiles();
masterClockTime >= nextFileTime) {
startNewFiles(masterClockTime);
}
}
private synchronized void startNewFiles() {
private synchronized void startNewFiles(long masterClockTime) {
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();
long round = binaryStore.binaryStoreSettings.fileSeconds * 1000;
nextFileTime = (startTime/round) * round + round;
// System.out.println("Next file start at " + PamCalendar.formatDateTime(nextFileTime));
timer = new Timer();
timer.schedule(new FileTimerTask(), 1000, 1000);
// System.out.println("Next file start at " + PamCalendar.formatDateTime(nextFileTime));
}
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 {
@Override
public void run() {
checkFileTime();
checkFileTime(PamCalendar.getTimeInMillis());
}
}
@Override
public void pamStop() {
if (timer != null) {
timer.cancel();
}
stopTimer();
}
}