Esempio n. 1
0
    def requestAvatar(self, avatarID, mind, *interfaces):
        assert pb.IPerspective in interfaces

        key_split = avatarID.split(':')
        node = Node.objects.get(host=key_split[0], port=key_split[1])
        avatar = WorkerAvatar(avatarID, self.server, node)
        avatar.attached(mind)
        logger.info('worker:%s - connected' % avatarID)

        return pb.IPerspective, avatar, lambda a=avatar:a.detached(mind)
Esempio n. 2
0
    def _run_task(self, key, version, task_class, module_search_path, \
            worker_key, args={}, workunits=None, main_worker=None, task_id=None):
        """
        Runs a task on this node.  The worker scheduler on master makes all
        decisions about which worker to run on.  This method only checks
        to see if the worker is already running or not.  This is a very
        explicit and deliberate division of repsonsibility.  Allowing
        decisions here dilutes the ability of the Master to control the
        cluster

        @param key - task key
        @param version - version of task to run
        @param task_class - task class to be created TODO why is this here?
        @param module_search_path - TODO why is this here?
        @param worker_key - key of worker to run task on
        @param args - args for task
        @param subtask_key - key of subtask to run
        @param workunit_key - key of workunit to run
        @param main_worker - main worker for this task
        @param task_id - id of task being run
        """
        logger.info('RunTask:%s  key=%s  sub=%s  main=%s' \
            % (task_id, key, workunits, main_worker))
        worker = None

        with self.__lock:
            if worker_key in self.workers:
                # worker exists.  reuse it.
                logger.debug('RunTask - Using existing worker %s' % worker_key)
                worker = self.workers[worker_key]
                worker.run_task_deferred = worker.remote.callRemote('run_task',\
                        key, version, args, workunits, main_worker, task_id)
            else:
                # worker not running. start it saving the information required
                # to start the subtask.  This function will return a deferred
                # to the master.  The deferred will be
                logger.debug('RunTask - Spawning worker: %s', worker_key)
                worker = WorkerAvatar(self.worker_connection_manager, \
                                                            worker_key)
                worker.worker_key = worker_key
                worker.run_task_deferred = Deferred()
                pydra_root = pydra.__file__[:pydra.__file__.rfind('/')]
                try:
                    worker.popen = Popen(['python',
                                '%s/cluster/worker/worker.py' % pydra_root,
                                worker_key,
                                pydra_settings.WORKER_PORT.__str__()])
                except OSError:
                    # XXX ocassionally processes will have a communcation error
                    # while loading.  The process will be running but the POpen
                    # object is not constructed.  This means that we have no
                    # access to the subprocess functions.  Instead we must get
                    # the pid from the newly run process after it starts.  The
                    # pid can then be used instead of the Popen object.
                    #
                    # relevant bugs:
                    #    http://pydra-project.osuosl.org/ticket/158
                    #    http://bugs.python.org/issue1068268
                    debug.warn('OSError while spawning process, failing back to pid. see ticket #158')
                    worker.run_task_deferred.addCallback(worker.get_pid)
                self.workers[worker_key] = worker

            worker.key = key
            worker.version = version
            worker.args = args
            worker.main_worker = main_worker
            worker.task_id=task_id
            if worker_key == main_worker:
                worker.local_workunits = workunits
            else:
                worker.workunits = workunits

            return worker.run_task_deferred