Beispiel #1
0
 def _fill_work_queue(self):
     log.cc(1, "Starting to fill task queue...")
     for pathToMeasure in self._pathsToMeasure:
         if self._check_command():
             self._folderWalker.walk(pathToMeasure)
     if self._check_command() and self._workPackage.size_items() > 0:
         self._send_current_package()
Beispiel #2
0
 def _wait_output_finish(self):
     log.cc(1, "Workers finished, waiting for output to finish...")
     self._send_output_command('WORK_DONE')
     while self._check_command() or self._outThread.is_alive():
         self._outThread.join(JOB_EXIT_TIMEOUT)
         self._status_callback()
         self._continueProcessing = not bool(self._controlQueue.empty())
Beispiel #3
0
    def _run(self):
        # Keep processing queue until the job signals it is done and
        # the queue is empty, or receive an abort command
        while self._continue_processing():
            try:
                if self._workDone and self._outQueue.empty():
                    break
                filesOutput = self._outQueue.get_nowait()

            except Empty:
                log.cc(3, "EMPTY OUTPUT")
                time.sleep(OUTPUT_EMPTY_WAIT)
            else:
                self.taskPackagesReceived += 1
                log.cc(2, "GOT {} measures".format(len(filesOutput)))

                # Get a set of output for multiple files with each outputQueue item.
                # Each file has a set of output and errors to pack up for app
                for filePath, outputList, errorList in filesOutput:

                    # Synchronus callback to applicaiton
                    # Output writing and screen update occurs in this call
                    self._file_measure_callback(filePath, outputList,
                                                errorList)

                    if errorList:
                        log.file(1, "ERROR measuring: {}".format(filePath))
                        self._controlQueue.put_nowait(
                            ('JOB', 'ERROR', filePath))
Beispiel #4
0
    def _continue_processing(self):
        continueProcessing = True
        otherCommands = []
        myCommand = None
        try:
            while True:
                (target, command, payload) = self._controlQueue.get_nowait()
                log.cc(3, "command - {}, {}".format(target, command))
                if target == self.name:
                    myCommand = command
                    break
                else:
                    otherCommands.append((target, command, payload))
        except Empty:
            pass
        finally:
            if 'EXIT' == myCommand:
                log.cc(2, "COMMAND: EXIT")
                continueProcessing = False

            elif 'WORK_DONE' == myCommand:
                log.cc(2, "COMMAND: WORK_DONE")
                self._workDone = True

            if otherCommands:
                log.cc(4, "replacing conmmands - {}".format(otherCommands))
                utils.put_commands(self._controlQueue, otherCommands,
                                   CONTROL_QUEUE_TIMEOUT)

        return continueProcessing
Beispiel #5
0
 def _send_current_package(self):
     '''
     Place package of work on queue, and start a worker
     '''
     self._workers.start_next()
     log.cc(
         2, "PUT WorkPackage - files: {}, bytes: {}...".format(
             self._workPackage.size_items(),
             self._workPackage.size_bytes()))
     log.cc(4, list(self._workPackage.items()))
     try:
         self._taskQueue.put(list(self._workPackage.items()), True,
                             TASK_FULL_TIMEOUT)
     except Full:
         raise utils.JobException("FATAL ERROR -- FULL TASK QUEUE")
     else:
         self._taskPackagesSent += 1
         self._filesSinceLastSend = 0
         self._workPackage.reset()
Beispiel #6
0
    def __init__(self, outQueue, controlQueue, profileName,
                 file_measure_callback):
        log.cc(1, "Creating output queue thread")
        threading.Thread.__init__(self, name="Out")
        self._profileName = profileName

        # The main thread manages our life; if something gets truly out of
        # sync care more about exiting than ensuring output is flushed
        self.daemon = True

        # The main thread owns our queues
        self._outQueue = outQueue
        self._controlQueue = controlQueue
        self._file_measure_callback = file_measure_callback

        # Total task output packages we've received from all processes
        self.taskPackagesReceived = 0

        # Flag to track when receive WORK_DONE from the Job
        self._workDone = False
