1
0

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:
SomberNight
2020-01-09 17:50:05 +01:00
parent 7968531065
commit 37747d7469
3 changed files with 58 additions and 23 deletions

View File

@@ -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')