Skip to content
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

wallet: Remove boost from PeriodicFlush #18792

Merged
merged 3 commits into from
Jun 2, 2020

Conversation

maflcko
Copy link
Member

@maflcko maflcko commented Apr 28, 2020

The boost::this_thread::interruption_point() in the code base currently block the replacement of boost::thread with std::thread. [1]

Remove them from the wallet because they are either unused or useless.

The feature to interrupt a periodic flush is useless because all wallets have just been flushed

client->flush();
and another flush should be a noop. Also, they will be flushed again shortly after
client->stop();
, so even if repeated flushes weren't a noop, doing 3 instead of 2 shouldn't matter too much at this point. Also, the wallet is flushed every two seconds in the worst case, so if this is an expensive operation, that period should be readjusted. (Or bdb should be removed altogether #18916)

[1] Replacement of boost::thread with std::thread should happen because:

  • The boost thread dependency is slow to compile
  • Boost thread is less maintained than the standard lib
  • Boost thread is mostly redundant to the standard lib
  • Global interruption points via exceptions are hard to keep track of during review and easy to get wrong during runtime (e.g. accidental catch (...))

@maflcko
Copy link
Member Author

maflcko commented Apr 28, 2020

Not sure how to test manually, but I have included a unit test

@hebasto
Copy link
Member

hebasto commented Apr 28, 2020

Concept ACK.

@practicalswift
Copy link
Contributor

Concept ACK

@laanwj
Copy link
Member

laanwj commented Apr 30, 2020

The main thing to review here is the change in behavior: interruption_point raises an exception that escalates all the way to the thread main level, while the new code returns false, which is handled differently. For example it will still continue iterating over for (const std::shared_ptr<CWallet>& pwallet : GetWallets()) {. so dbh.nLastSeen and dbh.nLastWalletUpdate will be updated for all of them. I do not know if this is a problem.

@maflcko maflcko force-pushed the 2004-walletNoBoostPeriodicFlush branch from fae3bd8 to fa900e6 Compare April 30, 2020 11:01
@maflcko
Copy link
Member Author

maflcko commented Apr 30, 2020

I do not know if this is a problem

Me neither, but it seems avoidable by adding one more if-check. Done that.

@laanwj
Copy link
Member

laanwj commented Apr 30, 2020

Shouldn't the check be at the beginning of the for loop instead of of MaybeCompactWalletDB in that case?

@maflcko maflcko force-pushed the 2004-walletNoBoostPeriodicFlush branch from fa900e6 to faddf20 Compare April 30, 2020 11:58
@maflcko
Copy link
Member Author

maflcko commented Apr 30, 2020

Thanks, fixed.

@maflcko maflcko force-pushed the 2004-walletNoBoostPeriodicFlush branch from faddf20 to fa223c3 Compare May 4, 2020 17:54
@maflcko
Copy link
Member Author

maflcko commented May 4, 2020

Rebased after silent merge conflict

@DrahtBot
Copy link
Contributor

DrahtBot commented May 14, 2020

The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

Conflicts

Reviewers, this pull request conflicts with the following ones:

If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first.

Copy link
Contributor

@jnewbery jnewbery left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Concept ACK. Can you add a description for this PR?

You say here: #18758 (comment) that these interruption points can't be used. Were they used at some point in the past and were broken? If so, have you been able to determine which commit broke them? If not, I don't think it's worth adding the extra shutdown handling in this PR. It could potentially be added in a future PR.

You can remove the #include <boost/thread.hpp> from walletdb.cpp and db.cpp.

@@ -433,6 +433,8 @@ void CWallet::Flush(bool shutdown)
database->Flush(shutdown);
}

std::atomic<bool> CWallet::m_end_flush{false};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not use default member initialization in the header file?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This wouldn't compile. Thanks C++

@maflcko
Copy link
Member Author

maflcko commented May 26, 2020

Concept ACK. Can you add a description for this PR?

Done

@maflcko
Copy link
Member Author

maflcko commented May 26, 2020

You say here: #18758 (comment) that these interruption points can't be used.

Sorry, that pull is still marked as draft and is not ready for review. The decision boils down to "Is the interruption point run in a std::thread? If yes, the interruption point is unused".

Here, the scheduler is (still) a boost::thread, so the point should not be unused.

@maflcko maflcko force-pushed the 2004-walletNoBoostPeriodicFlush branch from fa223c3 to fabd1c9 Compare May 26, 2020 10:51
@maflcko
Copy link
Member Author

maflcko commented May 26, 2020

Force pushed to address feedback by @jnewbery (remove boost include from db.cpp)

@jnewbery
Copy link
Contributor

Force pushed to address feedback by @jnewbery (remove boost include from db.cpp)

I also suggested removing it from walletdb.cpp. Is that not possible?

@jnewbery
Copy link
Contributor

the scheduler is (still) a boost::thread, so the point should not be unused.

From a quick read of https://www.boost.org/doc/libs/1_53_0/doc/html/thread/thread_management.html#thread.thread_management.tutorial.interruption, it seems to me that the boost::thread::interruption_point only does anything if that thread's interrupt() function is called.

The only place that happens is the threadGroup.interrupt_all() call in Shutdown(), which (since #18234) happens after the scheduler thread is stopped.

I haven't looked deeply enough into #18234 to figure out whether that's a regression. If not, I think we can just remove all of these interrupt points that no longer do anything. If it is a regression, then perhaps this PR should explicitly state that it's a bug fix.

@maflcko
Copy link
Member Author

maflcko commented May 26, 2020

walletdb.cpp is still using it

catch (const boost::thread_interrupted&) {

@maflcko
Copy link
Member Author

maflcko commented May 26, 2020

The only place that happens is the threadGroup.interrupt_all() call in Shutdown(), which (since #18234) happens after the scheduler thread is stopped.

It looks like 306f71b tells the scheduler to stop after the current task is executed or before the execution starts (i.e. the scheduler is waiting for the next flush). The call is non-blocking when a task is currently executed. Consequently, the next line will interrupt all threads in the thread group, which will also interrupt the periodic flush action in case it is currently running. So I don't think the behaviour has changed in that commit, at least not in regard to flushing? Correct me if I am wrong.

@maflcko
Copy link
Member Author

maflcko commented May 26, 2020

I start to wonder if it is worth to abort the periodic flush when flush(true) is called shortly after in StopWallets.

@jnewbery
Copy link
Contributor

walletdb.cpp is still using it ...

That's a catch in WalletBatch::LoadWallet(), which I think is only called in the main thread or rpc thread.

@jnewbery
Copy link
Contributor

It looks like 306f71b tells the scheduler to stop after the current task is executed or before the execution starts (i.e. the scheduler is waiting for the next flush). The call is non-blocking when a task is currently executed. Consequently, the next line will interrupt all threads in the thread group, which will also interrupt the periodic flush action in case it is currently running. So I don't think the behaviour has changed in that commit, at least not in regard to flushing? Correct me if I am wrong.

No, you're right. I misunderstood what stop() was doing.

I start to wonder if it is worth to abort the periodic flush when flush(true) is called shortly after in StopWallets.

Yes, it does seem unnecessary. We call flush() on all wallets before interrupting the scheduler thread:

https://github.com/bitcoin/bitcoin/blob/master/src/init.cpp#L194

then we interrupt the scheduler thread (which may cause us to interrupt a periodic flush), and then we flush again on shutdown:

https://github.com/bitcoin/bitcoin/blob/master/src/init.cpp#L285

Making that middle flush interruptible does seem unnecessary.

@maflcko maflcko force-pushed the 2004-walletNoBoostPeriodicFlush branch from fabd1c9 to e8a8e37 Compare May 27, 2020 16:28
@maflcko
Copy link
Member Author

maflcko commented May 28, 2020

@laanwj @hebasto Mind taking another look here?

Copy link
Member

@fanquake fanquake left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK the change - however there's another boost::thread_interrupted& in walletdb.cpp:

}
catch (const boost::thread_interrupted&) {
throw;
}

I think it can also be removed, but if not, I'm not sure how we can drop the <boost/thread.hpp> include as unused in fa7b885.

FindWalletTx is only called by zapwallet, which is never called in a
boost::thread
@maflcko
Copy link
Member Author

maflcko commented Jun 2, 2020

@fanquake Good catch. Added a commit with rationale to remove that as well.

Copy link
Member

@fanquake fanquake left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK fa1c74f

@fanquake fanquake merged commit 5879bfa into bitcoin:master Jun 2, 2020
@maflcko maflcko deleted the 2004-walletNoBoostPeriodicFlush branch June 2, 2020 14:38
sidhujag pushed a commit to syscoin/syscoin that referenced this pull request Jun 2, 2020
fa1c74f wallet: Remove unused boost::thread_interrupted (MarcoFalke)
fa7b885 walletdb: Remove unsed boost/thread (MarcoFalke)
5555d97 wallet: Make PeriodicFlush uninterruptible (MarcoFalke)

Pull request description:

  The `boost::this_thread::interruption_point()` in the code base currently block the replacement of `boost::thread` with `std::thread`. [1]

  Remove them from the wallet because they are either unused or useless.

  The feature to interrupt a periodic flush is useless because all wallets have just been flushed https://github.com/bitcoin/bitcoin/blob/9ccaee1d5e2e4b79b0a7c29aadb41b97e4741332/src/init.cpp#L194 and another flush should be a noop. Also, they will be flushed again shortly after https://github.com/bitcoin/bitcoin/blob/9ccaee1d5e2e4b79b0a7c29aadb41b97e4741332/src/init.cpp#L285, so even if repeated flushes weren't a noop, doing 3 instead of 2 shouldn't matter too much at this point. Also, the wallet is flushed every two seconds in the worst case, so if this is an expensive operation, that period should be readjusted. (Or bdb should be removed altogether bitcoin#18916)

  [1] Replacement of `boost::thread` with `std::thread` should happen because:

  * The boost thread dependency is slow to compile
  * Boost thread is less maintained than the standard lib
  * Boost thread is mostly redundant to the standard lib
  * Global interruption points via exceptions are hard to keep track of during review and easy to get wrong during runtime (e.g. accidental `catch (...)`)

ACKs for top commit:
  fanquake:
    ACK fa1c74f

Tree-SHA512: b166619256de2ef4325480fa1367f68bc9371ad785ec503aed61eab41ba61f1a9807aab25451a24efda3db64855c9ba0025645b98bc58557bc3ec56c5b3297d0
ComputerCraftr pushed a commit to ComputerCraftr/bitcoin that referenced this pull request Jun 16, 2020
fa1c74f wallet: Remove unused boost::thread_interrupted (MarcoFalke)
fa7b885 walletdb: Remove unsed boost/thread (MarcoFalke)
5555d97 wallet: Make PeriodicFlush uninterruptible (MarcoFalke)

Pull request description:

  The `boost::this_thread::interruption_point()` in the code base currently block the replacement of `boost::thread` with `std::thread`. [1]

  Remove them from the wallet because they are either unused or useless.

  The feature to interrupt a periodic flush is useless because all wallets have just been flushed https://github.com/bitcoin/bitcoin/blob/9ccaee1d5e2e4b79b0a7c29aadb41b97e4741332/src/init.cpp#L194 and another flush should be a noop. Also, they will be flushed again shortly after https://github.com/bitcoin/bitcoin/blob/9ccaee1d5e2e4b79b0a7c29aadb41b97e4741332/src/init.cpp#L285, so even if repeated flushes weren't a noop, doing 3 instead of 2 shouldn't matter too much at this point. Also, the wallet is flushed every two seconds in the worst case, so if this is an expensive operation, that period should be readjusted. (Or bdb should be removed altogether bitcoin#18916)

  [1] Replacement of `boost::thread` with `std::thread` should happen because:

  * The boost thread dependency is slow to compile
  * Boost thread is less maintained than the standard lib
  * Boost thread is mostly redundant to the standard lib
  * Global interruption points via exceptions are hard to keep track of during review and easy to get wrong during runtime (e.g. accidental `catch (...)`)

ACKs for top commit:
  fanquake:
    ACK fa1c74f

Tree-SHA512: b166619256de2ef4325480fa1367f68bc9371ad785ec503aed61eab41ba61f1a9807aab25451a24efda3db64855c9ba0025645b98bc58557bc3ec56c5b3297d0
deadalnix pushed a commit to Bitcoin-ABC/bitcoin-abc that referenced this pull request Dec 7, 2020
Summary:
```
The boost::this_thread::interruption_point() in the code base currently
block the replacement of boost::thread with std::thread. [1]

Remove them from the wallet because they are either unused or useless.
```

Backport of core [[bitcoin/bitcoin#18792 | PR18792]].

Depends on D8615.

Test Plan:
  ninja all check-all

Reviewers: #bitcoin_abc, majcosta

Reviewed By: #bitcoin_abc, majcosta

Differential Revision: https://reviews.bitcoinabc.org/D8616
kwvg added a commit to kwvg/dash that referenced this pull request Jul 13, 2021
kwvg added a commit to kwvg/dash that referenced this pull request Jul 13, 2021
kwvg added a commit to kwvg/dash that referenced this pull request Jul 13, 2021
kwvg added a commit to kwvg/dash that referenced this pull request Jul 13, 2021
kwvg added a commit to kwvg/dash that referenced this pull request Jul 15, 2021
kwvg added a commit to kwvg/dash that referenced this pull request Jul 15, 2021
Co-authored-by: UdjinM6 <UdjinM6@users.noreply.github.com>
kwvg added a commit to kwvg/dash that referenced this pull request Jul 15, 2021
Co-authored-by: UdjinM6 <UdjinM6@users.noreply.github.com>
kwvg added a commit to kwvg/dash that referenced this pull request Jul 15, 2021
Co-authored-by: UdjinM6 <UdjinM6@users.noreply.github.com>
kwvg added a commit to kwvg/dash that referenced this pull request Jul 15, 2021
Co-authored-by: UdjinM6 <UdjinM6@users.noreply.github.com>
kwvg added a commit to kwvg/dash that referenced this pull request Jul 16, 2021
Co-authored-by: UdjinM6 <UdjinM6@users.noreply.github.com>
UdjinM6 added a commit to dashpay/dash that referenced this pull request Jul 16, 2021
@bitcoin bitcoin locked as resolved and limited conversation to collaborators Feb 15, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants