01234567890123456789012345678901234567890123456789012345678901234567890123456789
323324325326327328329330331332333334335336337338339340341342 343344345346347348349350351352 353354355356357358359360361362363364365366367368369370371372 391392393394395396397398399400401402403404405406407408409410411412413414 415416417418419420421422423424425426427428429430431432433434 50865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126 56475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774 |
<----SKIPPED LINES---->
AIRCRAFT_LENGTH['Boeing 737-400 (twin-jet)'] = 36.4
AIRCRAFT_LENGTH['Boeing 737-700 (twin-jet)'] = 33.63
AIRCRAFT_LENGTH['Boeing 737-800 (twin-jet)'] = 39.47
AIRCRAFT_LENGTH['Boeing 737-900 (twin-jet)'] = 42.11
AIRCRAFT_LENGTH['Boeing 747-400 (quad-jet)'] = 36.4
AIRCRAFT_LENGTH['Boeing 747-8 (quad-jet)'] = 76.25
AIRCRAFT_LENGTH['Boeing 757-200 (twin-jet)'] = 47.3
AIRCRAFT_LENGTH['Boeing 757-300 (twin-jet)'] = 54.4
AIRCRAFT_LENGTH['Boeing 767-200 (twin-jet)'] = 48.51
AIRCRAFT_LENGTH['Boeing 767-300 (twin-jet)'] = 54.94
AIRCRAFT_LENGTH['Boeing 777 (twin-jet)'] = (63.73 + 73.86) / 2
AIRCRAFT_LENGTH['Boeing 777-200 (twin-jet)'] = 63.73
AIRCRAFT_LENGTH['Boeing 777-200LR/F (twin-jet)'] = 63.73
AIRCRAFT_LENGTH['Boeing 777-300ER (twin-jet)'] = 73.86
AIRCRAFT_LENGTH['Boeing 787-10 (twin-jet)'] = 68.28
AIRCRAFT_LENGTH['Boeing 787-8 (twin-jet)'] = 56.72
AIRCRAFT_LENGTH['Boeing 787-9 (twin-jet)'] = 62.81
AIRCRAFT_LENGTH['Canadair Regional Jet CRJ-200 (twin-jet)'] = 26.77
AIRCRAFT_LENGTH['Canadair Regional Jet CRJ-700 (twin-jet)'] = 32.3
AIRCRAFT_LENGTH['Canadair Regional Jet CRJ-900 (twin-jet)'] = 36.2
AIRCRAFT_LENGTH['Canadair Challenger 350 (twin-jet)'] = 20.9
AIRCRAFT_LENGTH['Bombardier Challenger 300 (twin-jet)'] = 20.92
AIRCRAFT_LENGTH['Bombardier Global Express (twin-jet)'] = (29.5 + 30.3) / 2
AIRCRAFT_LENGTH['Embraer 170/175 (twin-jet)'] = (29.90 + 31.68) / 2
AIRCRAFT_LENGTH['Embraer Phenom 300 (twin-jet)'] = 15.9
AIRCRAFT_LENGTH['EMBRAER 175 (long wing) (twin-jet)'] = 31.68
AIRCRAFT_LENGTH['Embraer ERJ-135 (twin-jet)'] = 26.33
AIRCRAFT_LENGTH['Cessna Caravan (single-turboprop)'] = 11.46
AIRCRAFT_LENGTH['Cessna Citation CJ2+ (twin-jet)'] = 14.53
AIRCRAFT_LENGTH['Cessna Citation CJ3 (twin-jet)'] = 15.59
AIRCRAFT_LENGTH['Cessna Citation II (twin-jet)'] = 14.54
AIRCRAFT_LENGTH['Cessna Citation Latitude (twin-jet)'] = 18.97
AIRCRAFT_LENGTH['Cessna Citation Sovereign (twin-jet)'] = 19.35
AIRCRAFT_LENGTH['Cessna Citation V (twin-jet)'] = 14.91
AIRCRAFT_LENGTH['Cessna Citation X (twin-jet)'] = 22.04
AIRCRAFT_LENGTH['Cessna Skyhawk (piston-single)'] = 8.28
AIRCRAFT_LENGTH['Cessna Skylane (piston-single)'] = 8.84
AIRCRAFT_LENGTH['Cessna T206 Turbo Stationair (piston-single)'] = 8.61
AIRCRAFT_LENGTH['Beechcraft Bonanza (33) (piston-single)'] = 7.65
AIRCRAFT_LENGTH['Beechcraft Super King Air 200 (twin-turboprop)'] = 13.31
AIRCRAFT_LENGTH['Beechcraft Super King Air 350 (twin-turboprop)'] = 14.22
AIRCRAFT_LENGTH['Beechcraft King Air 90 (twin-turboprop)'] = 10.82
AIRCRAFT_LENGTH['Learjet 45 (twin-jet)'] = 17.68
AIRCRAFT_LENGTH['Pilatus PC-12 (single-turboprop)'] = 14.4
def Log(message, file=None, rolling=None):
"""Write a message to a logfile along with a timestamp.
Args:
<----SKIPPED LINES---->
f.write(str(datetime.datetime.now(TZ))+'\n')
f.write('\n')
f.write(str(message)+'\n')
except IOError:
Log('Unable to append to ' + file)
if rolling:
existing_log_lines = ReadFile(file).splitlines()
with open(rolling, 'w') as f:
f.write('\n'.join(existing_log_lines[-ROLLING_LOG_SIZE:]))
def UpdateRollingLogSize(configuration):
"""Set the global rolling_log_line_count based on settings file."""
if 'rolling_log_line_count' in configuration:
global ROLLING_LOG_SIZE
ROLLING_LOG_SIZE = configuration['rolling_log_line_count']
def LogTimes(times):
"""Logs elapsed time messages from a list of epochs."""
msg = ''
for n, t in enumerate(times[:-1]):
msg += '%.2fs to get from reading %d to reading %s\n' % (times[n + 1] - t, n, n + 1)
Log(msg)
def MaintainRollingWebLog(message, max_count, filename=None):
"""Maintains a rolling text file of at most max_count printed messages.
Newest data at top and oldest data at the end, of at most max_count messages,
where the delimiter between each message is identified by a special fixed string.
Args:
message: text message to prepend to the file.
max_count: maximum number of messages to keep in the file; the max_count+1st message
is deleted.
filename: the file to update.
"""
# can't define as a default parameter because ROLLING_MESSAGE_FILE name is potentially
# modified based on SIMULATION flag
if not filename:
filename = ROLLING_MESSAGE_FILE
rolling_log_header = '='*(SPLITFLAP_CHARS_PER_LINE + 2)
<----SKIPPED LINES---->
args=(to_servo_q, to_main_q, shutdown[1]))
return remote, servo
def ValidateSingleRunning(enabled, start_function, p=None, args=()):
"""Restarts a new instance of multiprocessing process if not running"""
if not SHUTDOWN_SIGNAL:
if not enabled:
if p is not None: # must have just requested a disabling of single instance
args[2].value = 1 # trigger a shutdown on the single instance
return None
if p is None or not p.is_alive():
if p is None:
Log('Process for %s starting for first time' % str(start_function))
elif VERBOSE:
Log('Process (%s) for %s died; restarting' % (str(p), str(start_function)))
args[2].value = 0 # (re)set shutdown flag to allow function to run
p = multiprocessing.Process(target=start_function, args=args)
p.daemon = True # has been set to True #TODO
p.start()
return p
def EnqueueArduinos(flights, json_desc_dict, configuration, to_servo_q, to_remote_q):
"""Send latest data to arduinos via their shared-memory queues"""
last_flight = {}
if flights:
last_flight = flights[-1]
if SIMULATION:
now = json_desc_dict['now']
else:
now = time.time()
additional_attributes = {}
today = EpochDisplayTime(now, '%x')
flight_count_today = len([1 for f in flights if DisplayTime(f, '%x') == today])
<----SKIPPED LINES---->
global VERSION_ARDUINO
VERSION_MESSAGEBOARD = MakeCopy('messageboard')
VERSION_ARDUINO = MakeCopy('arduino')
def main():
"""Traffic cop between incoming radio flight messages, configuration, and messageboard.
This is the main logic, checking for new flights, augmenting the radio signal with
additional web-scraped data, and generating messages in a form presentable to the
messageboard.
"""
VersionControl()
# Since this clears log files, it should occur first before we start logging
if '-s' in sys.argv:
global SIMULATION_COUNTER
SimulationSetup()
last_heartbeat_time = HeartbeatRestart()
init_timing = [time.time()] # time 0
# This flag slows down simulation time around a flight, great for debugging the arduinos
simulation_slowdown = bool('-f' in sys.argv)
# Redirect any errors to a log file instead of the screen, and add a datestamp
if not SIMULATION:
sys.stderr = open(STDERR_FILE, 'a')
Log('', STDERR_FILE)
init_timing.append(time.time()) # time 1
Log('Starting up process %d' % os.getpid())
already_running_ids = FindRunningParents()
if already_running_ids:
for pid in already_running_ids:
Log('Sending termination signal to %d' % pid)
os.kill(pid, signal.SIGTERM)
init_timing.append(time.time()) # time 2
SetPinMode()
configuration = ReadAndParseSettings(CONFIG_FILE)
UpdateRollingLogSize(configuration)
startup_time = time.time()
json_desc_dict = {}
init_timing.append(time.time()) # time 3
flights = UnpickleObjectFromFile(PICKLE_FLIGHTS, True, max_days=MAX_INSIGHT_HORIZON_DAYS)
# Clear the loaded flight of any cached data, identified by keys with a specific
# suffix, since code fixes may change the values for some of those cached elements
for flight in flights:
for key in list(flight.keys()):
if key.endswith(CACHED_ELEMENT_PREFIX):
flight.pop(key)
init_timing.append(time.time()) # time 4
# If we're displaying just a single insight message, we want it to be something
# unique, to the extent possible; this dict holds a count of the diff types of messages
# displayed so far
insight_message_distribution = {}
# bootstrap the flight insights distribution from a list of insights on each
# flight (i.e.: flight['insight_types'] for a given flight might look like
# [1, 2, 7, 9], or [], to indicate which insights were identified; this then
# transforms that into {0: 25, 1: 18, ...} summing across all flights.
missing_insights = []
for flight in flights:
if 'insight_types' not in flight:
missing_insights.append(
'%s on %s' % (DisplayFlightNumber(flight), DisplayTime(flight, '%x %X')))
distribution = flight.get('insight_types', [])
for key in distribution:
insight_message_distribution[key] = (
insight_message_distribution.get(key, 0) + 1)
if missing_insights:
Log('Flights missing insight distributions: %s' % ';'.join(missing_insights))
init_timing.append(time.time()) # time 5
# initialize objects required for arduinos, but we can only start them in the main
# loop, because the tail end of the init section needs to confirm that all other
# messageboard.py processes have exited!
to_remote_q, to_servo_q, to_main_q, shutdown = InitArduinoVariables()
remote, servo = None, None
# used in simulation to print the hour of simulation once per simulated hour
prev_simulated_hour = ''
persistent_nearby_aircraft = {} # key = flight number; value = last seen epoch
persistent_path = {}
histogram = {}
# Next up to print is index 0; this is a list of tuples:
# tuple element#1: flag indicating the type of message that this is
# tuple element#2: the message itself
message_queue = []
next_message_time = time.time()
# We repeat the loop every x seconds; this ensures that if the processing time is long,
# we don't wait another x seconds after processing completes
next_loop_time = time.time() + LOOP_DELAY_SECONDS
# These files are read only if the version on disk has been modified more recently
# than the last time it was read
last_dump_json_timestamp = 0
init_timing.append(time.time()) # time 6
WaitUntilKillComplete(already_running_ids)
init_timing.append(time.time()) # time 7
LogTimes(init_timing)
Log('Finishing initialization of %d; starting radio polling loop' % os.getpid())
while (not SIMULATION or SIMULATION_COUNTER < len(DUMP_JSONS)) and not SHUTDOWN_SIGNAL:
last_heartbeat_time = Heartbeat(last_heartbeat_time)
new_configuration = ReadAndParseSettings(CONFIG_FILE)
UpdateRollingLogSize(new_configuration)
CheckForNewFilterCriteria(configuration, new_configuration, message_queue, flights)
configuration = new_configuration
ResetLogs(configuration) # clear the logs if requested
# if this is a SIMULATION, then process every diff dump. But if it isn't a simulation,
# then only read & do related processing for the next dump if the last-modified
# timestamp indicates the file has been updated since it was last read.
tmp_timestamp = 0
if not SIMULATION:
<----SKIPPED LINES---->
|
01234567890123456789012345678901234567890123456789012345678901234567890123456789
323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374 393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437 50895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129 56505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777 |
<----SKIPPED LINES---->
AIRCRAFT_LENGTH['Boeing 737-400 (twin-jet)'] = 36.4
AIRCRAFT_LENGTH['Boeing 737-700 (twin-jet)'] = 33.63
AIRCRAFT_LENGTH['Boeing 737-800 (twin-jet)'] = 39.47
AIRCRAFT_LENGTH['Boeing 737-900 (twin-jet)'] = 42.11
AIRCRAFT_LENGTH['Boeing 747-400 (quad-jet)'] = 36.4
AIRCRAFT_LENGTH['Boeing 747-8 (quad-jet)'] = 76.25
AIRCRAFT_LENGTH['Boeing 757-200 (twin-jet)'] = 47.3
AIRCRAFT_LENGTH['Boeing 757-300 (twin-jet)'] = 54.4
AIRCRAFT_LENGTH['Boeing 767-200 (twin-jet)'] = 48.51
AIRCRAFT_LENGTH['Boeing 767-300 (twin-jet)'] = 54.94
AIRCRAFT_LENGTH['Boeing 777 (twin-jet)'] = (63.73 + 73.86) / 2
AIRCRAFT_LENGTH['Boeing 777-200 (twin-jet)'] = 63.73
AIRCRAFT_LENGTH['Boeing 777-200LR/F (twin-jet)'] = 63.73
AIRCRAFT_LENGTH['Boeing 777-300ER (twin-jet)'] = 73.86
AIRCRAFT_LENGTH['Boeing 787-10 (twin-jet)'] = 68.28
AIRCRAFT_LENGTH['Boeing 787-8 (twin-jet)'] = 56.72
AIRCRAFT_LENGTH['Boeing 787-9 (twin-jet)'] = 62.81
AIRCRAFT_LENGTH['Canadair Regional Jet CRJ-200 (twin-jet)'] = 26.77
AIRCRAFT_LENGTH['Canadair Regional Jet CRJ-700 (twin-jet)'] = 32.3
AIRCRAFT_LENGTH['Canadair Regional Jet CRJ-900 (twin-jet)'] = 36.2
AIRCRAFT_LENGTH['Canadair Challenger (twin-jet)'] = 20.9
AIRCRAFT_LENGTH['Canadair Challenger 350 (twin-jet)'] = 20.9
AIRCRAFT_LENGTH['Bombardier Challenger 300 (twin-jet)'] = 20.92
AIRCRAFT_LENGTH['Bombardier Global Express (twin-jet)'] = (29.5 + 30.3) / 2
AIRCRAFT_LENGTH['Embraer 170/175 (twin-jet)'] = (29.90 + 31.68) / 2
AIRCRAFT_LENGTH['Embraer Phenom 300 (twin-jet)'] = 15.9
AIRCRAFT_LENGTH['EMBRAER 175 (long wing) (twin-jet)'] = 31.68
AIRCRAFT_LENGTH['Embraer ERJ-135 (twin-jet)'] = 26.33
AIRCRAFT_LENGTH['Cessna Caravan (single-turboprop)'] = 11.46
AIRCRAFT_LENGTH['Cessna Citation CJ2+ (twin-jet)'] = 14.53
AIRCRAFT_LENGTH['Cessna Citation CJ3 (twin-jet)'] = 15.59
AIRCRAFT_LENGTH['Cessna Citation Excel/XLS (twin-jet)'] = 16.0
AIRCRAFT_LENGTH['Cessna Citation II (twin-jet)'] = 14.54
AIRCRAFT_LENGTH['Cessna Citation Latitude (twin-jet)'] = 18.97
AIRCRAFT_LENGTH['Cessna Citation Sovereign (twin-jet)'] = 19.35
AIRCRAFT_LENGTH['Cessna Citation V (twin-jet)'] = 14.91
AIRCRAFT_LENGTH['Cessna Citation X (twin-jet)'] = 22.04
AIRCRAFT_LENGTH['Cessna Skyhawk (piston-single)'] = 8.28
AIRCRAFT_LENGTH['Cessna Skylane (piston-single)'] = 8.84
AIRCRAFT_LENGTH['Cessna T206 Turbo Stationair (piston-single)'] = 8.61
AIRCRAFT_LENGTH['Beechcraft Bonanza (33) (piston-single)'] = 7.65
AIRCRAFT_LENGTH['Beechcraft Super King Air 200 (twin-turboprop)'] = 13.31
AIRCRAFT_LENGTH['Beechcraft Super King Air 350 (twin-turboprop)'] = 14.22
AIRCRAFT_LENGTH['Beechcraft King Air 90 (twin-turboprop)'] = 10.82
AIRCRAFT_LENGTH['Learjet 45 (twin-jet)'] = 17.68
AIRCRAFT_LENGTH['Pilatus PC-12 (single-turboprop)'] = 14.4
def Log(message, file=None, rolling=None):
"""Write a message to a logfile along with a timestamp.
Args:
<----SKIPPED LINES---->
f.write(str(datetime.datetime.now(TZ))+'\n')
f.write('\n')
f.write(str(message)+'\n')
except IOError:
Log('Unable to append to ' + file)
if rolling:
existing_log_lines = ReadFile(file).splitlines()
with open(rolling, 'w') as f:
f.write('\n'.join(existing_log_lines[-ROLLING_LOG_SIZE:]))
def UpdateRollingLogSize(configuration):
"""Set the global rolling_log_line_count based on settings file."""
if 'rolling_log_line_count' in configuration:
global ROLLING_LOG_SIZE
ROLLING_LOG_SIZE = configuration['rolling_log_line_count']
def LogTimes(times):
"""Logs elapsed time messages from a list tuples of epochs and identifiers."""
msg = ''
for n, t in enumerate(times[:-1]):
msg += '%.2fs to get from reading %d to reading %s\n' % (
times[n + 1][0] - t[0], t[1], times[n + 1][1])
Log(msg)
def MaintainRollingWebLog(message, max_count, filename=None):
"""Maintains a rolling text file of at most max_count printed messages.
Newest data at top and oldest data at the end, of at most max_count messages,
where the delimiter between each message is identified by a special fixed string.
Args:
message: text message to prepend to the file.
max_count: maximum number of messages to keep in the file; the max_count+1st message
is deleted.
filename: the file to update.
"""
# can't define as a default parameter because ROLLING_MESSAGE_FILE name is potentially
# modified based on SIMULATION flag
if not filename:
filename = ROLLING_MESSAGE_FILE
rolling_log_header = '='*(SPLITFLAP_CHARS_PER_LINE + 2)
<----SKIPPED LINES---->
args=(to_servo_q, to_main_q, shutdown[1]))
return remote, servo
def ValidateSingleRunning(enabled, start_function, p=None, args=()):
"""Restarts a new instance of multiprocessing process if not running"""
if not SHUTDOWN_SIGNAL:
if not enabled:
if p is not None: # must have just requested a disabling of single instance
args[2].value = 1 # trigger a shutdown on the single instance
return None
if p is None or not p.is_alive():
if p is None:
Log('Process for %s starting for first time' % str(start_function))
elif VERBOSE:
Log('Process (%s) for %s died; restarting' % (str(p), str(start_function)))
args[2].value = 0 # (re)set shutdown flag to allow function to run
p = multiprocessing.Process(target=start_function, args=args)
p.daemon = True
p.start()
return p
def EnqueueArduinos(flights, json_desc_dict, configuration, to_servo_q, to_remote_q):
"""Send latest data to arduinos via their shared-memory queues"""
last_flight = {}
if flights:
last_flight = flights[-1]
if SIMULATION:
now = json_desc_dict['now']
else:
now = time.time()
additional_attributes = {}
today = EpochDisplayTime(now, '%x')
flight_count_today = len([1 for f in flights if DisplayTime(f, '%x') == today])
<----SKIPPED LINES---->
global VERSION_ARDUINO
VERSION_MESSAGEBOARD = MakeCopy('messageboard')
VERSION_ARDUINO = MakeCopy('arduino')
def main():
"""Traffic cop between incoming radio flight messages, configuration, and messageboard.
This is the main logic, checking for new flights, augmenting the radio signal with
additional web-scraped data, and generating messages in a form presentable to the
messageboard.
"""
VersionControl()
# Since this clears log files, it should occur first before we start logging
if '-s' in sys.argv:
global SIMULATION_COUNTER
SimulationSetup()
last_heartbeat_time = HeartbeatRestart()
init_timing = [(time.time(), 0)]
# This flag slows down simulation time around a flight, great for debugging the arduinos
simulation_slowdown = bool('-f' in sys.argv)
# Redirect any errors to a log file instead of the screen, and add a datestamp
if not SIMULATION:
sys.stderr = open(STDERR_FILE, 'a')
Log('', STDERR_FILE)
init_timing.append((time.time(), 1))
Log('Starting up process %d' % os.getpid())
already_running_ids = FindRunningParents()
if already_running_ids:
for pid in already_running_ids:
Log('Sending termination signal to %d' % pid)
os.kill(pid, signal.SIGTERM)
init_timing.append((time.time(), 2))
SetPinMode()
configuration = ReadAndParseSettings(CONFIG_FILE)
UpdateRollingLogSize(configuration)
startup_time = time.time()
json_desc_dict = {}
init_timing.append((time.time(), 3))
flights = UnpickleObjectFromFile(PICKLE_FLIGHTS, True, max_days=MAX_INSIGHT_HORIZON_DAYS)
# Clear the loaded flight of any cached data, identified by keys with a specific
# suffix, since code fixes may change the values for some of those cached elements
for flight in flights:
for key in list(flight.keys()):
if key.endswith(CACHED_ELEMENT_PREFIX):
flight.pop(key)
init_timing.append((time.time(), 4))
# If we're displaying just a single insight message, we want it to be something
# unique, to the extent possible; this dict holds a count of the diff types of messages
# displayed so far
insight_message_distribution = {}
# bootstrap the flight insights distribution from a list of insights on each
# flight (i.e.: flight['insight_types'] for a given flight might look like
# [1, 2, 7, 9], or [], to indicate which insights were identified; this then
# transforms that into {0: 25, 1: 18, ...} summing across all flights.
missing_insights = []
for flight in flights:
if 'insight_types' not in flight:
missing_insights.append(
'%s on %s' % (DisplayFlightNumber(flight), DisplayTime(flight, '%x %X')))
distribution = flight.get('insight_types', [])
for key in distribution:
insight_message_distribution[key] = (
insight_message_distribution.get(key, 0) + 1)
if missing_insights:
Log('Flights missing insight distributions: %s' % ';'.join(missing_insights))
init_timing.append((time.time(), 5))
# initialize objects required for arduinos, but we can only start them in the main
# loop, because the tail end of the init section needs to confirm that all other
# messageboard.py processes have exited!
to_remote_q, to_servo_q, to_main_q, shutdown = InitArduinoVariables()
remote, servo = None, None
# used in simulation to print the hour of simulation once per simulated hour
prev_simulated_hour = ''
persistent_nearby_aircraft = {} # key = flight number; value = last seen epoch
persistent_path = {}
histogram = {}
# Next up to print is index 0; this is a list of tuples:
# tuple element#1: flag indicating the type of message that this is
# tuple element#2: the message itself
message_queue = []
next_message_time = time.time()
# We repeat the loop every x seconds; this ensures that if the processing time is long,
# we don't wait another x seconds after processing completes
next_loop_time = time.time() + LOOP_DELAY_SECONDS
# These files are read only if the version on disk has been modified more recently
# than the last time it was read
last_dump_json_timestamp = 0
init_timing.append((time.time(), 6))
WaitUntilKillComplete(already_running_ids)
init_timing.append((time.time(), 7))
LogTimes(init_timing)
Log('Finishing initialization of %d; starting radio polling loop' % os.getpid())
while (not SIMULATION or SIMULATION_COUNTER < len(DUMP_JSONS)) and not SHUTDOWN_SIGNAL:
last_heartbeat_time = Heartbeat(last_heartbeat_time)
new_configuration = ReadAndParseSettings(CONFIG_FILE)
UpdateRollingLogSize(new_configuration)
CheckForNewFilterCriteria(configuration, new_configuration, message_queue, flights)
configuration = new_configuration
ResetLogs(configuration) # clear the logs if requested
# if this is a SIMULATION, then process every diff dump. But if it isn't a simulation,
# then only read & do related processing for the next dump if the last-modified
# timestamp indicates the file has been updated since it was last read.
tmp_timestamp = 0
if not SIMULATION:
<----SKIPPED LINES---->
|