@@ -73,6 +73,8 @@ def __init__(self, credentials_path='credentials.json', rerun_key=None, multi_th
7373 if host is not None :
7474 self .host = host
7575
76+ self .pid = os .getpid ()
77+
7678 self .api_client = ApiClient (self .credentials_path , self .host , self .http_proto )
7779
7880 self .store = Store ()
@@ -566,9 +568,11 @@ def _process_task(self, payload):
566568 self .store .batches [batch_index ]["submissions" ][task_group_id ] += 1
567569
568570 if stream :
569- self ._stream_response (batch_index , task_id , task_group_id , task_data , approve , completed )
571+ self ._stream_response (batch_index , task_id , task_group_id , taskworker_id , task_data , approve ,
572+ completed )
570573 else :
571- self ._aggregate_responses (batch_index , task_id , task_group_id , task_data , approve , completed )
574+ self ._aggregate_responses (batch_index , task_id , task_group_id , taskworker_id , task_data , approve ,
575+ completed )
572576
573577 self .check_for_pending_tasks_reviews ()
574578 else :
@@ -598,17 +602,17 @@ def check_for_pending_tasks_reviews(self):
598602 def _review_completed (self , project_key , ratings , ignore_history = True ):
599603 self .rate (project_key , ratings , ignore_history = ignore_history )
600604
601- def _stream_response (self , batch_index , task_id , task_group_id , task_data , approve , completed ):
605+ def _stream_response (self , batch_index , task_id , task_group_id , taskworker_id , task_data , approve , completed ):
602606 log .info (msg = "streaming responses..." )
603607
604608 log .info (msg = "calling approve callback..." )
605609
606610 if approve ([task_data ]):
607611 task_data ["accept" ] = True
608- log .info (msg = "task %d approved" % task_id )
612+ log .info (msg = "task worker %d approved" % taskworker_id )
609613 else :
610614 task_data ["accept" ] = False
611- log .info (msg = "task %d rejected" % task_id )
615+ log .info (msg = "task worker %d rejected" % taskworker_id )
612616
613617 # reverse increment as rejection will create another task
614618 self .store .batches [batch_index ]["submissions" ][task_group_id ] -= 1
@@ -624,11 +628,11 @@ def _stream_response(self, batch_index, task_id, task_group_id, task_data, appro
624628 if is_done :
625629 self .store .mark_task_completed (batch_index , task_id , task_group_id )
626630
627- def _aggregate_responses (self , batch_index , task_id , task_group_id , task_data , approve , completed ):
631+ def _aggregate_responses (self , batch_index , task_id , task_group_id , taskworker_id , task_data , approve , completed ):
628632 log .info (msg = "aggregating responses..." )
629633
630634 # store it for aggregation (stream = False)
631- self .store .aggregate (batch_index , task_id , task_group_id , task_data )
635+ self .store .aggregate (batch_index , task_id , task_group_id , taskworker_id , task_data )
632636
633637 is_done = self .store .is_task_complete (batch_index , task_id , task_group_id )
634638
@@ -638,44 +642,52 @@ def _aggregate_responses(self, batch_index, task_id, task_group_id, task_data, a
638642 is_done = self .store .is_batch_complete (batch_index )
639643
640644 if is_done :
641- self .store . mark_batch_completed (batch_index )
645+ self ._on_batch_complete (batch_index , approve , completed )
642646
643- tasks_data = self .store .get_aggregated (batch_index )
647+ def _on_batch_complete (self , batch_index , approve , completed ):
648+ self .store .mark_batch_completed (batch_index )
644649
645- log .info (msg = "calling approve callback..." )
646- approvals = approve (tasks_data )
650+ tasks_data = self .store .get_aggregated (batch_index )
647651
648- tasks_approvals = zip (tasks_data , approvals )
652+ log .info (msg = "calling approve callback..." )
653+ approvals = approve (tasks_data )
649654
650- for task_approval in tasks_approvals :
651- task_data = task_approval [0 ]
652- approval = task_approval [1 ]
655+ tasks_approvals = zip (tasks_data , approvals )
653656
654- task_data ["accept" ] = approval
657+ for task_approval in tasks_approvals :
658+ task_data = task_approval [0 ]
659+ approval = task_approval [1 ]
655660
656- if approval :
657- log .info (msg = "task %d approved" % task_data .get ("task_id" ))
658- else :
659- log .info (msg = "task %d rejected" % task_data .get ("task_id" ))
660- self .store .batches [batch_index ]["submissions" ][task_group_id ] -= 1
661- self .store .mark_task_incomplete (batch_index , task_group_id )
662- self .store .mark_batch_incomplete (batch_index )
661+ task_data ["accept" ] = approval
663662
664- self .api_client .update_approval_status (task_data )
663+ if approval :
664+ log .info (msg = "task worker %d approved" % task_data .get ("taskworker_id" ))
665+ else :
666+ log .info (msg = "task worker %d rejected" % task_data .get ("taskworker_id" ))
667+ self .store .mark_task_incomplete (
668+ batch_index ,
669+ task_data .get ("task_id" ),
670+ task_data .get ("task_group_id" )
671+ )
672+ self .store .mark_batch_incomplete (batch_index )
665673
666- is_done = self .store . is_batch_complete ( batch_index )
674+ self .api_client . update_approval_status ( task_data )
667675
668- if is_done :
669- approved_tasks = [x [0 ] for x in zip (tasks_data , approvals ) if x [1 ]]
676+ is_done = self .store .is_batch_complete (batch_index )
670677
671- log .info (msg = "calling completed callback..." )
672- completed (approved_tasks )
678+ if is_done :
679+ approved_tasks = [x [0 ] for x in zip (tasks_data , approvals ) if x [1 ]]
680+
681+ log .info (msg = "calling completed callback..." )
682+ completed (approved_tasks )
673683
674684 def _fetch_task (self , task_id ):
675685 data = self .api_client .fetch_task (task_id )
676686 return transform_task (data )
677687
678688 def _open_channel (self ):
689+ signal .signal (signal .SIGINT , self ._handler )
690+
679691 # shared queue between main process and channel for message passing
680692 self .queue = multiprocessing .Queue ()
681693
@@ -687,23 +699,29 @@ def _open_channel(self):
687699 thread = callback_thread (name = 'signal monitor' , target = signal .pause )
688700 thread .start ()
689701
690- signal .signal (signal .SIGINT , self ._handler )
691-
692702 subscribe_url = self .websock_proto + self .host + self .api_client .route .subscribe
693703
694- print "starting channel..."
695704 self .channel = Channel (self .queue , self .api_client , subscribe_url )
696705 self .channel .start ()
697706
698707 def _handler (self , signum , frame ):
708+ forced_closure = signum in [signal .SIGINT , signal .SIGTERM ]
709+
699710 # call this handler to stop the processes definitively
700- if signum in [signal .SIGINT , signal .SIGTERM , signal .SIGABRT ] and os .getpid () == self .channel .pid :
701- self .channel .stop ()
711+ if signum in [signal .SIGINT , signal .SIGTERM , signal .SIGABRT ]:
712+
713+ if self .channel is not None and os .getpid () == self .channel .pid :
714+ # log.warn(msg="closing channel thread")
715+
716+ self .channel .stop (forced_closure )
717+
718+ if self .queue is not None :
719+ self .queue .put (None )
720+ self .queue = None
702721
703- if self .queue is not None :
704- self .queue .put (None )
705- self .queue = None
722+ # if self.pid is not None and os.getpid() == self.pid:
723+ # log.warning(msg="client:closing main thread")
706724
707725 def _stop (self ):
708- log .info (msg = "disconnecting..." )
726+ log .warn (msg = "disconnecting..." )
709727 os .kill (int (self .channel .pid ), signal .SIGINT )
0 commit comments