1818# CDDL HEADER END
1919
2020#
21- # Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
21+ # Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved.
2222#
2323
2424import os
7676
7777expected_token = None
7878
79- sleep_event = threading .Event ()
79+
80+ class PeriodicTimer :
81+ """
82+ Helper class to facilitate waiting for periodic events.
83+ Requires the start() function to be called first.
84+ """
85+ def __init__ (self , interval ):
86+ """
87+ :param interval: interval in seconds
88+ """
89+ self ._interval = interval
90+ self ._flag = 0
91+ self ._cv = threading .Condition ()
92+
93+ def start (self ):
94+ threading .Thread (target = self .run , daemon = True ).start ()
95+
96+ def run (self ):
97+ """
98+ Run the timer and notify waiting threads after each interval
99+ """
100+ while True :
101+ time .sleep (self ._interval )
102+ self .notify_all ()
103+
104+ def wait_for_tick (self ):
105+ """
106+ Wait for the next tick of the timer
107+ """
108+ with self ._cv :
109+ last_flag = self ._flag
110+ while last_flag == self ._flag :
111+ self ._cv .wait ()
112+
113+ def notify_all (self ):
114+ """
115+ Notify all listeners, possibly out of band.
116+ """
117+ with self ._cv :
118+ self ._flag ^= 1
119+ self ._cv .notify_all ()
120+
121+
122+ periodic_timer = None
80123app = Flask (__name__ )
81124auth = HTTPTokenAuth (scheme = 'Bearer' )
82125REINDEX_POINT = '/reindex'
83126
84127
85128def trigger_reindex ():
86129 # Signal the sync/indexer thread.
87- sleep_event .set ()
88- sleep_event .clear ()
130+ periodic_timer .notify_all ()
89131
90132
91133@auth .verify_token
@@ -100,7 +142,7 @@ def verify_token(token):
100142@app .route (REINDEX_POINT )
101143@auth .login_required
102144def index ():
103- trigger_reindex ()
145+ periodic_timer . notify_all ()
104146
105147 return "Reindex triggered"
106148
@@ -193,7 +235,7 @@ def setup_redirect_source(logger, url_root):
193235def wait_for_tomcat (logger , uri ):
194236 """
195237 Active/busy waiting for Tomcat to come up.
196- Currently there is no upper time bound.
238+ Currently, there is no upper time bound.
197239 """
198240 logger .info ("Waiting for Tomcat to start" )
199241
@@ -299,16 +341,7 @@ def indexer_no_projects(logger, uri, config_path, extra_indexer_options):
299341 indexer .execute ()
300342
301343 logger .info ("Waiting for reindex to be triggered" )
302- sleep_event .wait ()
303-
304-
305- def timeout_loop (logger , sync_period ):
306- while True :
307- sleep_seconds = sync_period * 60
308- logger .info ("Sleeping for {} seconds" .format (sleep_seconds ))
309- time .sleep (sleep_seconds )
310-
311- trigger_reindex ()
344+ periodic_timer .wait_for_tick ()
312345
313346
314347def project_syncer (logger , loglevel , uri , config_path , numworkers , env ):
@@ -357,7 +390,7 @@ def project_syncer(logger, loglevel, uri, config_path, numworkers, env):
357390 save_config (logger , uri , config_path )
358391
359392 logger .info ("Waiting for reindex to be triggered" )
360- sleep_event . wait ()
393+ periodic_timer . wait_for_tick ()
361394
362395
363396def create_bare_config (logger , use_projects , extra_indexer_options = None ):
@@ -412,7 +445,7 @@ def check_index_and_wipe_out(logger):
412445 """
413446 Check index by running the indexer. If the index does not match
414447 currently running version and the CHECK_INDEX environment variable
415- is non empty, wipe out the directories under data root.
448+ is non- empty, wipe out the directories under data root.
416449 """
417450 check_index = os .environ .get ('CHECK_INDEX' )
418451 if check_index and os .path .exists (OPENGROK_CONFIG_FILE ):
@@ -430,8 +463,8 @@ def check_index_and_wipe_out(logger):
430463 try :
431464 logger .info ("Removing '{}'" .format (path ))
432465 shutil .rmtree (path )
433- except Exception as e :
434- logger .error ("cannot delete '{}': {}" .format (path , e ))
466+ except Exception as exc :
467+ logger .error ("cannot delete '{}': {}" .format (path , exc ))
435468
436469
437470def start_rest_thread (logger ):
@@ -451,14 +484,6 @@ def start_rest_thread(logger):
451484 rest_thread .start ()
452485
453486
454- def start_timeout_thread (logger , sync_period ):
455- logger .debug ("Starting timeout thread" )
456- thread = threading .Thread (target = timeout_loop ,
457- name = "Timeout thread" ,
458- args = (logger , sync_period ), daemon = True )
459- thread .start ()
460-
461-
462487def main ():
463488 log_level = os .environ .get ('OPENGROK_LOG_LEVEL' )
464489 if log_level :
@@ -479,11 +504,11 @@ def main():
479504 logger .debug ("URL_ROOT = {}" .format (url_root ))
480505 logger .debug ("URI = {}" .format (uri ))
481506
482- sync_period = get_num_from_env (logger , 'SYNC_PERIOD_MINUTES' , 10 )
483- if sync_period == 0 :
507+ sync_period_mins = get_num_from_env (logger , 'SYNC_PERIOD_MINUTES' , 10 )
508+ if sync_period_mins == 0 :
484509 logger .info ("periodic synchronization disabled" )
485510 else :
486- logger .info ("synchronization period = {} minutes" .format (sync_period ))
511+ logger .info ("synchronization period = {} minutes" .format (sync_period_mins ))
487512
488513 # Note that deploy is done before Tomcat is started.
489514 deploy (logger , url_root )
@@ -505,15 +530,15 @@ def main():
505530 use_projects = False
506531
507532 #
508- # Create empty configuration to avoid the non existent file exception
533+ # Create empty configuration to avoid the non- existent file exception
509534 # in the web app during the first web app startup.
510535 #
511536 if not os .path .exists (OPENGROK_CONFIG_FILE ) or \
512537 os .path .getsize (OPENGROK_CONFIG_FILE ) == 0 :
513538 create_bare_config (logger , use_projects , extra_indexer_options .split ())
514539
515540 #
516- # Index check needs read-only configuration so it is placed
541+ # Index check needs read-only configuration, so it is called
517542 # right after create_bare_config().
518543 #
519544 check_index_and_wipe_out (logger )
@@ -579,8 +604,11 @@ def main():
579604 sync_thread .start ()
580605
581606 start_rest_thread (logger )
582- if sync_period > 0 :
583- start_timeout_thread (logger , sync_period )
607+
608+ if sync_period_mins > 0 :
609+ global periodic_timer
610+ periodic_timer = PeriodicTimer (sync_period_mins * 60 )
611+ periodic_timer .start ()
584612
585613 # Start Tomcat last. It will be the foreground process.
586614 logger .info ("Starting Tomcat" )
@@ -595,8 +623,9 @@ def signal_handler(signum, frame):
595623 print ("Received signal {}" .format (signum ))
596624
597625 global tomcat_popen
598- print ("Terminating Tomcat {}" .format (tomcat_popen ))
599- tomcat_popen .terminate ()
626+ if tomcat_popen :
627+ print ("Terminating Tomcat {}" .format (tomcat_popen ))
628+ tomcat_popen .terminate ()
600629
601630 sys .exit (0 )
602631
0 commit comments