<commit_before># encoding: utf-8
"""
exabgp.py

Created by <NAME> on 2009-08-30.
Copyright (c) 2009 Exa Networks. All rights reserved.
"""

import os
import sys
import time
import signal
import select

from exabgp.network.peer import Peer
from exabgp.version import version

from exabgp.daemon import Daemon
from exabgp.processes import Processes
from exabgp.configuration import Configuration
from exabgp.network.connection import errno_block

from exabgp.log import Logger
logger = Logger()


class Supervisor (object):
	# [hex(ord(c)) for c in os.popen('clear').read()]
	clear = ''.join([chr(int(c,16)) for c in ['0x1b', '0x5b', '0x48', '0x1b', '0x5b', '0x32', '0x4a']])

	def __init__ (self,configuration):
		self.daemon = Daemon(self)
		self.processes = Processes(self)
		self.configuration = Configuration(configuration)

		self.watchdogs = {}
		self._peers = {}
		self._shutdown = False
		self._reload = False
		self._restart = False
		self._route_update = False
		self._commands = {}
		self._saved_pid = False
		self.reload()

		signal.signal(signal.SIGTERM, self.sigterm)
		signal.signal(signal.SIGHUP, self.sighup)
		signal.signal(signal.SIGALRM, self.sigalrm)

	def sigterm (self,signum, frame):
		logger.supervisor("SIG TERM received")
		self._shutdown = True

	def sighup (self,signum, frame):
		logger.supervisor("SIG HUP received")
		self._reload = True

	def sigalrm (self,signum, frame):
		logger.supervisor("SIG ALRM received")
		self._restart = True

	def run (self,supervisor_speed=0.5):
		if self.daemon.drop_privileges():
			logger.supervisor("Could not drop privileges to '%s' refusing to run as root" % self.daemon.user)
			logger.supervisor("Set the environmemnt value USER to change the unprivileged user")
			return
		self.daemon.daemonise()
		self.daemon.savepid()

		# did we complete the run of updates caused by the last SIGHUP ?
		reload_completed = True

		while True:
			try:
				while self._peers:
					start = time.time()

					self.handle_commands(self.processes.received())

					if self._shutdown:
						self._shutdown = False
						self.shutdown()
					elif self._reload and reload_completed:
						self._reload = False
						self.reload()
					elif self._restart:
						self._restart = False
						self.restart()
					elif self._route_update:
						self._route_update = False
						self.route_update()
					elif self._commands:
						self.commands(self._commands)
						self._commands = {}

					reload_completed = True
					# Handle all connection
					peers = self._peers.keys()
					ios = []
					while peers:
						for key in peers[:]:
							peer = self._peers[key]
							# there was no routes to send for this peer, we performed keepalive checks
							if peer.run() is not True:
								# no need to come back to it before a a full cycle
								if peer.bgp and peer.bgp.connection:
									ios.append(peer.bgp.connection.io)
								peers.remove(key)
							# send the route we parsed (if we parsed any to our child processes)
							# This is a generator and can only be run once
							for route in peer.received_routes():
								# This is a generator which content does only change at config reload
								for name in self.processes.receive_routes():
									# using str(key) as we should not manipulate it and assume its format
									self.processes.write(name,"neighbor %s %s\n" % (str(key),route))
						# otherwise process as many routes as we can within a second for the remaining peers
						duration = time.time() - start
						# RFC state that we MUST not more than one KEEPALIVE / sec
						# And doing less could cause the session to drop
						if duration >= 1.0:
							reload_completed = False
							ios=[]
							break
					duration = time.time() - start
					if ios:
						try:
							read,_,_ = select.select(ios,[],[],max(supervisor_speed-duration,0))
						except select.error,e:
							errno,message = e.args
							if not errno in errno_block:
								raise
					else:
						if duration < supervisor_speed:
							time.sleep(max(supervisor_speed-duration,0))
				self.processes.terminate()
				self.daemon.removepid()
				break
			except KeyboardInterrupt:
				logger.supervisor("^C received")
				self._shutdown = True
#				from leak import objgraph
#				print objgraph.show_most_common_types(limit=20)
#				import random
#				obj = objgraph.by_type('ReceivedRoute')[random.randint(0,2000)]
#				objgraph.show_backrefs([obj], max_depth=10)

	def shutdown (self):
		"""terminate all the current BGP connections"""
		logger.info("Performing shutdown","supervisor")
		for key in self._peers.keys():
			self._peers[key].stop()

	def reload (self):
		"""reload the configuration and send to the peer the route which changed"""
		logger.info("Performing reload of exabgp %s" % version,"configuration")

		reloaded = self.configuration.reload()<commit_msg>^C during IO cause IO Errors, intercept them<commit_after># encoding: utf-8
"""
exabgp.py

Created by <NAME> on 2009-08-30.
Copyright (c) 2009 Exa Networks. All rights reserved.
"""

