diff --git a/src/communicator/__init__.py b/src/communicator/__init__.py index 0ab796f5..e6404efc 100755 --- a/src/communicator/__init__.py +++ b/src/communicator/__init__.py @@ -61,6 +61,7 @@ class OnionrCommunicatorDaemon: # populate kv values self.shared_state.get_by_string('DeadSimpleKV').put('blockQueue', {}) + self.shared_state.get_by_string('DeadSimpleKV').put('shutdown', False) if config.get('general.offline_mode', False): self.isOnline = False @@ -97,9 +98,6 @@ class OnionrCommunicatorDaemon: # amount of threads running by name, used to prevent too many self.threadCounts = {} - # set true when shutdown command received - self.shutdown = False - # list of blocks currently downloading self.currentDownloading = [] @@ -239,23 +237,28 @@ class OnionrCommunicatorDaemon: get_url() while not config.get('onboarding.done', True) and \ - not self.shutdown: + not self.shared_state.get_by_string( + 'DeadSimpleKV').get('shutdown'): try: time.sleep(2) except KeyboardInterrupt: - self.shutdown = True + self.shared_state.get_by_string( + 'DeadSimpleKV').put('shutdown', True) # Main daemon loop, mainly for calling timers, # don't do any complex operations here to avoid locking try: - while not self.shutdown: + while not self.shared_state.get_by_string( + 'DeadSimpleKV').get('shutdown'): for i in self.timers: - if self.shutdown: + if self.shared_state.get_by_string( + 'DeadSimpleKV').get('shutdown'): break i.processTimer() time.sleep(self.delay) except KeyboardInterrupt: - self.shutdown = True + self.shared_state.get_by_string( + 'DeadSimpleKV').put('shutdown', True) logger.info( 'Goodbye. (Onionr is cleaning up, and will exit)', terminal=True) diff --git a/src/communicator/onlinepeers/onlinepeers.py b/src/communicator/onlinepeers/onlinepeers.py index d422c871..894ec6da 100644 --- a/src/communicator/onlinepeers/onlinepeers.py +++ b/src/communicator/onlinepeers/onlinepeers.py @@ -31,6 +31,7 @@ def get_online_peers(comm_inst: 'OnionrCommunicatorDaemon'): Connect to more peers if we have none connected """ config = comm_inst.config + kv: "DeadSimpleKV" = comm_inst.shared_state.get_by_string("DeadSimpleKV") if config.get('general.offline_mode', False): comm_inst.decrementThreadCount('get_online_peers') return @@ -49,7 +50,7 @@ def get_online_peers(comm_inst: 'OnionrCommunicatorDaemon'): else: comm_inst.connectNewPeer() - if comm_inst.shutdown: + if kv.get('shutdown'): break else: if len(comm_inst.onlinePeers) == 0: diff --git a/src/communicator/peeraction.py b/src/communicator/peeraction.py index aeda75c1..f26b6a92 100644 --- a/src/communicator/peeraction.py +++ b/src/communicator/peeraction.py @@ -27,6 +27,7 @@ def peer_action(comm_inst, peer, action, returnHeaders=False, max_resp_size=5242880): """Perform a get request to a peer.""" penalty_score = -10 + kv: "DeadSimpleKV" = comm_inst.shared_state.get_by_string("DeadSimpleKV") if len(peer) == 0: return False url = 'http://%s/%s' % (peer, action) @@ -47,7 +48,7 @@ def peer_action(comm_inst, peer, action, onlinepeers.remove_online_peer(comm_inst, peer) keydb.transportinfo.set_address_info( peer, 'lastConnectAttempt', epoch.get_epoch()) - if action != 'ping' and not comm_inst.shutdown: + if action != 'ping' and not kv.get('shutdown'): logger.warn(f'Lost connection to {peer}', terminal=True) # Will only add a new peer to pool if needed onlinepeers.get_online_peers(comm_inst) diff --git a/src/communicatorutils/connectnewpeers.py b/src/communicatorutils/connectnewpeers.py index 3fae9462..cc6755de 100755 --- a/src/communicatorutils/connectnewpeers.py +++ b/src/communicatorutils/connectnewpeers.py @@ -33,6 +33,7 @@ def connect_new_peer_to_communicator(comm_inst, peer='', useBootstrap=False): config = comm_inst.config retData = False tried = comm_inst.offlinePeers + kv: "DeadSimpleKV" = comm_inst.shared_state.get_by_string("DeadSimpleKV") transports = gettransports.get() if peer != '': if stringvalidators.validate_transport(peer): @@ -77,7 +78,7 @@ def connect_new_peer_to_communicator(comm_inst, peer='', useBootstrap=False): or address in comm_inst.onlinePeers \ or address in comm_inst.cooldownPeer: continue - if comm_inst.shutdown: + if kv.get('shutdown'): return # Ping a peer, ret = peeraction.peer_action(comm_inst, address, 'ping') diff --git a/src/communicatorutils/downloadblocks/__init__.py b/src/communicatorutils/downloadblocks/__init__.py index ea9cb6b6..35474834 100755 --- a/src/communicatorutils/downloadblocks/__init__.py +++ b/src/communicatorutils/downloadblocks/__init__.py @@ -63,7 +63,7 @@ def download_blocks_from_communicator(comm_inst: "OnionrCommunicatorDaemon"): if not shoulddownload.should_download(comm_inst, blockHash): continue - if comm_inst.shutdown or not comm_inst.isOnline or \ + if kv.get('shutdown') or not comm_inst.isOnline or \ storage_counter.is_full(): # Exit loop if shutting down or offline, or disk allocation reached break @@ -84,7 +84,7 @@ def download_blocks_from_communicator(comm_inst: "OnionrCommunicatorDaemon"): blockPeers = onionrcrypto.cryptoutils.random_shuffle(blockPeers) peerUsed = blockPeers.pop(0) - if not comm_inst.shutdown and peerUsed.strip() != '': + if not kv.get('shutdown') and peerUsed.strip() != '': logger.info( f"Attempting to download %s from {peerUsed}..." % (blockHash[:12],)) content = peeraction.peer_action( diff --git a/src/communicatorutils/netcheck.py b/src/communicatorutils/netcheck.py index e3ad4870..63aad540 100755 --- a/src/communicatorutils/netcheck.py +++ b/src/communicatorutils/netcheck.py @@ -32,6 +32,7 @@ def net_check(comm_inst): """ # for detecting if we have received incoming connections recently rec = False + kv: "DeadSimpleKV" = comm_inst.shared_state.get_by_string("DeadSimpleKV") if len(comm_inst.onlinePeers) == 0: try: if (epoch.get_epoch() - int(localcommand.local_command @@ -41,7 +42,7 @@ def net_check(comm_inst): except ValueError: pass if not rec and not netutils.checkNetwork(torPort=comm_inst.proxyPort): - if not comm_inst.shutdown: + if not kv.get('shutdown'): if not comm_inst.config.get('general.offline_mode', False): logger.warn('Network check failed, are you connected to ' + 'the Internet, and is Tor working? ' + diff --git a/src/communicatorutils/onionrcommunicatortimers.py b/src/communicatorutils/onionrcommunicatortimers.py index c0d8b1ca..2fbca2eb 100755 --- a/src/communicatorutils/onionrcommunicatortimers.py +++ b/src/communicatorutils/onionrcommunicatortimers.py @@ -13,6 +13,7 @@ import logger from typing import TYPE_CHECKING from typing import Callable, NewType, Iterable if TYPE_CHECKING: + from deadsimplekv import DeadSimpleKV from communicator import OnionrCommunicatorDaemon """ This program is free software: you can redistribute it and/or modify @@ -47,6 +48,8 @@ class OnionrCommunicatorTimers: self.daemon_inst = daemon_inst self.max_threads = max_threads self.args = my_args + self.kv: "DeadSimpleKV" = daemon_inst.shared_state.get_by_string( + "DeadSimpleKV") self.daemon_inst.timers.append(self) self.count = 0 @@ -60,7 +63,7 @@ class OnionrCommunicatorTimers: self.daemon_inst.threadCounts[self.timer_function.__name__] = 0 # execute timer's func, if we are not missing *required* online peer - if self.count == self.frequency and not self.daemon_inst.shutdown: + if self.count == self.frequency and not self.kv.get('shutdown'): try: if self.requires_peer and \ len(self.daemon_inst.onlinePeers) == 0: diff --git a/src/httpapi/apiutils/shutdown.py b/src/httpapi/apiutils/shutdown.py index 4a6db909..63bdb440 100644 --- a/src/httpapi/apiutils/shutdown.py +++ b/src/httpapi/apiutils/shutdown.py @@ -1,13 +1,9 @@ -""" - Onionr - Private P2P Communication +"""Onionr - Private P2P Communication. - Shutdown the node either hard or cleanly +Shutdown the node either hard or cleanly """ from flask import Blueprint, Response from flask import g -from onionrblocks import onionrblockapi -import onionrexceptions -from onionrutils import stringvalidators """ This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -25,6 +21,7 @@ from onionrutils import stringvalidators shutdown_bp = Blueprint('shutdown', __name__) + def shutdown(client_api_inst): try: client_api_inst.publicAPI.httpServer.stop() @@ -33,8 +30,9 @@ def shutdown(client_api_inst): pass return Response("bye") + @shutdown_bp.route('/shutdownclean') def shutdown_clean(): # good for calling from other clients - g.too_many.get_by_string("OnionrCommunicatorDaemon").shutdown = True + g.too_many.get_by_string("DeadSimpleKV").put('shutdown', True) return Response("bye")