def run(self):
"""Option to calling manually calling start()/stop(). This will start
the server and watch for signals to stop the server"""
self.server.start()
log.info(" ABCIServer started on port: {}".format(self.port))
# wait for interrupt
evt = Event()
gevent.signal(signal.SIGQUIT, evt.set)
gevent.signal(signal.SIGTERM, evt.set)
gevent.signal(signal.SIGINT, evt.set)
evt.wait()
log.info("Shutting down server")
self.server.stop()
# TM will spawn off 3 connections: mempool, consensus, query
# If an error happens in 1 it still leaves the others open which
# means you don't have all the connections available to TM
python类signal()的实例源码
def setup_in_process(self):
# Set up signal handlers for graceful exit
gevent.signal(gevent.signal.SIGINT, self.stop)
gevent.signal(gevent.signal.SIGTERM, self.stop)
# Update config
config['TIMEZONE'] = self.__timezone
config['API_KEY'] = self.__google_key
config['UNITS'] = self.__units
config['DEBUG'] = self.__debug
config['ROOT_PATH'] = os.path.abspath("{}/..".format(os.path.dirname(__file__)))
# Hush some new loggers
logging.getLogger('requests').setLevel(logging.WARNING)
logging.getLogger('urllib3').setLevel(logging.WARNING)
if config['DEBUG'] is True:
logging.getLogger().setLevel(logging.DEBUG)
# Conect the alarms and send the start up message
for alarm in self.__alarms:
alarm.connect()
alarm.startup_message()
# Main event handler loop
def test_exitcode_previous_to_join(self):
p = start_process(lambda: gevent.sleep(SHORTTIME))
# Assume that the child process is still alive when the next
# line is executed by the interpreter (there is no guarantee
# for that, but it's rather likely).
assert p.exitcode is None
# Expect the child watcher mechanism to pick up
# and process the child process termination event
# (within at most two seconds). The `gevent.sleep()`
# invocations allow for libev event loop iterations,
# two of which are required after the OS delivers the
# SIGCHLD signal to the parent process: one iteration
# invokes the child reap loop, and the next invokes
# the libev callback associated with the termination
# event.
deadline = time.time() + 2
while time.time() < deadline:
if p.exitcode is not None:
assert p.exitcode == 0
p.join()
return
gevent.sleep(ALMOSTZERO)
raise Exception('Child termination not detected')
def test_early_readchild_exit_write_from_child(self):
pr = start_process(ipc_readonce_then_exit, (self.rh,))
pw = start_process(ipc_endless_write_for_early_reader_exit, (self.wh,))
# This test is to make sure equivalent behavior as in test
# `test_early_readchild_exit` when the writing process is a
# child process itself (above, the write process in the initial
# process). Since gipc's child process creation
# routine messes around with signal handlers, this test makes
# sure that SIGPIPE is ignored in the child and that a
# failing write attempt (after early read child exit) results
# in an exception raised in the writing process.
pr.join()
pw.join()
assert pr.exitcode == 0
assert pw.exitcode == 0
self.rh2.close()
self.wh2.close()
def test_greenlet(self):
"""??????Greenlet????"""
class MyGreenlet(gevent.Greenlet):
def __init__(self, message, n):
super(MyGreenlet, self).__init__()
self.message = message
self.n = n
def _run(self):
print(self.message)
gevent.sleep(self.n)
g1 = MyGreenlet("Hi there111!", 1)
g1.start()
g2 = MyGreenlet("Hi there222!", 2)
g2.start()
gevent.joinall([g1, g2])
# def test_shutdown(self):
# def run_forever():
# _log.info('run_forever start..')
# gevent.sleep(1000)
# gevent.signal(signal.SIGQUIT, gevent.kill)
# thread = gevent.spawn(run_forever)
# thread.join()
def start(self):
"""start method is where we decide to :
* catch term signal
* run as daemon
* start the http server
"""
self.log.info("CacheServer starting ...")
# catch SIG_TERM
gevent.signal(signal.SIGTERM, self.sig_term)
gevent.signal(signal.SIGHUP, self.sig_hup)
# run
self._run = True
if self._daemon:
self.do_daemon()
# start http server
self.log.info("CacheServer started at: 'http://%s'" % self.http_address)
# Start cache server
try:
self.http_server.serve_forever()
except (SystemExit, KeyboardInterrupt):
pass
# finish here
self.log.info("CacheServer Exited")
def main(args=None, workers=None, client=EchoHubClient, worker_kwargs=None):
gevent.monkey.patch_all()
args = args if args else prepare_argparse().parse_args()
prepare_logging(args.verbose or 1)
if args.mode == 'server':
hub = HubServer(workers=workers)
elif args.mode == 'client':
hub = client(worker_kwargs=worker_kwargs)
else:
raise Exception("Unknown mode '%s'." % args.mode)
def sig_handler(sig=None, frame=None):
log.warning("Hub process received SIGTERM/SIGINT")
hub.stop()
log.info("Sig handler completed.")
gevent.signal(signal.SIGTERM, sig_handler)
gevent.signal(signal.SIGINT, sig_handler) # KeyboardInterrupt also
hub.start()
gevent.wait()
def cli(log_level, live):
logging.basicConfig(
filename='arbloop.log',
format='[%(asctime)s] [%(levelname)s] %(message)s',
level=log_level
)
logging.info('Warming up traders ...')
gevent.signal(signal.SIGQUIT, gevent.kill)
workers = []
for product in config.TRADER_PRODUCTS or []:
trader = Trader(product=product, live=live)
workers.append(
gevent.spawn(trader.trade)
)
gevent.joinall(workers)
def test_exitcode_sigkill(self):
p = start_process(p_child_b)
p.join()
if not WINDOWS:
assert p.exitcode == -signal.SIGKILL
else:
assert p.exitcode == 1
def test_terminate(self):
p = start_process(gevent.sleep, args=(1,))
# Test __repr__ and __str__
p.__repr__()
p.terminate()
p.join()
p.__repr__()
assert p.exitcode == -signal.SIGTERM
def p_child_b():
if not WINDOWS:
os.kill(os.getpid(), signal.SIGKILL)
else:
sys.exit(1)
def teardown(self):
check_for_handles_left_open()
# One could verify that signal handlers are not left improperly
# by a test case, but libev's signal handling might go through
# signalfd() which we cannot detect here anyway. So the test cases
# have to properly clean up their signal handling modifications
# themselves.
def test_orphaned_signal_watcher(self):
# Install libev-based signal watcher.
s = gevent.signal(signal.SIGTERM, signals_test_sigterm_handler)
# Normal behavior: signal handlers become inherited by children.
# Bogus behavior of libev-based signal watchers in child process:
# They should not be active anymore when 'orphaned' (when their
# corresponding event loop has been destroyed). What happens, however:
# The old handler stays active and registering a new handler does not
# 'overwrite' the old one -- both are active.
# Since this test is about testing the behavior of 'orphaned' libev
# signal watchers, the signal must be transmitted *after* event loop
# recreation, so wait here for the child process to go through
# the hub & event loop destruction (and recreation) process before
# sending the signal. Waiting is realized with sync through pipe.
# Without cleanup code in gipc, the inherited but orphaned libev signal
# watcher would be active in the fresh event loop and trigger the
# handler. This is a problem. With cleanup code, this handler must
# never be called. Child exitcode 20 means that the inherited handler
# has been called, -15 (-signal.SIGTERM) means that the child was
# actually killed by SIGTERM within a certain short time interval.
# Returncode 0 would mean that the child finished normally after that
# short time interval.
with pipe() as (r, w):
p = start_process(signals_test_child_a, (w,))
assert r.get() == p.pid
os.kill(p.pid, signal.SIGTERM)
p.join()
if not WINDOWS:
assert p.exitcode == -signal.SIGTERM
else:
assert p.exitcode == signal.SIGTERM
s.cancel()
def test_signal_handlers_default(self):
p = start_process(signals_test_child_defaulthandlers)
p.join()
# Child exits normally when all signal dispositions are default.
assert p.exitcode == 0
def signals_test_child_defaulthandlers():
for s in signals_to_reset:
assert signal.getsignal(s) is signal.SIG_DFL
def sigusr1_handler():
print 'Received SIGUSER1 -- Graceful exit'
sys.exit(0)
# Set the signal handler
def install_handler(self):
if self.installed_force:
self.installed_force.cancel()
self.installed_force = None
self.installed = gevent.signal(signal.SIGINT, self.handle_int)
def install_handler_force(self):
if self.installed:
self.installed.cancel()
self.installed = None
self.installed_force = gevent.signal(signal.SIGINT, self.handle_force)
def handle_force(self): # pylint: disable=no-self-use
""" User pressed ^C a second time. Send SIGTERM to ourself. """
os.kill(os.getpid(), signal.SIGTERM)
def __init__(self, api, token_address):
assert isinstance(api, RaidenAPI)
self.ready = Event()
self.api = api
self.token_address = token_address
existing_channels = self.api.get_channel_list(self.token_address)
open_channels = [
channel for channel in existing_channels if channel.state == CHANNEL_STATE_OPENED
]
if len(open_channels) == 0:
token = self.api.raiden.chain.token(self.token_address)
if not token.balance_of(self.api.raiden.address) > 0:
raise ValueError('not enough funds for echo node %s for token %s' % (
pex(self.api.raiden.address),
pex(self.token_address),
))
self.api.connect_token_network(
self.token_address,
token.balance_of(self.api.raiden.address),
initial_channel_target=10,
joinable_funds_target=.5,
)
self.last_poll_block = self.api.raiden.get_block_number()
self.received_transfers = Queue()
self.stop_signal = None # used to signal REMOVE_CALLBACK and stop echo_workers
self.greenlets = list()
self.lock = BoundedSemaphore()
self.seen_transfers = deque(list(), TRANSFER_MEMORY)
self.num_handled_transfers = 0
self.lottery_pool = Queue()
# register ourselves with the raiden alarm task
self.api.raiden.alarm.register_callback(self.echo_node_alarm_callback)
self.echo_worker_greenlet = gevent.spawn(self.echo_worker)
def echo_node_alarm_callback(self, block_number):
""" This can be registered with the raiden AlarmTask.
If `EchoNode.stop()` is called, it will give the return signal to be removed from
the AlarmTask callbacks.
"""
if not self.ready.is_set():
self.ready.set()
log.debug('echo_node callback', block_number=block_number)
if self.stop_signal is not None:
return REMOVE_CALLBACK
else:
self.greenlets.append(gevent.spawn(self.poll_all_received_events))
return True
def main():
server = MixedTCPServer(LISTEN_PORT, SS_PORT)
gevent.signal(signal.SIGTERM, server.close)
gevent.signal(signal.SIGINT, server.close)
server.start()
gevent.wait()
def main():
args = sys.argv[1:]
if len(args) != 2:
sys.exit('Usage: %s source-address destination-address' % __file__)
source = args[0]
dest = parse_address(args[1])
server = PortForwarder(source, dest)
log('Starting port forwarder %s:%s -> %s:%s', *(server.address[:2] + dest))
gevent.signal(signal.SIGTERM, server.close)
gevent.signal(signal.SIGINT, server.close)
server.start()
gevent.wait()
def stop():
print 'Handling signal TERM'
if http_server.started:
http_server.stop()
sys.exit(signal.SIGTERM)
def stop():
print 'Handling signal TERM'
if http_server.started:
http_server.stop()
sys.exit(signal.SIGTERM)
def sig_term(self, *args):
"""if we receive a term signal, we will shutdown properly
"""
self.log.warn("Shutdown ...")
self.stop()
sys.exit(0)
def start(self):
self.log.info("Starting OutboundServer ...")
# catch SIG_TERM
gevent.signal(signal.SIGTERM, self.sig_term)
gevent.signal(signal.SIGHUP, self.sig_hup)
# run
self._run = True
if self._daemon:
self.do_daemon()
super(PlivoOutboundServer, self).start()
self.log.info("OutboundServer started at '%s'" \
% str(self.fs_outbound_address))
self.serve_forever()
self.log.info("OutboundServer Exited")
def sig_term(self, *args):
"""if we receive a term signal, we will shutdown properly
"""
self.log.warn("Shutdown ...")
self.stop()
sys.exit(0)
def setup_handlers(server, plugin):
"""
Setup signal handlers to stop server gracefully.
"""
gevent.signal(signal.SIGINT, partial(stop_services, server, plugin))
gevent.signal(signal.SIGTERM, partial(stop_services, server, plugin))
def sender_shutdown():
global shutdown_started
# Make control+c or some other kill signal force quit the second time it happens
if shutdown_started:
logger.info('Force exiting')
os._exit(0)
else:
shutdown_started = True
logger.info('Shutting server..')
# Immediately release all locks and give up any master status and slave presence
if coordinator:
coordinator.leave_cluster()
# Stop sender RPC server
rpc.shutdown()
for tasks in worker_tasks.itervalues():
for task in tasks:
task['kill_set'].set()
for tasks in autoscale_email_worker_tasks.itervalues():
for task in tasks:
task['kill_set'].set()
logger.info('Waiting for sender workers to shut down')
for tasks in worker_tasks.itervalues():
for task in tasks:
task['greenlet'].join()
for tasks in autoscale_email_worker_tasks.itervalues():
for task in tasks:
task['greenlet'].join()
# Force quit. Avoid sender process existing longer than it needs to
os._exit(0)