Added _minRepetitions to msgPrintControl
This is an API breaking change, because the previous maxRepetitions_ member (size_t) is replaced with the msgPrintControlOptions struct. However, since this value is only used once in the entire sinqMotor ecosystem, I deemed this an acceptable tradeoff and did not bump the major version.
This commit is contained in:
1 parent
7cad532a29
commit
b173b9554b
2 files changed
+93
-66
No files matched your search
+51
-58
@@ -5,9 +5,9 @@
|
||||
|
||||
msgPrintControlKey::msgPrintControlKey(char *controller, int axisNo,
|
||||
const char *functionName, int line,
|
||||
size_t maxRepetitions)
|
||||
msgPrintControlOptions options)
|
||||
: controller_(controller), axisNo_(axisNo), functionName_(functionName),
|
||||
line_(line), maxRepetitions_(maxRepetitions) {}
|
||||
line_(line), options_(options) {}
|
||||
|
||||
void msgPrintControlKey::format(char *buffer, size_t bufferSize) {
|
||||
snprintf(buffer, bufferSize, "controller %s, axis %d, function %s, line %d",
|
||||
@@ -22,76 +22,69 @@ msgPrintControl::~msgPrintControl() = default;
|
||||
|
||||
bool msgPrintControl::shouldBePrinted(msgPrintControlKey &key, bool wantToPrint,
|
||||
asynUser *pasynUser) {
|
||||
|
||||
// Reset the suffix
|
||||
suffix_[0] = 0;
|
||||
|
||||
if (wantToPrint) {
|
||||
/*
|
||||
We want to print the message associated with key -> Check if the number
|
||||
of allowed repetitions is exceeded. If true, inform the user that
|
||||
further output is suppressed.
|
||||
*/
|
||||
if (map_.find(key) != map_.end()) {
|
||||
size_t repetitions = map_[key];
|
||||
if (repetitions < key.maxRepetitions_) {
|
||||
// Number of allowed repetitions not exceeded -> Printing the
|
||||
// message is ok.
|
||||
map_[key] = repetitions + 1;
|
||||
return true;
|
||||
} else if (repetitions == key.maxRepetitions_) {
|
||||
// Reached number of allowed repetitions -> Printing the message
|
||||
// is ok, but further trys are rejected.
|
||||
if (!wantToPrint) {
|
||||
auto iter = map_.find(key);
|
||||
|
||||
if (iter != map_.end() && iter->second != 0) {
|
||||
if (pasynUser != nullptr) {
|
||||
char formattedKey[100] = {0};
|
||||
key.format(formattedKey, sizeof(formattedKey));
|
||||
snprintf(suffix_, sizeof(suffix_),
|
||||
" Further repetition of this error message (key "
|
||||
"\"%s\") is suppressed.",
|
||||
formattedKey);
|
||||
map_[key] = repetitions + 1;
|
||||
return true;
|
||||
} else {
|
||||
// Exceeded number of allowed repetitions -> Do not print the
|
||||
// message
|
||||
return false;
|
||||
|
||||
asynPrint(
|
||||
pasynUser, ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\", axis %d => %s, line %d\n"
|
||||
"Error associated with key \"%s\" has been resolved.\n",
|
||||
key.controller_.c_str(), key.axisNo_,
|
||||
key.functionName_.c_str(), key.line_, formattedKey);
|
||||
}
|
||||
} else {
|
||||
// Message is not yet in map -> create an entry so it is watched in
|
||||
// the future.
|
||||
map_[key] = 1;
|
||||
return true;
|
||||
|
||||
iter->second = 0;
|
||||
}
|
||||
|
||||
} else {
|
||||
/*
|
||||
We do not want to print the message associated with key -> If the key is
|
||||
part of the map, set the counter back to zero.
|
||||
*/
|
||||
if (map_.find(key) != map_.end()) {
|
||||
if (map_[key] != 0) {
|
||||
if (pasynUser != nullptr) {
|
||||
char formattedKey[100] = {0};
|
||||
key.format(formattedKey, sizeof(formattedKey));
|
||||
asynPrint(
|
||||
pasynUser, ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nError "
|
||||
"associated with key \"%s\" has been resolved.\n",
|
||||
key.controller_.c_str(), key.axisNo_,
|
||||
key.functionName_.c_str(), key.line_, formattedKey);
|
||||
}
|
||||
map_[key] = 0;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
auto iter = map_.find(key);
|
||||
|
||||
if (iter == map_.end()) {
|
||||
// First occurrence.
|
||||
map_[key] = 1;
|
||||
return key.options_.minRepetitions == 0;
|
||||
}
|
||||
|
||||
size_t &repetitions = iter->second;
|
||||
++repetitions;
|
||||
|
||||
// Print one final message when suppression starts.
|
||||
if (repetitions == key.options_.maxRepetitions + 1) {
|
||||
char formattedKey[100] = {0};
|
||||
key.format(formattedKey, sizeof(formattedKey));
|
||||
|
||||
snprintf(suffix_, sizeof(suffix_),
|
||||
" Further repetition of this error message (key "
|
||||
"\"%s\") is suppressed.",
|
||||
formattedKey);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Suppress everything after the notification.
|
||||
if (repetitions > key.options_.maxRepetitions) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Suppress occurrences before minRepetitions.
|
||||
return repetitions > key.options_.minRepetitions;
|
||||
}
|
||||
|
||||
bool msgPrintControl::shouldBePrinted(char *portName, int axisNo,
|
||||
const char *functionName, int line,
|
||||
bool wantToPrint, asynUser *pasynUser,
|
||||
size_t maxRepetitions) {
|
||||
msgPrintControlKey key = msgPrintControlKey(portName, axisNo, functionName,
|
||||
line, maxRepetitions);
|
||||
msgPrintControlOptions options) {
|
||||
msgPrintControlKey key =
|
||||
msgPrintControlKey(portName, axisNo, functionName, line, options);
|
||||
return shouldBePrinted(key, wantToPrint, pasynUser);
|
||||
}
|
||||
|
||||
|
||||
+42
-8
@@ -3,8 +3,6 @@
|
||||
#ifndef msgPrintControl_H
|
||||
#define msgPrintControl_H
|
||||
|
||||
#define DefaultMaxRepetitions 4
|
||||
|
||||
// The EPICS libaries do not follow -Weffc++
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Weffc++"
|
||||
@@ -18,6 +16,41 @@
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
/**
|
||||
* @brief Configuration options controlling repetition of a message.
|
||||
*
|
||||
* These options determine how many consecutive occurrences of a message
|
||||
* are suppressed or printed by msgPrintControl.
|
||||
*
|
||||
* A message is identified by its msgPrintControlKey. The repetition count
|
||||
* is reset when `wantToPrint` is false.
|
||||
*/
|
||||
struct msgPrintControlOptions {
|
||||
/**
|
||||
* @brief Maximum number of consecutive occurrences that are printed.
|
||||
*
|
||||
* Once this number of consecutive occurrences has been reached,
|
||||
* subsequent occurrences are suppressed until the repetition count
|
||||
* is reset.
|
||||
*
|
||||
* The default value is 4.
|
||||
*/
|
||||
size_t maxRepetitions = 4;
|
||||
|
||||
/**
|
||||
* @brief Minimum number of consecutive repetitions before printing.
|
||||
*
|
||||
* This many consecutive occurrences are suppressed before the message
|
||||
* is printed. For example, a value of 2 suppresses the first two
|
||||
* occurrences and prints the third and subsequent occurrences.
|
||||
*
|
||||
* A value of 0 disables the minimum-repetition requirement and
|
||||
* preserves the original behaviour, where the first occurrence is
|
||||
* printed.
|
||||
*/
|
||||
size_t minRepetitions = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Class to identify a message print location. See the docstring of
|
||||
* `msgPrintControl` on how to use this key.
|
||||
@@ -26,7 +59,7 @@
|
||||
class HIDDEN msgPrintControlKey {
|
||||
public:
|
||||
msgPrintControlKey(char *controller_, int axisNo, const char *fileName,
|
||||
int line, size_t maxRepetitions = DefaultMaxRepetitions);
|
||||
int line, msgPrintControlOptions options = {});
|
||||
|
||||
bool operator==(const msgPrintControlKey &other) const {
|
||||
return axisNo_ == other.axisNo_ && line_ == other.line_ &&
|
||||
@@ -45,11 +78,12 @@ class HIDDEN msgPrintControlKey {
|
||||
int line_;
|
||||
|
||||
/**
|
||||
* @brief Maximum number of times a message is printed before it is
|
||||
* suppressed. This number is not used as part of the hash.
|
||||
* @brief Repetition-control options for this message.
|
||||
*
|
||||
* These options are not part of the key identity and are therefore not
|
||||
* considered by operator==() or std::hash<msgPrintControlKey>.
|
||||
*/
|
||||
size_t maxRepetitions_;
|
||||
msgPrintControlOptions options_;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -106,7 +140,7 @@ class HIDDEN msgPrintControl {
|
||||
|
||||
/**
|
||||
* @brief Checks if the error message associated with "key" has been printed
|
||||
* more than `this->maxRepetitions_` times in a row. If yes, returns false,
|
||||
* more than `key->maxRepetitions_` times in a row. If yes, returns false,
|
||||
* otherwise true. Counter is reset if `wantToPrint` is false.
|
||||
*
|
||||
* If the conditions for printing a message are met, `wantToPrint` must be
|
||||
@@ -145,7 +179,7 @@ class HIDDEN msgPrintControl {
|
||||
*/
|
||||
bool shouldBePrinted(char *controller, int axisNo, const char *functionName,
|
||||
int line, bool wantToPrint, asynUser *pasynUser,
|
||||
size_t maxRepetitions = DefaultMaxRepetitions);
|
||||
msgPrintControlOptions options = {});
|
||||
|
||||
/**
|
||||
* @brief Reset the error message count incremented in `shouldBePrinted` for
|
||||
|
||||
Reference in new issue
Block a user