asyncio: stop using get_event_loop(). introduce ~singleton loop.
asyncio.get_event_loop() became deprecated in python3.10. (see https://github.com/python/cpython/issues/83710) ``` .../electrum/electrum/daemon.py:470: DeprecationWarning: There is no current event loop self.asyncio_loop = asyncio.get_event_loop() .../electrum/electrum/network.py:276: DeprecationWarning: There is no current event loop self.asyncio_loop = asyncio.get_event_loop() ``` Also, according to that thread, "set_event_loop() [... is] not deprecated by oversight". So, we stop using get_event_loop() and set_event_loop() in our own code. Note that libraries we use (such as the stdlib for python <3.10), might call get_event_loop, which then relies on us having called set_event_loop e.g. for the GUI thread. To work around this, a custom event loop policy providing a get_event_loop implementation is used. Previously, we have been using a single asyncio event loop, created with util.create_and_start_event_loop, and code in many places got a reference to this loop using asyncio.get_event_loop(). Now, we still use a single asyncio event loop, but it is now stored as a global in util._asyncio_event_loop (access with util.get_asyncio_loop()). I believe these changes also fix https://github.com/spesmilo/electrum/issues/5376
This commit is contained in:
@@ -9,6 +9,7 @@ import copy
|
||||
from electrum import storage, bitcoin, keystore, bip32, slip39, wallet
|
||||
from electrum import Transaction
|
||||
from electrum import SimpleConfig
|
||||
from electrum import util
|
||||
from electrum.address_synchronizer import TX_HEIGHT_UNCONFIRMED, TX_HEIGHT_UNCONF_PARENT
|
||||
from electrum.wallet import (sweep, Multisig_Wallet, Standard_Wallet, Imported_Wallet,
|
||||
restore_wallet_from_text, Abstract_Wallet, BumpFeeStrategy)
|
||||
@@ -18,6 +19,7 @@ from electrum.util import (
|
||||
from electrum.transaction import (TxOutput, Transaction, PartialTransaction, PartialTxOutput,
|
||||
PartialTxInput, tx_from_any, TxOutpoint)
|
||||
from electrum.mnemonic import seed_type
|
||||
from electrum.network import Network
|
||||
|
||||
from electrum.plugins.trustedcoin import trustedcoin
|
||||
|
||||
@@ -699,8 +701,14 @@ class TestWalletSending(TestCaseForTestnet):
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.asyncio_loop, self._stop_loop, self._loop_thread = util.create_and_start_event_loop()
|
||||
self.config = SimpleConfig({'electrum_path': self.electrum_path})
|
||||
|
||||
def tearDown(self):
|
||||
self.asyncio_loop.call_soon_threadsafe(self._stop_loop.set_result, 1)
|
||||
self._loop_thread.join(timeout=1)
|
||||
super().tearDown()
|
||||
|
||||
def create_standard_wallet_from_seed(self, seed_words, *, config=None, gap_limit=2):
|
||||
if config is None:
|
||||
config = self.config
|
||||
@@ -1369,14 +1377,7 @@ class TestWalletSending(TestCaseForTestnet):
|
||||
raise Exception("unexpected txid")
|
||||
def has_internet_connection(self):
|
||||
return True
|
||||
def run_from_another_thread(self, coro, *, timeout=None):
|
||||
loop, stop_loop, loop_thread = create_and_start_event_loop()
|
||||
fut = asyncio.run_coroutine_threadsafe(coro, loop)
|
||||
try:
|
||||
return fut.result(timeout)
|
||||
finally:
|
||||
loop.call_soon_threadsafe(stop_loop.set_result, 1)
|
||||
loop_thread.join(timeout=1)
|
||||
run_from_another_thread = Network.run_from_another_thread
|
||||
def get_local_height(self):
|
||||
return 0
|
||||
def blockchain(self):
|
||||
@@ -1429,14 +1430,7 @@ class TestWalletSending(TestCaseForTestnet):
|
||||
raise Exception("unexpected txid")
|
||||
def has_internet_connection(self):
|
||||
return True
|
||||
def run_from_another_thread(self, coro, *, timeout=None):
|
||||
loop, stop_loop, loop_thread = create_and_start_event_loop()
|
||||
fut = asyncio.run_coroutine_threadsafe(coro, loop)
|
||||
try:
|
||||
return fut.result(timeout)
|
||||
finally:
|
||||
loop.call_soon_threadsafe(stop_loop.set_result, 1)
|
||||
loop_thread.join(timeout=1)
|
||||
run_from_another_thread = Network.run_from_another_thread
|
||||
def get_local_height(self):
|
||||
return 0
|
||||
def blockchain(self):
|
||||
@@ -1844,8 +1838,8 @@ class TestWalletSending(TestCaseForTestnet):
|
||||
network = NetworkMock()
|
||||
dest_addr = 'tb1q3ws2p0qjk5vrravv065xqlnkckvzcpclk79eu2'
|
||||
sweep_coro = sweep(privkeys, network=network, config=self.config, to_address=dest_addr, fee=5000, locktime=1325785, tx_version=1)
|
||||
loop = asyncio.get_event_loop()
|
||||
tx = loop.run_until_complete(sweep_coro)
|
||||
loop = util.get_asyncio_loop()
|
||||
tx = asyncio.run_coroutine_threadsafe(sweep_coro, loop).result()
|
||||
|
||||
tx_copy = tx_from_any(tx.serialize())
|
||||
self.assertEqual('010000000129349e5641d79915e9d0282fdbaee8c3df0b6731bab9d70bf626e8588bde24ac010000004847304402206bf0d0a93abae0d5873a62ebf277a5dd2f33837821e8b93e74d04e19d71b578002201a6d729bc159941ef5c4c9e5fe13ece9fc544351ba531b00f68ba549c8b38a9a01fdffffff01b82e0f00000000001600148ba0a0bc12b51831f58c7ea8607e76c5982c071fd93a1400',
|
||||
@@ -2199,14 +2193,7 @@ class TestWalletSending(TestCaseForTestnet):
|
||||
raise Exception("unexpected txid")
|
||||
def has_internet_connection(self):
|
||||
return True
|
||||
def run_from_another_thread(self, coro, *, timeout=None):
|
||||
loop, stop_loop, loop_thread = create_and_start_event_loop()
|
||||
fut = asyncio.run_coroutine_threadsafe(coro, loop)
|
||||
try:
|
||||
return fut.result(timeout)
|
||||
finally:
|
||||
loop.call_soon_threadsafe(stop_loop.set_result, 1)
|
||||
loop_thread.join(timeout=1)
|
||||
run_from_another_thread = Network.run_from_another_thread
|
||||
def get_local_height(self):
|
||||
return 0
|
||||
def blockchain(self):
|
||||
@@ -3284,8 +3271,14 @@ class TestWalletHistory_DoubleSpend(TestCaseForTestnet):
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.asyncio_loop, self._stop_loop, self._loop_thread = util.create_and_start_event_loop()
|
||||
self.config = SimpleConfig({'electrum_path': self.electrum_path})
|
||||
|
||||
def tearDown(self):
|
||||
self.asyncio_loop.call_soon_threadsafe(self._stop_loop.set_result, 1)
|
||||
self._loop_thread.join(timeout=1)
|
||||
super().tearDown()
|
||||
|
||||
@mock.patch.object(wallet.Abstract_Wallet, 'save_db')
|
||||
def test_restoring_wallet_without_manual_delete(self, mock_save_db):
|
||||
w = restore_wallet_from_text("small rapid pattern language comic denial donate extend tide fever burden barrel",
|
||||
|
||||
Reference in New Issue
Block a user