gui: Refactor OpenWalletActivity #16261

pull promag wants to merge 1 commits into bitcoin:master from promag:2019-06-refactor-open-wallet changing 3 files +101 −59
  1. promag commented at 3:01 pm on June 21, 2019: member

    This PR consists in 3 refactors:

    1. Split from OpenWalletActivity a base class WalletControllerActivity to simplify new activities, like the upcoming CreateWalletActivity;
    2. Move from BitcoinGUI the details of the wallet opening;
    3. Change threading model - WalletControllerActivity instances belong to the GUI thread and some code (the blocking code) is now executed in the worker thread asynchronously, which allows for a responsive GUI.
  2. DrahtBot commented at 3:05 pm on June 21, 2019: member

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

    Conflicts

    No conflicts as of last run.

  3. in src/qt/walletcontroller.cpp:205 in a962b68ebf outdated
    211+{
    212+    QString name = path.empty() ? QString("["+tr("default wallet")+"]") : QString::fromStdString(path);
    213+
    214+    showProgressDialog(tr("Opening Wallet <b>%1</b>...").arg(name.toHtmlEscaped()));
    215+
    216+    QTimer::singleShot(500, worker(), [this, path] {
    


    promag commented at 3:07 pm on June 21, 2019:

    We can ditch these 500ms but I think it is ok.

    If we decide to have 0ms then we can only replace QTimer::singleShot(0, with QMetaObject::invokeMethod after bumping Qt to 5.10 - see https://doc.qt.io/qt-5/qmetaobject.html#invokeMethod-5.


    hebasto commented at 9:23 am on July 7, 2019:
    What is the point to pause? If there is no clear and obvious rationale, QTimer::singleShot() should be avoided, IMO.

    promag commented at 2:39 pm on July 13, 2019:
    No point, but not harm, can make it 0. The point is to call the lambda in the worker() thread.

    hebasto commented at 7:58 pm on July 13, 2019:

    The point is to call the lambda in the worker() thread.

    Did you consider some other approaches?


    promag commented at 8:10 pm on July 13, 2019:
    Yes, those require more QObject subclass, signals and slots. IMO this approach is more clear.

    hebasto commented at 8:22 pm on July 13, 2019:
    May I suggest to remove (make 0 ms) or comment 500 ms timeout?

    promag commented at 9:38 pm on July 13, 2019:
    Sure, I can make 0ms and leave a comment.

    jonasschnelli commented at 3:46 pm on July 16, 2019:
    Is there a benefit of using 500ms? Seems racy…

    promag commented at 1:18 pm on August 29, 2019:
    Not really, I’ll make 0 then.
  4. DrahtBot added the label GUI on Jun 21, 2019
  5. fanquake added this to the "Blockers" column in a project

  6. fanquake requested review from hebasto on Jul 5, 2019
  7. fanquake requested review from jonasschnelli on Jul 5, 2019
  8. fanquake commented at 6:56 am on July 5, 2019: member
    @promag Can you rebase this on master; as it contains some bug fixes that would be nice to have when testing this PR, such as #16231.
  9. fanquake added the label Waiting for author on Jul 5, 2019
  10. promag force-pushed on Jul 5, 2019
  11. promag commented at 7:33 am on July 5, 2019: member
    @fanquake done.
  12. fanquake removed the label Waiting for author on Jul 5, 2019
  13. hebasto commented at 3:02 pm on July 5, 2019: member
    Concept ACK.
  14. fanquake commented at 2:24 am on July 6, 2019: member
    I had a quick test, and this PR on top of master (4f378ac30cf66178564620b4a8ca9cad7f031cc3) doesn’t fix #15453.
  15. in src/qt/walletcontroller.cpp:210 in 5604d30a30 outdated
    216+    QTimer::singleShot(500, worker(), [this, path] {
    217+        std::unique_ptr<interfaces::Wallet> wallet = node().loadWallet(path, m_error_message, m_warning_message);
    218+
    219+        if (wallet) m_wallet_model = m_wallet_controller->getOrCreateWallet(std::move(wallet));
    220+
    221+        QTimer::singleShot(500, this, &OpenWalletActivity::finish);
    


    hebasto commented at 9:23 am on July 7, 2019:
    Same here.

    hebasto commented at 8:08 pm on July 13, 2019:
    OpenWalletActivity::finish() could be inlined here. OpenWalletActivity::open() will remain small enough and readability will be improved, no?

    promag commented at 9:43 pm on July 13, 2019:

    OpenWalletActivity::finish() could be inlined here.

    At the time I had 2 reasons to not do that:

    1. finish could be called from multiple places, also initially it was a virtual method in the super class;
    2. wanted to avoid nesting lambdas.

    hebasto commented at 5:08 am on July 14, 2019:

    Could it be just

    0        finish();
    

    ?


    promag commented at 9:11 am on July 14, 2019:
    No, this finish() is not thread safe - it would be called from the worker thread.

    hebasto commented at 9:39 am on July 14, 2019:

    … this finish() is not thread safe - it would be called from the worker thread.

    Right. But thread safety is not required for finish(), IMO.


    promag commented at 1:36 pm on August 29, 2019:
    But it is, see OpenWalletActivity::finish(), it must be called on the GUI thread.

    hebasto commented at 10:24 am on September 2, 2019:
    Correct.
  16. in src/qt/walletcontroller.cpp:192 in 5604d30a30 outdated
    212+    QString name = path.empty() ? QString("["+tr("default wallet")+"]") : QString::fromStdString(path);
    213+
    214+    showProgressDialog(tr("Opening Wallet <b>%1</b>...").arg(name.toHtmlEscaped()));
    215+
    216+    QTimer::singleShot(500, worker(), [this, path] {
    217+        std::unique_ptr<interfaces::Wallet> wallet = node().loadWallet(path, m_error_message, m_warning_message);
    


    hebasto commented at 10:13 am on July 7, 2019:
    0auto wallet = node().loadWallet(path, m_error_message, m_warning_message);
    

    promag commented at 2:37 pm on July 13, 2019:
    I prefer to have to have the type.
  17. in src/qt/walletcontroller.cpp:46 in 5604d30a30 outdated
    44 {
    45-    m_activity_thread.quit();
    46-    m_activity_thread.wait();
    47+    m_activity_thread->quit();
    48+    m_activity_thread->wait();
    49+    delete m_activity_worker;
    


    hebasto commented at 1:08 pm on July 7, 2019:
    Could naked delete be avoided in the new code? There are some techniques to achieve this. E.g., m_activity_worker could have a parent QObject, like m_activity_thread has.

    promag commented at 9:34 pm on July 13, 2019:
    No object could be m_activity_worker parent because it’s the only object on its thread. Could connect WalletController::destroyed to its deleteLater or could use some smart pointer but honestly I think this is better.

    hebasto commented at 5:25 am on July 14, 2019:
    You could use QThread::finished signal. See: https://github.com/bitcoin/bitcoin/pull/16261/files#r303227866
  18. in src/qt/walletcontroller.cpp:151 in 5604d30a30 outdated
    157-    : m_wallet_controller(wallet_controller)
    158-    , m_name(name)
    159-{}
    160+WalletControllerActivity::~WalletControllerActivity()
    161+{
    162+    delete m_progress_dialog;
    


    hebasto commented at 1:09 pm on July 7, 2019:
    Could naked delete be avoided in the new code?

    promag commented at 9:38 pm on July 13, 2019:
    Ownership is given to m_parent_widget so that it shows up properly. If the activity finishes first then we delete it - note lines L174-L176 below.

    hebasto commented at 5:57 am on July 14, 2019:
  19. DrahtBot added the label Needs rebase on Jul 8, 2019
  20. promag force-pushed on Jul 8, 2019
  21. DrahtBot removed the label Needs rebase on Jul 9, 2019
  22. in src/qt/walletcontroller.cpp:36 in b71017a295 outdated
    32@@ -29,15 +33,17 @@ WalletController::WalletController(interfaces::Node& node, const PlatformStyle*
    33         getOrCreateWallet(std::move(wallet));
    34     }
    35 
    36-    m_activity_thread.start();
    37+    m_activity_worker->moveToThread(m_activity_thread);
    


    hebasto commented at 5:20 am on July 14, 2019:

    Could add

    0    connect(m_activity_thread, &QThread::finished, m_activity_worker, &QObject::deleteLater);
    

    and remove following

    0   delete m_activity_worker;
    

    ?


    promag commented at 4:57 pm on July 16, 2019:
    Why? The thread is explicitly stopped (actually the event loop is stopped and the thread finishes) in ~WalletController() so what better place to also delete the worker? I think explicit teardown is preferable.

    hebasto commented at 7:11 am on July 18, 2019:

    Why?

    Your approach binds the life of m_activity_worker to the WalletController instance lifetime. IMO, as m_activity_worker lives in m_activity_thread, connecting to the QThread::finished signal seems more appropriate.

  23. hebasto changes_requested
  24. in src/qt/walletcontroller.cpp:157 in b71017a295 outdated
    176-    if (wallet) {
    177-        Q_EMIT opened(m_wallet_controller->getOrCreateWallet(std::move(wallet)));
    178-    } else {
    179-        Q_EMIT message(QMessageBox::Critical, QString::fromStdString(error));
    180+    m_progress_dialog = new QProgressDialog(m_parent_widget);
    181+
    


    hebasto commented at 5:53 am on July 14, 2019:

    Could add

    0    connect(this, &OpenWalletActivity::finished, m_progress_dialog, &QObject::deleteLater);
    

    and remove above:

    0   delete m_progress_dialog;
    

    ?

  25. in src/qt/walletcontroller.cpp:175 in b71017a295 outdated
    184+    m_progress_dialog->setCancelButton(nullptr);
    185+    m_progress_dialog->setWindowModality(Qt::ApplicationModal);
    186+    GUIUtil::PolishProgressDialog(m_progress_dialog);
    187+
    188+    connect(m_progress_dialog, &QObject::destroyed, [this] {
    189+        m_progress_dialog = nullptr;
    


    hebasto commented at 5:55 am on July 14, 2019:
    Which cases require this line?

    promag commented at 5:26 pm on July 16, 2019:
    Actually I think it’s not required now. Initially I had setAttribute(Qt::WA_DeleteOnClose). Removed.
  26. hebasto changes_requested
  27. jonasschnelli commented at 9:17 am on July 17, 2019: contributor
    Looks like the wallet encryption test fails…
  28. promag commented at 10:20 am on July 17, 2019: member
    @jonasschnelli it was failing because of build timeouts.
  29. promag force-pushed on Aug 29, 2019
  30. hebasto approved
  31. hebasto commented at 10:46 am on September 2, 2019: member
    ACK 7afbd0cb69dae4af4b6a78c442c25832cd7fad42, I have tested the code: no change in behavior is observed (compared to the master 6519be605480fec95dcd814771038efcb1ad2abe).
  32. promag force-pushed on Sep 5, 2019
  33. gui: Refactor OpenWalletActivity bc6d8a3662
  34. promag force-pushed on Sep 5, 2019
  35. promag commented at 0:43 am on September 6, 2019: member
    @hebasto rebased and removed the unused declaration std::vector<std::string> getWalletsAvailableToOpen() const; - left over from other work.
  36. fanquake merged this on Sep 7, 2019
  37. fanquake closed this on Sep 7, 2019

  38. fanquake removed this from the "Blockers" column in a project

  39. promag deleted the branch on Sep 7, 2019
  40. DrahtBot locked this on Dec 16, 2021

github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2024-12-18 18:12 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me