Beispiel #7
0
    def _put_files_in_queue(self, path, deltaPath, filesAndConfigs):
        '''
        Package files from the path into workItems that are grouped
        into workPackages and placed into the task queue for jobworkers.
        Packages are broken up if files number or total size exceeds
        thresholds to help evenly distribute load across cores
        '''
        if not filesAndConfigs:
            return

        for fileName, configEntrys in filesAndConfigs:

            # Expensive to check file size here, but worth it for pracelling widely
            # varying file sizes out to cores for CPU intensive jobs.
            # Profiling shows it is not worth caching this
            try:
                fileSize = utils.get_file_size(os.path.join(path, fileName))
            except Exception as e:
                # It is possible (at least in Windows) for a fileName to exist
                # in the file system but be invalid for Windows calls. This is
                # the first place the file is accessed through the file system;
                # if it blows up don't want the job to fall apart, and this is
                # an unusual case, so don't bother with a pathway back to the main
                # application; just swallow it and provide debug
                log.msg(1, str(e))
                log.stack()
                continue

            log.cc(3, "WorkItem: {}, {}".format(fileSize, fileName))
            self.numFilesToProcess += 1
            workItem = (path, deltaPath, fileName, configEntrys, self._options,
                        len(filesAndConfigs))
            self._workPackage.add(workItem, fileSize)

            if self._workPackage.ready_to_send() or (self._filesSinceLastSend >
                                                     MAX_FILES_BEFORE_SEND):
                self._send_current_package()

            if not self._check_command():
                break
Beispiel #8
0
    def _check_command(self):
        '''
        Check command queue for any problems posted while running a job
        Exceptions received from the command queue are unpackaged 
        and thrown for main to handle
        '''
        otherCommands = []
        try:
            while self._continueProcessing:
                (target, command, payload) = self._controlQueue.get_nowait()
                log.cc(4, "command check: {}, {}".format(target, command))
                if target == 'JOB':
                    if 'ERROR' == command:
                        # Error notifications in the control queue are only used to support
                        # break on error -- the error info is handled by the output queue.
                        log.cc(1,
                               "COMMAND: ERROR for file: {}".format(payload))
                        if self._options.breakOnError:
                            self._continueProcessing = False
                    elif 'EXCEPTION' == command:
                        # Exceptions are bundled up for display to user
                        log.cc(1, "COMMAND: EXCEPTION RECEIVED")
                        if self._options.breakOnError:
                            self._continueProcessing = False
                        self.exceptions.append(payload)
                else:
                    otherCommands.append((target, command, payload))
        except Empty:
            log.cc(4, "command check: empty")
        finally:
            # Put any queue items removed back in the queue
            for (target, command, payload) in otherCommands:
                log.cc(4, "command replace: {}, {}".format(target, command))
                self._controlQueue.put_nowait((target, command, payload))

        return self._continueProcessing
Beispiel #9
0
    def run(self):
        log.cc(1, "STARTING: Begining to process output queue...")
        try:
            if self._profileName is not None:
                import cProfile
                cProfile.runctx('self._run()', globals(), {'self': self},
                                self._profileName + self.name)
            else:
                self._run()
            log.cc(1, "FINISHED processing output queue")

        except KeyboardInterrupt:
            log.cc(1, "Ctrl-c occurred in OUTPUT THREAD")
            _thread.interrupt_main()
        except Exception as e:
            log.msg(1, "EXCEPTION processing output queue: " + str(e))
            log.stack()
            self._controlQueue.put_nowait(('JOB', 'EXCEPTION', e))
        finally:
            log.cc(1, "TERMINATING")
Beispiel #10
0
 def _wait_then_exit(self):
     log.cc(1, "Waiting to cleanup workers and output thread...")
     self._send_workers_command('EXIT')
     self._send_output_command('EXIT')
     for worker in self._workers():
         tries = 0
         while worker.is_alive() and tries < WORKER_EXIT_TRIES:
             self._status_callback()
             worker.join(WORKER_EXIT_TIMEOUT)
             log.cc(
                 2, "Worker {} is_alive: {}".format(worker.name,
                                                    worker.is_alive()))
             self._check_command()
             tries += 1
     self._outThread.join(JOB_EXIT_TIMEOUT)
     self._close_queues()
     log.cc(1, "TERMINATING")
Beispiel #11
0
 def _send_command(self, target, command, payload):
     log.cc(2, "COMMAND:  {}, {} {}".format(target, command, payload))
     self._controlQueue.put_nowait((target, command, payload))
Beispiel #12
0
 def _wait_process_packages(self):
     log.cc(1, "Task queue complete, waiting for workers to finish...")
     while self._check_command() and self._task_queue_size() > 0:
         time.sleep(MAIN_PROCESSING_SLEEP)
         self._status_callback()
         log.cc(2, "Task queue size: " + str(self._task_queue_size()))