Skip to content

Commit 7d3b235

Browse files
committed
round-robin recording
1 parent d9fb708 commit 7d3b235

File tree

4 files changed

+27
-5
lines changed

4 files changed

+27
-5
lines changed

doc/configurationParameters.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ The parameters related to 3rd-party libraries are described here for convenience
107107
| consumer-fileRecorder-* | dropEmptyHBFrames | int | 0 | If 1, memory pages are scanned and empty HBframes are discarded, i.e. couples of packets which contain only RDH, the first one with pagesCounter=0 and the second with stop bit set. This setting does not change the content of in-memory data pages, other consumers would still get full data pages with empty packets. This setting is meant to reduce the amount of data recorded for continuous detectors in triggered mode. Use with dropEmptyHBFramesTriggerMask, if some empty frames with specific trigger types need to be kept (eg TF or SOC). |
108108
| consumer-fileRecorder-* | dropEmptyHBFramesTriggerMask | int | 0 | (when using dropEmptyHBFrames = 1) empty HB frames are kept if any bit in RDH TriggerType field matches this pattern (RDHTriggerType & TriggerMask != 0). To be provided as a decimal value: eg 2048 (TF triggers, bit 11), 3584 (TF + SOC + EOC bits 9,10,11). |
109109
| consumer-fileRecorder-* | fileName | string | | Path to the file where to record data. The following variables are replaced at runtime: ${XXX} -> get variable XXX from environment, %t -> unix timestamp (seconds since epoch), %T -> formatted date/time, %i -> equipment ID of each data chunk (used to write data from different equipments to different output files), %l -> link ID (used to write data from different links to different output files). |
110-
| consumer-fileRecorder-* | filesMax | int | 1 | If 1 (default), file splitting is disabled: file is closed whenever a limit is reached on a given recording stream. Otherwise, file splitting is enabled: whenever the current file reaches a limit, it is closed an new one is created (with an incremental name). If <=0, an unlimited number of incremental chunks can be created. If non-zero, it defines the maximum number of chunks. The file name is suffixed with chunk number (by default, ".001, .002, ..." at the end of the file name. One may use "%f" in the file name to define where this incremental file counter is printed. |
110+
| consumer-fileRecorder-* | filesMax | int | 1 | If 1 (default), file splitting is disabled: file is closed whenever a limit is reached on a given recording stream. Otherwise, file splitting is enabled: whenever the current file reaches a limit, it is closed an new one is created (with an incremental name). If = 0, an unlimited number of incremental chunks can be created. If smaller than zero, it defines the number of chunks to use round-robin, indefinitely. If bigger than zero, it defines the maximum number of chunks. The file name is suffixed with chunk number (by default, ".001, .002, ..." at the end of the file name. One may use "%f" in the file name to define where this incremental file counter is printed. |
111111
| consumer-fileRecorder-* | pagesMax | int | 0 | Maximum number of data pages accepted by recorder. If zero (default), no maximum set.|
112112
| consumer-fileRecorder-* | tfMax | int | 0 | Maximum number of timeframes accepted by recorder. If zero (default), no maximum set.|
113113
| consumer-processor-* | ensurePageOrder | int | 0 | If set, ensures that data pages goes out of the processing pool in same order as input (which is not guaranteed with multithreading otherwise). This option adds latency. |

doc/releaseNotes.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -588,3 +588,7 @@ This file describes the main feature changes for each readout.exe released versi
588588

589589
## v2.21.3 - 05/10/2023
590590
- Monitoring: fix multiple publish if system stuck for longer than the update period.
591+
592+
## next version
593+
- Updated configuration parameters:
594+
- consumer-fileRecorder-*.filesMax: if negative value, the files are written round-robin indefinitely. For example, if value is -4, there will be files 001 to 004 used as circular buffer. This implies limits are defined with the other parameters (e.g. maximum size, number of tf, or pages).

src/ConsumerFileRecorder.cxx

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -197,16 +197,18 @@ class ConsumerFileRecorder : public Consumer
197197
cfg.getOptionalValue(cfgEntryPoint + ".dataBlockHeaderEnabled", recordWithDataBlockHeader, 0);
198198
theLog.log(LogInfoDevel_(3002), "Recording internal data block headers = %d", recordWithDataBlockHeader);
199199

200-
// configuration parameter: | consumer-fileRecorder-* | filesMax | int | 1 | If 1 (default), file splitting is disabled: file is closed whenever a limit is reached on a given recording stream. Otherwise, file splitting is enabled: whenever the current file reaches a limit, it is closed an new one is created (with an incremental name). If <=0, an unlimited number of incremental chunks can be created. If non-zero, it defines the maximum number of chunks. The file name is suffixed with chunk number (by default, ".001, .002, ..." at the end of the file name. One may use "%f" in the file name to define where this incremental file counter is printed. |
200+
// configuration parameter: | consumer-fileRecorder-* | filesMax | int | 1 | If 1 (default), file splitting is disabled: file is closed whenever a limit is reached on a given recording stream. Otherwise, file splitting is enabled: whenever the current file reaches a limit, it is closed an new one is created (with an incremental name). If = 0, an unlimited number of incremental chunks can be created. If smaller than zero, it defines the number of chunks to use round-robin, indefinitely. If bigger than zero, it defines the maximum number of chunks. The file name is suffixed with chunk number (by default, ".001, .002, ..." at the end of the file name. One may use "%f" in the file name to define where this incremental file counter is printed. |
201201
filesMax = 1;
202202
if (cfg.getOptionalValue<int>(cfgEntryPoint + ".filesMax", filesMax) == 0) {
203203
if (filesMax == 1) {
204204
theLog.log(LogInfoDevel_(3002), "File splitting disabled");
205205
} else {
206206
if (filesMax > 0) {
207207
theLog.log(LogInfoDevel_(3002), "File splitting enabled - max %d files per stream", filesMax);
208-
} else {
208+
} else if (filesMax == 0) {
209209
theLog.log(LogInfoDevel_(3002), "File splitting enabled - unlimited files");
210+
} else {
211+
theLog.log(LogInfoDevel_(3002), "File splitting enabled - %d files round-robin, indefinitely", (-filesMax) );
210212
}
211213
}
212214
}
@@ -401,7 +403,11 @@ class ConsumerFileRecorder : public Consumer
401403
}
402404

403405
// create file handle
404-
std::shared_ptr<FileHandle> newHandle = std::make_shared<FileHandle>(newFileName, &theLog, maxFileSize, maxFilePages, maxFileTF);
406+
InfoLogger* _theLog = &theLog;
407+
if (silence) {
408+
_theLog = nullptr;
409+
}
410+
std::shared_ptr<FileHandle> newHandle = std::make_shared<FileHandle>(newFileName, _theLog, maxFileSize, maxFilePages, maxFileTF);
405411
if (newHandle == nullptr) {
406412
return -1;
407413
}
@@ -483,6 +489,16 @@ class ConsumerFileRecorder : public Consumer
483489
// let's move to next file chunk
484490
int fileId = fpUsed->fileId;
485491
fileId++;
492+
if (filesMax<0) {
493+
if ((fileId % (-filesMax)) == 1) {
494+
fileId = 1;
495+
if (!silence) {
496+
// stop logging round-robin creation of files
497+
theLog.logInfo("Recording now continues round-robin on existing files, further iterations will not be logged.");
498+
silence = 1;
499+
}
500+
}
501+
}
486502
if ((filesMax < 1) || (fileId <= filesMax)) {
487503
createFile(&fpUsed, sourceId, false, fileId);
488504
}
@@ -651,6 +667,8 @@ class ConsumerFileRecorder : public Consumer
651667
int dropEmptyHBFrames = 0; // if set, some empty packets are discarded (see logic in code)
652668
int dropEmptyHBFramesTriggerMask = 0; // (when using dropEmptyHBFrames = 1) empty HB frames are kept if any bit in RDH TriggerType field matches this pattern. (TriggerType & TriggerMask != 0)
653669

670+
bool silence = 0; // when set, no logs are printed
671+
654672
class Packet
655673
{
656674
public:

src/readoutConfigEditor.tcl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ set configurationParametersDescriptor {
5353
| consumer-fileRecorder-* | dropEmptyHBFrames | int | 0 | If 1, memory pages are scanned and empty HBframes are discarded, i.e. couples of packets which contain only RDH, the first one with pagesCounter=0 and the second with stop bit set. This setting does not change the content of in-memory data pages, other consumers would still get full data pages with empty packets. This setting is meant to reduce the amount of data recorded for continuous detectors in triggered mode. Use with dropEmptyHBFramesTriggerMask, if some empty frames with specific trigger types need to be kept (eg TF or SOC). |
5454
| consumer-fileRecorder-* | dropEmptyHBFramesTriggerMask | int | 0 | (when using dropEmptyHBFrames = 1) empty HB frames are kept if any bit in RDH TriggerType field matches this pattern (RDHTriggerType & TriggerMask != 0). To be provided as a decimal value: eg 2048 (TF triggers, bit 11), 3584 (TF + SOC + EOC bits 9,10,11). |
5555
| consumer-fileRecorder-* | fileName | string | | Path to the file where to record data. The following variables are replaced at runtime: ${XXX} -> get variable XXX from environment, %t -> unix timestamp (seconds since epoch), %T -> formatted date/time, %i -> equipment ID of each data chunk (used to write data from different equipments to different output files), %l -> link ID (used to write data from different links to different output files). |
56-
| consumer-fileRecorder-* | filesMax | int | 1 | If 1 (default), file splitting is disabled: file is closed whenever a limit is reached on a given recording stream. Otherwise, file splitting is enabled: whenever the current file reaches a limit, it is closed an new one is created (with an incremental name). If <=0, an unlimited number of incremental chunks can be created. If non-zero, it defines the maximum number of chunks. The file name is suffixed with chunk number (by default, ".001, .002, ..." at the end of the file name. One may use "%f" in the file name to define where this incremental file counter is printed. |
56+
| consumer-fileRecorder-* | filesMax | int | 1 | If 1 (default), file splitting is disabled: file is closed whenever a limit is reached on a given recording stream. Otherwise, file splitting is enabled: whenever the current file reaches a limit, it is closed an new one is created (with an incremental name). If = 0, an unlimited number of incremental chunks can be created. If smaller than zero, it defines the number of chunks to use round-robin, indefinitely. If bigger than zero, it defines the maximum number of chunks. The file name is suffixed with chunk number (by default, ".001, .002, ..." at the end of the file name. One may use "%f" in the file name to define where this incremental file counter is printed. |
5757
| consumer-fileRecorder-* | pagesMax | int | 0 | Maximum number of data pages accepted by recorder. If zero (default), no maximum set.|
5858
| consumer-fileRecorder-* | tfMax | int | 0 | Maximum number of timeframes accepted by recorder. If zero (default), no maximum set.|
5959
| consumer-processor-* | ensurePageOrder | int | 0 | If set, ensures that data pages goes out of the processing pool in same order as input (which is not guaranteed with multithreading otherwise). This option adds latency. |

0 commit comments

Comments
 (0)