split network main_taskgroup: create daemon.taskgroup
network.main_taskgroup restarts every time the proxy settings are changed, many long-running tasks (some introduced with lightning) are not prepared for and do not want this.
This commit is contained in:
@@ -29,7 +29,7 @@ import time
|
||||
import traceback
|
||||
import sys
|
||||
import threading
|
||||
from typing import Dict, Optional, Tuple
|
||||
from typing import Dict, Optional, Tuple, Iterable
|
||||
from base64 import b64decode
|
||||
from collections import defaultdict
|
||||
|
||||
@@ -39,6 +39,7 @@ import jsonrpcclient
|
||||
import jsonrpcserver
|
||||
from jsonrpcserver import response
|
||||
from jsonrpcclient.clients.aiohttp_client import AiohttpClient
|
||||
from aiorpcx import TaskGroup
|
||||
|
||||
from .network import Network
|
||||
from .util import (json_decode, to_bytes, to_string, profiler, standardize_path, constant_time_compare)
|
||||
@@ -280,28 +281,44 @@ class Daemon(Logger):
|
||||
if fd is None:
|
||||
raise Exception('failed to lock daemon; already running?')
|
||||
self.asyncio_loop = asyncio.get_event_loop()
|
||||
if config.get('offline'):
|
||||
self.network = None
|
||||
else:
|
||||
self.network = Network(config)
|
||||
self.network = None
|
||||
if not config.get('offline'):
|
||||
self.network = Network(config, daemon=self)
|
||||
self.fx = FxThread(config, self.network)
|
||||
self.gui_object = None
|
||||
# path -> wallet; make sure path is standardized.
|
||||
self._wallets = {} # type: Dict[str, Abstract_Wallet]
|
||||
jobs = [self.fx.run]
|
||||
daemon_jobs = []
|
||||
# Setup JSONRPC server
|
||||
if listen_jsonrpc:
|
||||
jobs.append(self.start_jsonrpc(config, fd))
|
||||
daemon_jobs.append(self.start_jsonrpc(config, fd))
|
||||
# request server
|
||||
if self.config.get('run_payserver'):
|
||||
self.pay_server = None
|
||||
if not config.get('offline') and self.config.get('run_payserver'):
|
||||
self.pay_server = PayServer(self)
|
||||
jobs.append(self.pay_server.run())
|
||||
daemon_jobs.append(self.pay_server.run())
|
||||
# server-side watchtower
|
||||
if self.config.get('run_watchtower'):
|
||||
self.watchtower = None
|
||||
if not config.get('offline') and self.config.get('run_watchtower'):
|
||||
self.watchtower = WatchTowerServer(self.network)
|
||||
jobs.append(self.watchtower.run)
|
||||
daemon_jobs.append(self.watchtower.run)
|
||||
if self.network:
|
||||
self.network.start(jobs)
|
||||
self.network.start(jobs=[self.fx.run])
|
||||
|
||||
self.taskgroup = TaskGroup()
|
||||
asyncio.run_coroutine_threadsafe(self._run(jobs=daemon_jobs), self.asyncio_loop)
|
||||
|
||||
@log_exceptions
|
||||
async def _run(self, jobs: Iterable = None):
|
||||
if jobs is None:
|
||||
jobs = []
|
||||
try:
|
||||
async with self.taskgroup as group:
|
||||
[await group.spawn(job) for job in jobs]
|
||||
except BaseException as e:
|
||||
self.logger.exception('daemon.taskgroup died.')
|
||||
finally:
|
||||
self.logger.info("stopping daemon.taskgroup")
|
||||
|
||||
async def authenticate(self, headers):
|
||||
if self.rpc_password == '':
|
||||
@@ -462,7 +479,7 @@ class Daemon(Logger):
|
||||
|
||||
def is_running(self):
|
||||
with self.running_lock:
|
||||
return self.running
|
||||
return self.running and not self.taskgroup.closed()
|
||||
|
||||
def stop(self):
|
||||
with self.running_lock:
|
||||
@@ -477,8 +494,15 @@ class Daemon(Logger):
|
||||
if self.network:
|
||||
self.logger.info("shutting down network")
|
||||
self.network.stop()
|
||||
self.logger.info("stopping, removing lockfile")
|
||||
self.logger.info("stopping taskgroup")
|
||||
fut = asyncio.run_coroutine_threadsafe(self.taskgroup.cancel_remaining(), self.asyncio_loop)
|
||||
try:
|
||||
fut.result(timeout=2)
|
||||
except (asyncio.TimeoutError, asyncio.CancelledError):
|
||||
pass
|
||||
self.logger.info("removing lockfile")
|
||||
remove_lockfile(get_lockfile(self.config))
|
||||
self.logger.info("stopped")
|
||||
|
||||
def run_gui(self, config, plugins):
|
||||
threading.current_thread().setName('GUI')
|
||||
|
||||
Reference in New Issue
Block a user