Moved communicator shutdown over to KV model for more decoupling
parent
0460d3380f
commit
0e4e7bb050
|
@ -61,6 +61,7 @@ class OnionrCommunicatorDaemon:
|
||||||
|
|
||||||
# populate kv values
|
# populate kv values
|
||||||
self.shared_state.get_by_string('DeadSimpleKV').put('blockQueue', {})
|
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):
|
if config.get('general.offline_mode', False):
|
||||||
self.isOnline = False
|
self.isOnline = False
|
||||||
|
@ -97,9 +98,6 @@ class OnionrCommunicatorDaemon:
|
||||||
# amount of threads running by name, used to prevent too many
|
# amount of threads running by name, used to prevent too many
|
||||||
self.threadCounts = {}
|
self.threadCounts = {}
|
||||||
|
|
||||||
# set true when shutdown command received
|
|
||||||
self.shutdown = False
|
|
||||||
|
|
||||||
# list of blocks currently downloading
|
# list of blocks currently downloading
|
||||||
self.currentDownloading = []
|
self.currentDownloading = []
|
||||||
|
|
||||||
|
@ -239,23 +237,28 @@ class OnionrCommunicatorDaemon:
|
||||||
get_url()
|
get_url()
|
||||||
|
|
||||||
while not config.get('onboarding.done', True) and \
|
while not config.get('onboarding.done', True) and \
|
||||||
not self.shutdown:
|
not self.shared_state.get_by_string(
|
||||||
|
'DeadSimpleKV').get('shutdown'):
|
||||||
try:
|
try:
|
||||||
time.sleep(2)
|
time.sleep(2)
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
self.shutdown = True
|
self.shared_state.get_by_string(
|
||||||
|
'DeadSimpleKV').put('shutdown', True)
|
||||||
|
|
||||||
# Main daemon loop, mainly for calling timers,
|
# Main daemon loop, mainly for calling timers,
|
||||||
# don't do any complex operations here to avoid locking
|
# don't do any complex operations here to avoid locking
|
||||||
try:
|
try:
|
||||||
while not self.shutdown:
|
while not self.shared_state.get_by_string(
|
||||||
|
'DeadSimpleKV').get('shutdown'):
|
||||||
for i in self.timers:
|
for i in self.timers:
|
||||||
if self.shutdown:
|
if self.shared_state.get_by_string(
|
||||||
|
'DeadSimpleKV').get('shutdown'):
|
||||||
break
|
break
|
||||||
i.processTimer()
|
i.processTimer()
|
||||||
time.sleep(self.delay)
|
time.sleep(self.delay)
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
self.shutdown = True
|
self.shared_state.get_by_string(
|
||||||
|
'DeadSimpleKV').put('shutdown', True)
|
||||||
|
|
||||||
logger.info(
|
logger.info(
|
||||||
'Goodbye. (Onionr is cleaning up, and will exit)', terminal=True)
|
'Goodbye. (Onionr is cleaning up, and will exit)', terminal=True)
|
||||||
|
|
|
@ -31,6 +31,7 @@ def get_online_peers(comm_inst: 'OnionrCommunicatorDaemon'):
|
||||||
Connect to more peers if we have none connected
|
Connect to more peers if we have none connected
|
||||||
"""
|
"""
|
||||||
config = comm_inst.config
|
config = comm_inst.config
|
||||||
|
kv: "DeadSimpleKV" = comm_inst.shared_state.get_by_string("DeadSimpleKV")
|
||||||
if config.get('general.offline_mode', False):
|
if config.get('general.offline_mode', False):
|
||||||
comm_inst.decrementThreadCount('get_online_peers')
|
comm_inst.decrementThreadCount('get_online_peers')
|
||||||
return
|
return
|
||||||
|
@ -49,7 +50,7 @@ def get_online_peers(comm_inst: 'OnionrCommunicatorDaemon'):
|
||||||
else:
|
else:
|
||||||
comm_inst.connectNewPeer()
|
comm_inst.connectNewPeer()
|
||||||
|
|
||||||
if comm_inst.shutdown:
|
if kv.get('shutdown'):
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
if len(comm_inst.onlinePeers) == 0:
|
if len(comm_inst.onlinePeers) == 0:
|
||||||
|
|
|
@ -27,6 +27,7 @@ def peer_action(comm_inst, peer, action,
|
||||||
returnHeaders=False, max_resp_size=5242880):
|
returnHeaders=False, max_resp_size=5242880):
|
||||||
"""Perform a get request to a peer."""
|
"""Perform a get request to a peer."""
|
||||||
penalty_score = -10
|
penalty_score = -10
|
||||||
|
kv: "DeadSimpleKV" = comm_inst.shared_state.get_by_string("DeadSimpleKV")
|
||||||
if len(peer) == 0:
|
if len(peer) == 0:
|
||||||
return False
|
return False
|
||||||
url = 'http://%s/%s' % (peer, action)
|
url = 'http://%s/%s' % (peer, action)
|
||||||
|
@ -47,7 +48,7 @@ def peer_action(comm_inst, peer, action,
|
||||||
onlinepeers.remove_online_peer(comm_inst, peer)
|
onlinepeers.remove_online_peer(comm_inst, peer)
|
||||||
keydb.transportinfo.set_address_info(
|
keydb.transportinfo.set_address_info(
|
||||||
peer, 'lastConnectAttempt', epoch.get_epoch())
|
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)
|
logger.warn(f'Lost connection to {peer}', terminal=True)
|
||||||
# Will only add a new peer to pool if needed
|
# Will only add a new peer to pool if needed
|
||||||
onlinepeers.get_online_peers(comm_inst)
|
onlinepeers.get_online_peers(comm_inst)
|
||||||
|
|
|
@ -33,6 +33,7 @@ def connect_new_peer_to_communicator(comm_inst, peer='', useBootstrap=False):
|
||||||
config = comm_inst.config
|
config = comm_inst.config
|
||||||
retData = False
|
retData = False
|
||||||
tried = comm_inst.offlinePeers
|
tried = comm_inst.offlinePeers
|
||||||
|
kv: "DeadSimpleKV" = comm_inst.shared_state.get_by_string("DeadSimpleKV")
|
||||||
transports = gettransports.get()
|
transports = gettransports.get()
|
||||||
if peer != '':
|
if peer != '':
|
||||||
if stringvalidators.validate_transport(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.onlinePeers \
|
||||||
or address in comm_inst.cooldownPeer:
|
or address in comm_inst.cooldownPeer:
|
||||||
continue
|
continue
|
||||||
if comm_inst.shutdown:
|
if kv.get('shutdown'):
|
||||||
return
|
return
|
||||||
# Ping a peer,
|
# Ping a peer,
|
||||||
ret = peeraction.peer_action(comm_inst, address, 'ping')
|
ret = peeraction.peer_action(comm_inst, address, 'ping')
|
||||||
|
|
|
@ -63,7 +63,7 @@ def download_blocks_from_communicator(comm_inst: "OnionrCommunicatorDaemon"):
|
||||||
if not shoulddownload.should_download(comm_inst, blockHash):
|
if not shoulddownload.should_download(comm_inst, blockHash):
|
||||||
continue
|
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():
|
storage_counter.is_full():
|
||||||
# Exit loop if shutting down or offline, or disk allocation reached
|
# Exit loop if shutting down or offline, or disk allocation reached
|
||||||
break
|
break
|
||||||
|
@ -84,7 +84,7 @@ def download_blocks_from_communicator(comm_inst: "OnionrCommunicatorDaemon"):
|
||||||
blockPeers = onionrcrypto.cryptoutils.random_shuffle(blockPeers)
|
blockPeers = onionrcrypto.cryptoutils.random_shuffle(blockPeers)
|
||||||
peerUsed = blockPeers.pop(0)
|
peerUsed = blockPeers.pop(0)
|
||||||
|
|
||||||
if not comm_inst.shutdown and peerUsed.strip() != '':
|
if not kv.get('shutdown') and peerUsed.strip() != '':
|
||||||
logger.info(
|
logger.info(
|
||||||
f"Attempting to download %s from {peerUsed}..." % (blockHash[:12],))
|
f"Attempting to download %s from {peerUsed}..." % (blockHash[:12],))
|
||||||
content = peeraction.peer_action(
|
content = peeraction.peer_action(
|
||||||
|
|
|
@ -32,6 +32,7 @@ def net_check(comm_inst):
|
||||||
"""
|
"""
|
||||||
# for detecting if we have received incoming connections recently
|
# for detecting if we have received incoming connections recently
|
||||||
rec = False
|
rec = False
|
||||||
|
kv: "DeadSimpleKV" = comm_inst.shared_state.get_by_string("DeadSimpleKV")
|
||||||
if len(comm_inst.onlinePeers) == 0:
|
if len(comm_inst.onlinePeers) == 0:
|
||||||
try:
|
try:
|
||||||
if (epoch.get_epoch() - int(localcommand.local_command
|
if (epoch.get_epoch() - int(localcommand.local_command
|
||||||
|
@ -41,7 +42,7 @@ def net_check(comm_inst):
|
||||||
except ValueError:
|
except ValueError:
|
||||||
pass
|
pass
|
||||||
if not rec and not netutils.checkNetwork(torPort=comm_inst.proxyPort):
|
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):
|
if not comm_inst.config.get('general.offline_mode', False):
|
||||||
logger.warn('Network check failed, are you connected to ' +
|
logger.warn('Network check failed, are you connected to ' +
|
||||||
'the Internet, and is Tor working? ' +
|
'the Internet, and is Tor working? ' +
|
||||||
|
|
|
@ -13,6 +13,7 @@ import logger
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
from typing import Callable, NewType, Iterable
|
from typing import Callable, NewType, Iterable
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
|
from deadsimplekv import DeadSimpleKV
|
||||||
from communicator import OnionrCommunicatorDaemon
|
from communicator import OnionrCommunicatorDaemon
|
||||||
"""
|
"""
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
@ -47,6 +48,8 @@ class OnionrCommunicatorTimers:
|
||||||
self.daemon_inst = daemon_inst
|
self.daemon_inst = daemon_inst
|
||||||
self.max_threads = max_threads
|
self.max_threads = max_threads
|
||||||
self.args = my_args
|
self.args = my_args
|
||||||
|
self.kv: "DeadSimpleKV" = daemon_inst.shared_state.get_by_string(
|
||||||
|
"DeadSimpleKV")
|
||||||
|
|
||||||
self.daemon_inst.timers.append(self)
|
self.daemon_inst.timers.append(self)
|
||||||
self.count = 0
|
self.count = 0
|
||||||
|
@ -60,7 +63,7 @@ class OnionrCommunicatorTimers:
|
||||||
self.daemon_inst.threadCounts[self.timer_function.__name__] = 0
|
self.daemon_inst.threadCounts[self.timer_function.__name__] = 0
|
||||||
|
|
||||||
# execute timer's func, if we are not missing *required* online peer
|
# 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:
|
try:
|
||||||
if self.requires_peer and \
|
if self.requires_peer and \
|
||||||
len(self.daemon_inst.onlinePeers) == 0:
|
len(self.daemon_inst.onlinePeers) == 0:
|
||||||
|
|
|
@ -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 Blueprint, Response
|
||||||
from flask import g
|
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
|
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
|
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__)
|
shutdown_bp = Blueprint('shutdown', __name__)
|
||||||
|
|
||||||
|
|
||||||
def shutdown(client_api_inst):
|
def shutdown(client_api_inst):
|
||||||
try:
|
try:
|
||||||
client_api_inst.publicAPI.httpServer.stop()
|
client_api_inst.publicAPI.httpServer.stop()
|
||||||
|
@ -33,8 +30,9 @@ def shutdown(client_api_inst):
|
||||||
pass
|
pass
|
||||||
return Response("bye")
|
return Response("bye")
|
||||||
|
|
||||||
|
|
||||||
@shutdown_bp.route('/shutdownclean')
|
@shutdown_bp.route('/shutdownclean')
|
||||||
def shutdown_clean():
|
def shutdown_clean():
|
||||||
# good for calling from other clients
|
# 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")
|
return Response("bye")
|
||||||
|
|
Loading…
Reference in New Issue