コード例 #1
0
    def run_tasks(self, queue, parallel=True, show_progress=True):
        '''this run_tasks function takes a list of Task objects, each
           potentially a different kind of task, and extracts the parameters
           with task.export_params(), and the running function with 
           task.export_func(), and hands these over to the multiprocessing
           worker. It's up to the Task to return some correct function
           from it's set of task functions that correspond with the variables.

           Examples
           ========

           funcs
           {'task-reddit-hpc': <function watchme.watchers.urls.tasks.get_task>}

           tasks
           {'task-reddit-hpc': [('url', 'https://www.reddit.com/r/hpc'),
                                ('active', 'true'),
                                ('type', 'urls')]}
        '''
        if parallel is True:
            return self._run_parallel(queue, show_progress)

        # Otherwise, run in serial
        results = {}

        # Progressbar
        total = len(queue)
        progress = 1

        for task in queue:
            prefix = "[%s:%s/%s]" % (task.name, progress, total)
            if show_progress is True:
                bot.show_progress(progress, total, length=35, prefix=prefix)
            else:
                bot.info('Running %s' % prefix)
            results[task.name] = task.run()
            progress += 1

        return results
コード例 #2
0
    def run(self, funcs, tasks):
        '''run will send a list of tasks, a tuple with arguments, through a function.
           the arguments should be ordered correctly.
        
           Parameters
           ==========
           funcs: the functions to run with multiprocessing.pool, a dictionary
                  with lookup by the task name
           tasks: a dict of tasks, each task name (key) with a 
                  tuple of arguments to process
        '''
        # Number of tasks must == number of functions
        assert (len(funcs) == len(tasks))

        # Keep track of some progress for the user
        progress = 1
        total = len(tasks)

        # if we don't have tasks, don't run
        if len(tasks) == 0:
            return

        # results will also have the same key to look up
        finished = dict()
        results = []

        try:
            prefix = "[%s/%s]" % (progress, total)
            if self.show_progress:
                bot.show_progress(0, total, length=35, prefix=prefix)
            pool = multiprocessing.Pool(self.workers, init_worker)

            self.start()
            for key, params in tasks.items():
                func = funcs[key]
                if not self.show_progress:
                    bot.info('Processing task %s:%s' % (key, params))
                result = pool.apply_async(multi_wrapper,
                                          multi_package(func, [params]))

                # Store the key with the result
                results.append((key, result))

            while len(results) > 0:
                pair = results.pop()
                key, result = pair
                result.wait()
                if self.show_progress:
                    bot.show_progress(progress,
                                      total,
                                      length=35,
                                      prefix=prefix)
                progress += 1
                prefix = "[%s/%s]" % (progress, total)
                finished[key] = result.get()

            self.end()
            pool.close()
            pool.join()

        except (KeyboardInterrupt, SystemExit):
            bot.error("Keyboard interrupt detected, terminating workers!")
            pool.terminate()
            sys.exit(1)

        except Exception as e:
            bot.error(e)

        return finished