2015-07-12 20:36:46 +02:00
|
|
|
import sys
|
|
|
|
import logging
|
2019-03-23 03:41:42 +01:00
|
|
|
import signal
|
|
|
|
import importlib
|
2015-07-12 20:36:46 +02:00
|
|
|
|
|
|
|
import gevent
|
2016-03-11 12:39:39 +01:00
|
|
|
import gevent.hub
|
2015-07-12 20:36:46 +02:00
|
|
|
|
version 0.2.0, new lib for bitcoin ecc, dont display or track notify errors, dont reload again within 1 sec, null peer ip fix, signingmoved to ContentManager, content.json include support, content.json multisig ready, content.json proper bitcoincore compatible signing, content.json include permissions, multithreaded publish, publish timeout 60s, no exception on invalid bitcoin address, testcase for new lib, bip32 based persite privatekey generation, multiuser ready, simple json database query command, websocket api fileGet, wrapper loading title stuck bugfix
2015-02-09 02:09:02 +01:00
|
|
|
from Config import config
|
2019-03-23 03:41:42 +01:00
|
|
|
from . import Debug
|
2015-01-12 02:03:45 +01:00
|
|
|
|
|
|
|
last_error = None
|
version 0.2.0, new lib for bitcoin ecc, dont display or track notify errors, dont reload again within 1 sec, null peer ip fix, signingmoved to ContentManager, content.json include support, content.json multisig ready, content.json proper bitcoincore compatible signing, content.json include permissions, multithreaded publish, publish timeout 60s, no exception on invalid bitcoin address, testcase for new lib, bip32 based persite privatekey generation, multiuser ready, simple json database query command, websocket api fileGet, wrapper loading title stuck bugfix
2015-02-09 02:09:02 +01:00
|
|
|
|
2019-03-23 03:41:42 +01:00
|
|
|
def shutdown(reason="Unknown"):
|
|
|
|
logging.info("Shutting down (reason: %s)..." % reason)
|
2019-04-15 12:31:33 +02:00
|
|
|
import main
|
2019-04-15 16:07:18 +02:00
|
|
|
if "file_server" in dir(main):
|
2018-04-04 15:33:25 +02:00
|
|
|
try:
|
2019-04-15 16:07:18 +02:00
|
|
|
gevent.spawn(main.file_server.stop)
|
2019-04-15 12:31:33 +02:00
|
|
|
if "ui_server" in dir(main):
|
|
|
|
gevent.spawn(main.ui_server.stop)
|
2019-03-15 21:06:59 +01:00
|
|
|
except Exception as err:
|
|
|
|
print("Proper shutdown error: %s" % err)
|
2018-04-04 15:33:25 +02:00
|
|
|
sys.exit(0)
|
|
|
|
else:
|
2016-03-12 23:09:57 +01:00
|
|
|
sys.exit(0)
|
2015-07-12 20:36:46 +02:00
|
|
|
|
version 0.2.0, new lib for bitcoin ecc, dont display or track notify errors, dont reload again within 1 sec, null peer ip fix, signingmoved to ContentManager, content.json include support, content.json multisig ready, content.json proper bitcoincore compatible signing, content.json include permissions, multithreaded publish, publish timeout 60s, no exception on invalid bitcoin address, testcase for new lib, bip32 based persite privatekey generation, multiuser ready, simple json database query command, websocket api fileGet, wrapper loading title stuck bugfix
2015-02-09 02:09:02 +01:00
|
|
|
# Store last error, ignore notify, allow manual error logging
|
2019-03-23 03:41:42 +01:00
|
|
|
def handleError(*args, **kwargs):
|
2015-07-12 20:36:46 +02:00
|
|
|
global last_error
|
|
|
|
if not args: # Manual called
|
|
|
|
args = sys.exc_info()
|
|
|
|
silent = True
|
|
|
|
else:
|
|
|
|
silent = False
|
|
|
|
if args[0].__name__ != "Notify":
|
|
|
|
last_error = args
|
2019-03-23 03:41:42 +01:00
|
|
|
|
2016-03-12 23:09:57 +01:00
|
|
|
if args[0].__name__ == "KeyboardInterrupt":
|
2019-03-23 03:41:42 +01:00
|
|
|
shutdown("Keyboard interrupt")
|
|
|
|
elif not silent and args[0].__name__ != "Notify":
|
2015-07-12 20:36:46 +02:00
|
|
|
logging.exception("Unhandled exception")
|
2018-01-19 02:24:29 +01:00
|
|
|
if "greenlet.py" not in args[2].tb_frame.f_code.co_filename: # Don't display error twice
|
2019-03-23 03:41:42 +01:00
|
|
|
sys.__excepthook__(*args, **kwargs)
|
version 0.2.0, new lib for bitcoin ecc, dont display or track notify errors, dont reload again within 1 sec, null peer ip fix, signingmoved to ContentManager, content.json include support, content.json multisig ready, content.json proper bitcoincore compatible signing, content.json include permissions, multithreaded publish, publish timeout 60s, no exception on invalid bitcoin address, testcase for new lib, bip32 based persite privatekey generation, multiuser ready, simple json database query command, websocket api fileGet, wrapper loading title stuck bugfix
2015-02-09 02:09:02 +01:00
|
|
|
|
|
|
|
|
|
|
|
# Ignore notify errors
|
2019-03-23 03:41:42 +01:00
|
|
|
def handleErrorNotify(*args, **kwargs):
|
|
|
|
err = args[0]
|
|
|
|
if err.__name__ == "KeyboardInterrupt":
|
|
|
|
shutdown("Keyboard interrupt")
|
|
|
|
elif err.__name__ != "Notify":
|
2019-11-19 01:42:00 +01:00
|
|
|
logging.error("Unhandled exception: %s" % Debug.formatException(args))
|
2019-03-23 03:41:42 +01:00
|
|
|
sys.__excepthook__(*args, **kwargs)
|
version 0.2.0, new lib for bitcoin ecc, dont display or track notify errors, dont reload again within 1 sec, null peer ip fix, signingmoved to ContentManager, content.json include support, content.json multisig ready, content.json proper bitcoincore compatible signing, content.json include permissions, multithreaded publish, publish timeout 60s, no exception on invalid bitcoin address, testcase for new lib, bip32 based persite privatekey generation, multiuser ready, simple json database query command, websocket api fileGet, wrapper loading title stuck bugfix
2015-02-09 02:09:02 +01:00
|
|
|
|
2015-01-12 02:03:45 +01:00
|
|
|
|
2016-03-11 12:39:39 +01:00
|
|
|
if config.debug: # Keep last error for /Debug
|
2015-07-12 20:36:46 +02:00
|
|
|
sys.excepthook = handleError
|
version 0.2.0, new lib for bitcoin ecc, dont display or track notify errors, dont reload again within 1 sec, null peer ip fix, signingmoved to ContentManager, content.json include support, content.json multisig ready, content.json proper bitcoincore compatible signing, content.json include permissions, multithreaded publish, publish timeout 60s, no exception on invalid bitcoin address, testcase for new lib, bip32 based persite privatekey generation, multiuser ready, simple json database query command, websocket api fileGet, wrapper loading title stuck bugfix
2015-02-09 02:09:02 +01:00
|
|
|
else:
|
2015-07-12 20:36:46 +02:00
|
|
|
sys.excepthook = handleErrorNotify
|
version 0.2.0, new lib for bitcoin ecc, dont display or track notify errors, dont reload again within 1 sec, null peer ip fix, signingmoved to ContentManager, content.json include support, content.json multisig ready, content.json proper bitcoincore compatible signing, content.json include permissions, multithreaded publish, publish timeout 60s, no exception on invalid bitcoin address, testcase for new lib, bip32 based persite privatekey generation, multiuser ready, simple json database query command, websocket api fileGet, wrapper loading title stuck bugfix
2015-02-09 02:09:02 +01:00
|
|
|
|
2016-03-11 12:39:39 +01:00
|
|
|
|
|
|
|
# Override default error handler to allow silent killing / custom logging
|
2016-04-06 13:45:47 +02:00
|
|
|
if "handle_error" in dir(gevent.hub.Hub):
|
|
|
|
gevent.hub.Hub._original_handle_error = gevent.hub.Hub.handle_error
|
|
|
|
else:
|
|
|
|
logging.debug("gevent.hub.Hub.handle_error not found using old gevent hooks")
|
|
|
|
OriginalGreenlet = gevent.Greenlet
|
|
|
|
class ErrorhookedGreenlet(OriginalGreenlet):
|
|
|
|
def _report_error(self, exc_info):
|
|
|
|
sys.excepthook(exc_info[0], exc_info[1], exc_info[2])
|
|
|
|
|
|
|
|
gevent.Greenlet = gevent.greenlet.Greenlet = ErrorhookedGreenlet
|
2019-03-15 21:06:59 +01:00
|
|
|
importlib.reload(gevent)
|
2016-03-11 12:39:39 +01:00
|
|
|
|
2019-11-19 01:42:00 +01:00
|
|
|
def handleGreenletError(context, type, value, tb):
|
2019-11-19 02:16:44 +01:00
|
|
|
if context.__class__ is tuple and context[0].__class__.__name__ == "ThreadPool":
|
|
|
|
# Exceptions in ThreadPool will be handled in the main Thread
|
|
|
|
return None
|
|
|
|
|
2016-03-18 19:19:59 +01:00
|
|
|
if isinstance(value, str):
|
|
|
|
# Cython can raise errors where the value is a plain string
|
|
|
|
# e.g., AttributeError, "_semaphore.Semaphore has no attr", <traceback>
|
|
|
|
value = type(value)
|
2019-11-19 01:42:00 +01:00
|
|
|
|
|
|
|
if not issubclass(type, gevent.get_hub().NOT_ERROR):
|
2016-03-18 19:19:59 +01:00
|
|
|
sys.excepthook(type, value, tb)
|
2016-03-11 12:39:39 +01:00
|
|
|
|
2019-11-19 01:42:00 +01:00
|
|
|
gevent.get_hub().handle_error = handleGreenletError
|
2015-04-19 15:38:41 +02:00
|
|
|
|
2019-03-23 03:41:42 +01:00
|
|
|
try:
|
|
|
|
signal.signal(signal.SIGTERM, lambda signum, stack_frame: shutdown("SIGTERM"))
|
|
|
|
except Exception as err:
|
|
|
|
logging.debug("Error setting up SIGTERM watcher: %s" % err)
|
|
|
|
|
|
|
|
|
2015-04-19 15:38:41 +02:00
|
|
|
if __name__ == "__main__":
|
2015-07-12 20:36:46 +02:00
|
|
|
import time
|
|
|
|
from gevent import monkey
|
|
|
|
monkey.patch_all(thread=False, ssl=False)
|
2019-03-15 21:06:59 +01:00
|
|
|
from . import Debug
|
2015-04-19 15:38:41 +02:00
|
|
|
|
2016-03-11 12:39:39 +01:00
|
|
|
def sleeper(num):
|
2019-03-15 21:06:59 +01:00
|
|
|
print("started", num)
|
2015-07-12 20:36:46 +02:00
|
|
|
time.sleep(3)
|
2016-03-11 12:39:39 +01:00
|
|
|
raise Exception("Error")
|
2019-03-15 21:06:59 +01:00
|
|
|
print("stopped", num)
|
2016-03-11 12:39:39 +01:00
|
|
|
thread1 = gevent.spawn(sleeper, 1)
|
|
|
|
thread2 = gevent.spawn(sleeper, 2)
|
2015-07-12 20:36:46 +02:00
|
|
|
time.sleep(1)
|
2019-03-15 21:06:59 +01:00
|
|
|
print("killing...")
|
2016-03-11 12:39:39 +01:00
|
|
|
thread1.kill(exception=Debug.Notify("Worker stopped"))
|
|
|
|
#thread2.throw(Debug.Notify("Throw"))
|
2019-03-15 21:06:59 +01:00
|
|
|
print("killed")
|
2018-04-04 15:33:25 +02:00
|
|
|
gevent.joinall([thread1,thread2])
|