import os
import sys
import time
import signal
import select

from exabgp.network.peer import Peer
from exabgp.version import version

from exabgp.daemon import Daemon
from exabgp.processes import Processes
from exabgp.configuration import Configuration
from exabgp.network.connection import errno_block

from exabgp.log import Logger
logger = Logger()


class Supervisor (object):
	# [hex(ord(c)) for c in os.popen('clear').read()]
	clear = ''.join([chr(int(c,16)) for c in ['0x1b', '0x5b', '0x48', '0x1b', '0x5b', '0x32', '0x4a']])

	def __init__ (self,configuration):
		self.daemon = Daemon(self)
		self.processes = Processes(self)
		self.configuration = Configuration(configuration)

		self.watchdogs = {}
		self._peers = {}
		self._shutdown = False
		self._reload = False
		self._restart = False
		self._route_update = False
		self._commands = {}
		self._saved_pid = False
		self.reload()

		signal.signal(signal.SIGTERM, self.sigterm)
		signal.signal(signal.SIGHUP, self.sighup)
		signal.signal(signal.SIGALRM, self.sigalrm)

	def sigterm (self,signum, frame):
		logger.supervisor("SIG TERM received")
		self._shutdown = True

	def sighup (self,signum, frame):
		logger.supervisor("SIG HUP received")
		self._reload = True

	def sigalrm (self,signum, frame):
		logger.supervisor("SIG ALRM received")
		self._restart = True

	def run (self,supervisor_speed=0.5):
		if self.daemon.drop_privileges():
			logger.supervisor("Could not drop privileges to '%s' refusing to run as root" % self.daemon.user)
			logger.supervisor("Set the environmemnt value USER to change the unprivileged user")
			return
		self.daemon.daemonise()
		self.daemon.savepid()

		# did we complete the run of updates caused by the last SIGHUP ?
		reload_completed = True

		while True:
			try:
				while self._peers:
					start = time.time()

					self.handle_commands(self.processes.received())

					if self._shutdown:
						self._shutdown = False
						self.shutdown()
					elif self._reload and reload_completed:
						self._reload = False
						self.reload()
					elif self._restart:
						self._restart = False
						self.restart()
					elif self._route_update:
						self._route_update = False
						self.route_update()
					elif self._commands:
						self.commands(self._commands)
						self._commands = {}

					reload_completed = True
					# Handle all connection
					peers = self._peers.keys()
					ios = []
					while peers:
						for key in peers[:]:
							peer = self._peers[key]
							# there was no routes to send for this peer, we performed keepalive checks
							if peer.run() is not True:
								# no need to come back to it before a a full cycle
								if peer.bgp and peer.bgp.connection:
									ios.append(peer.bgp.connection.io)
								peers.remove(key)
							# send the route we parsed (if we parsed any to our child processes)
							# This is a generator and can only be run once
							for route in peer.received_routes():
								# This is a generator which content does only change at config reload
								for name in self.processes.receive_routes():
									# using str(key) as we should not manipulate it and assume its format
									self.processes.write(name,"neighbor %s %s\n" % (str(key),route))
						# otherwise process as many routes as we can within a second for the remaining peers
						duration = time.time() - start
						# RFC state that we MUST not more than one KEEPALIVE / sec
						# And doing less could cause the session to drop
						if duration >= 1.0:
							reload_completed = False
							ios=[]
							break
					duration = time.time() - start
					if ios:
						try:
							read,_,_ = select.select(ios,[],[],max(supervisor_speed-duration,0))
						except select.error,e:
							errno,message = e.args
							if not errno in errno_block:
								raise
					else:
						if duration < supervisor_speed:
							time.sleep(max(supervisor_speed-duration,0))
				self.processes.terminate()
				self.daemon.removepid()
				break
			except KeyboardInterrupt:
				logger.supervisor("^C received")
				self._shutdown = True
			except IOError:
				logger.supervisor("I/O Error received, most likely ^C during IO")
				self._shutdown = True
#				from leak import objgraph
#				print objgraph.show_most_common_types(limit=20)
#				import random
#				obj = objgraph.by_type('ReceivedRoute')[random.randint(0,2000)]
#				objgraph.show_backrefs([obj], max_depth=10)

	def shutdown (self):
		"""terminate all the current BGP connections"""
		logger.info("Performing shutdown","supervisor")
		for key in self._peers.keys():
			self._peers[key].stop()

	def reload (self):
		"""reload the configuration and send to the peer the route which changed"""
		logger.info("Performing reload of exabgp %s" % version,"configuration")

		reloaded = self.configuration.reload()
{'fraction_non_alphanumeric': 0.10330409953089945, 'fraction_numerical': 0.009382011013665103, 'mean_word_length': 3.19281744335186, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4407858', 'n_tokens_mistral': 3888, 'n_tokens_neox': 3020, 'n_words': 918}