-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Validations::flush() doesn't use JobQueue (RIPD-1356): #2083
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -429,25 +429,34 @@ class ValidationsImp : public Validations | |
bool anyNew = false; | ||
|
||
JLOG (j_.info()) << "Flushing validations"; | ||
ScopedLockType sl (mLock); | ||
for (auto& it: mCurrentValidations) | ||
{ | ||
if (it.second) | ||
mStaleValidations.push_back (it.second); | ||
|
||
anyNew = true; | ||
} | ||
mCurrentValidations.clear (); | ||
ScopedLockType sl (mLock); | ||
for (auto& it: mCurrentValidations) | ||
{ | ||
if (it.second) | ||
{ | ||
mStaleValidations.push_back (it.second); | ||
anyNew = true; | ||
} | ||
} | ||
mCurrentValidations.clear (); | ||
|
||
if (anyNew) | ||
condWrite (); | ||
// If there isn't a write in progress already, then write to the | ||
// database synchronously. | ||
if (anyNew && !mWriting) | ||
{ | ||
mWriting = true; | ||
doWrite (sl); | ||
} | ||
|
||
while (mWriting) | ||
{ | ||
ScopedUnlockType sul (mLock); | ||
std::this_thread::sleep_for (std::chrono::milliseconds (100)); | ||
// Handle the case where flush() is called while a queuedWrite | ||
// is already in progress. | ||
while (mWriting) | ||
{ | ||
ScopedUnlockType sul (mLock); | ||
std::this_thread::sleep_for (std::chrono::milliseconds (100)); | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It appears the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. My understanding of the standard is that any unsynchronized access (read or write) of a non-atomic by two different threads is undefined behavior. If my understanding is correct, then since However I could convert There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. My vote is to leave the code as Scott has written it. Scott is correct that the read needs to be protected, and this seems better than the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That sounds legit to me. The only reason I brought it up was that I noticed yesterday that there are several other instances of Soooooooo... Maybe do the same trick in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. PS. I'll note that my original comment had the disclaimer "unless I'm missing something". I missed something. 😆 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, I'll pass a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. BTW, I think it's better to ask the question and miss something than to not ask the question. So thanks for asking. |
||
} | ||
|
||
JLOG (j_.debug()) << "Validations flushed"; | ||
} | ||
|
||
|
@@ -458,20 +467,27 @@ class ValidationsImp : public Validations | |
|
||
mWriting = true; | ||
app_.getJobQueue ().addJob ( | ||
jtWRITE, "Validations::doWrite", | ||
[this] (Job&) { doWrite(); }); | ||
jtWRITE, "Validations::queuedWrite", | ||
[this] (Job&) { queuedWrite(); }); | ||
} | ||
|
||
void doWrite () | ||
void queuedWrite () | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, that's an excellent suggestion. Thanks. |
||
{ | ||
auto event = app_.getJobQueue ().getLoadEventAP (jtDISK, "ValidationWrite"); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What is the purpose of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it saves load/timing information for the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh! Ok. I haven't delved into the |
||
|
||
std::string insVal ("INSERT INTO Validations " | ||
ScopedLockType sl (mLock); | ||
doWrite (sl); | ||
} | ||
|
||
// NOTE: doWrite() must be called with mLock *locked*. The passed | ||
// ScopedLockType& acts as a reminder to future maintainers. | ||
void doWrite (ScopedLockType& sl) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you explain the purpose of passing in the scoped lock to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Passing in the reference to the lock is not required by the functionality. It's a way of signaling to maintainers that the lock must be held when |
||
{ | ||
std::string const insVal ("INSERT INTO Validations " | ||
"(InitialSeq, LedgerSeq, LedgerHash,NodePubKey,SignTime,RawData) " | ||
"VALUES (:initialSeq, :ledgerSeq, :ledgerHash,:nodePubKey,:signTime,:rawData);"); | ||
std::string findSeq("SELECT LedgerSeq FROM Ledgers WHERE Ledgerhash=:ledgerHash;"); | ||
std::string const findSeq("SELECT LedgerSeq FROM Ledgers WHERE Ledgerhash=:ledgerHash;"); | ||
|
||
ScopedLockType sl (mLock); | ||
assert (mWriting); | ||
|
||
while (!mStaleValidations.empty ()) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good fix!