Ejemplo n.º 1
0
class GearmanIn(Actor):
    '''**Consumes events/jobs from  Gearmand.**

    Consumes jobs from a Gearmand server.
    When secret is none, no decryption is done.


    Parameters:

        - hostlist(list)(["localhost:4730"])
           |  A list of gearmand servers.  Each entry should have
           |  format host:port.

        - secret(str)(None)
           |  The AES encryption key to decrypt Mod_gearman messages.

        - workers(int)(1)
           |  The number of gearman workers within 1 process.

        - queue(str)(wishbone)
           |  The queue to consume jobs from.

        - enable_keepalive(bool)(False)
           |  Attempt to monkey patch the gearmand module to enable socket
           |  keepalive.


    Queues:

        - outbox:   Outgoing events.

    '''
    def __init__(self,
                 actor_config,
                 hostlist=["localhost:4730"],
                 secret=None,
                 workers=1,
                 queue="wishbone",
                 enable_keepalive=False):
        Actor.__init__(self, actor_config)

        self.pool.createQueue("outbox")
        self.background_instances = []

        if self.kwargs.secret is None:
            self.decrypt = self.__plainTextJob
        else:
            key = self.kwargs.secret[0:32]
            self.cipher = AES.new(key + chr(0) * (32 - len(key)))
            self.decrypt = self.__encryptedJob

    def preHook(self):

        if self.kwargs.enable_keepalive:
            self.logging.info("Requested to monkey patch Gearmand")
            if gearman_version == "2.0.2":
                self.logging.info(
                    "Detected gearman version 2.0.2, patching sockets with SO_KEEPALIVE enabled."
                )
                self.gearmanWorker = self._gearmanWorkerPatched
            else:
                self.logging.warning(
                    "Did not detect gearman version 2.0.2. Not patching , patching sockets with keepalive enabled."
                )
                self.gearmanWorker = self._gearmanWorkerNotPatched
        else:
            self.gearmanWorker = self._gearmanWorkerNotPatched

        for _ in range(self.kwargs.workers):
            self.sendToBackground(self.gearmanWorker)

        self.sendToBackground(self.monitor)

    def consume(self, gearman_worker, gearman_job):

        decrypted = self.decrypt(gearman_job.data)
        event = Event(decrypted)
        self.submit(event, self.pool.queue.outbox)
        return gearman_job.data

    def __encryptedJob(self, data):
        return self.cipher.decrypt(base64.b64decode(data))

    def __plainTextJob(self, data):
        return data

    def _gearmanWorkerPatched(self):

        self.logging.info("Gearmand worker instance started")
        while self.loop():
            try:
                with mock.patch.object(GearmanConnection,
                                       '_create_client_socket',
                                       create_client_socket):
                    self.worker_instance = GearmanWorker(self.kwargs.hostlist)
                    self.worker_instance.register_task(self.kwargs.queue,
                                                       self.consume)
                    self.worker_instance.work()
            except Exception as err:
                self.logging.warn(
                    "Connection to gearmand failed. Reason: '%s'. Retry in 1 second."
                    % err)
                sleep(1)
            finally:
                self.worker_instance.shutdown()

    def _gearmanWorkerNotPatched(self):

        self.logging.info("Gearmand worker instance started")
        while self.loop():
            try:
                self.worker_instance = GearmanWorker(self.kwargs.hostlist)
                self.worker_instance.register_task(self.kwargs.queue,
                                                   self.consume)
                self.worker_instance.work()
            except Exception as err:
                self.logging.warn(
                    "Connection to gearmand failed. Reason: '%s'. Retry in 1 second."
                    % err)
                sleep(1)
            finally:
                self.worker_instance.shutdown()

    def monitor(self):

        self.logging.info("Connection monitor started.")
        while self.loop():
            sleep(5)
            for conn in self.worker_instance.connection_list:
                if not conn.connected:
                    self.logging.error(
                        "Connection to '%s' is dead.  Trying to reconnect." %
                        (conn.gearman_host))
                    try:
                        conn.connect()
                        self.logging.info("Connection to '%s' is restored." %
                                          (conn.gearman_host))
                    except Exception as err:
                        self.logging.error(
                            "Failed to reconnect to '%s'. Retry in 5 seconds. Reason: '%s'"
                            % (conn.gearman_host, err))
                else:
                    self.logging.debug("Connection to '%s' is alive." %
                                       (conn.gearman_host))
Ejemplo n.º 2
0
        return False


def task_listener(gearman_worker, gearman_job):
    task_name, video_id, segment_id = pickle.loads(gearman_job.data)
    result = False

    if task_name == 'transcode':
        result = transcode_segment(video_id, segment_id)
    elif task_name == 'thumbnail':
        result = generate_thumbnail(video_id, segment_id)

    return pickle.dumps(result)


if __name__ == "__main__":
    # worker run

    logger.info("Setting up the worker.")
    gm_worker = GearmanWorker([GEARMAND_HOST_PORT])
    gm_worker.register_task(SEGMENT_TASK_NAME, task_listener)

    try:
        logger.info("Worker was set up successfully. Waiting for work.")
        gm_worker.work()

    except KeyboardInterrupt:
        gm_worker.shutdown()
        logger.info("Worker has shut down successfully. Bye.")
        return False


def task_listener(gearman_worker, gearman_job):
    task_name, video_id, segment_id = pickle.loads(gearman_job.data)
    result = False

    if task_name == 'transcode':
        result = transcode_segment(video_id, segment_id)
    elif task_name == 'thumbnail':
        result = generate_thumbnail(video_id, segment_id)

    return pickle.dumps(result)


if __name__ == "__main__":
    # worker run

    logger.info("Setting up the worker.")
    gm_worker = GearmanWorker([GEARMAND_HOST_PORT])
    gm_worker.register_task(SEGMENT_TASK_NAME, task_listener)

    try:
        logger.info("Worker was set up successfully. Waiting for work.")
        gm_worker.work()

    except KeyboardInterrupt:
        gm_worker.shutdown()
        logger.info("Worker has shut down successfully. Bye.")
Ejemplo n.º 4
0
class GearmanIn(Actor):

    '''**Consumes events/jobs from  Gearmand.**

    Consumes jobs from a Gearmand server.
    When secret is none, no decryption is done.


    Parameters:

        - hostlist(list)(["localhost:4730"])
           |  A list of gearmand servers.  Each entry should have
           |  format host:port.

        - secret(str)(None)
           |  The AES encryption key to decrypt Mod_gearman messages.

        - workers(int)(1)
           |  The number of gearman workers within 1 process.

        - queue(str)(wishbone)
           |  The queue to consume jobs from.

        - enable_keepalive(bool)(False)
           |  Attempt to monkey patch the gearmand module to enable socket
           |  keepalive.


    Queues:

        - outbox:   Outgoing events.

    '''

    def __init__(self, actor_config, hostlist=["localhost:4730"], secret=None, workers=1, queue="wishbone", enable_keepalive=False):
        Actor.__init__(self, actor_config)

        self.pool.createQueue("outbox")
        self.background_instances = []

        if self.kwargs.secret is None:
            self.decrypt = self.__plainTextJob
        else:
            key = self.kwargs.secret[0:32]
            self.cipher = AES.new(key + chr(0) * (32 - len(key)))
            self.decrypt = self.__encryptedJob

    def preHook(self):

        if self.kwargs.enable_keepalive:
            self.logging.info("Requested to monkey patch Gearmand")
            if gearman_version == "2.0.2":
                self.logging.info("Detected gearman version 2.0.2, patching sockets with SO_KEEPALIVE enabled.")
                self.gearmanWorker = self._gearmanWorkerPatched
            else:
                self.logging.warning("Did not detect gearman version 2.0.2. Not patching , patching sockets with keepalive enabled.")
                self.gearmanWorker = self._gearmanWorkerNotPatched
        else:
            self.gearmanWorker = self._gearmanWorkerNotPatched

        for _ in range(self.kwargs.workers):
            self.sendToBackground(self.gearmanWorker)

        self.sendToBackground(self.monitor)

    def consume(self, gearman_worker, gearman_job):

        decrypted = self.decrypt(gearman_job.data)
        event = Event(decrypted)
        self.submit(event, self.pool.queue.outbox)
        return gearman_job.data

    def __encryptedJob(self, data):
        return self.cipher.decrypt(base64.b64decode(data))

    def __plainTextJob(self, data):
        return data

    def _gearmanWorkerPatched(self):

        self.logging.info("Gearmand worker instance started")
        while self.loop():
            try:
                with mock.patch.object(GearmanConnection, '_create_client_socket', create_client_socket):
                    self.worker_instance = GearmanWorker(self.kwargs.hostlist)
                    self.worker_instance.register_task(self.kwargs.queue, self.consume)
                    self.worker_instance.work()
            except Exception as err:
                self.logging.warn("Connection to gearmand failed. Reason: '%s'. Retry in 1 second." % err)
                sleep(1)
            finally:
                self.worker_instance.shutdown()

    def _gearmanWorkerNotPatched(self):

        self.logging.info("Gearmand worker instance started")
        while self.loop():
            try:
                self.worker_instance = GearmanWorker(self.kwargs.hostlist)
                self.worker_instance.register_task(self.kwargs.queue, self.consume)
                self.worker_instance.work()
            except Exception as err:
                self.logging.warn("Connection to gearmand failed. Reason: '%s'. Retry in 1 second." % err)
                sleep(1)
            finally:
                self.worker_instance.shutdown()

    def monitor(self):

        self.logging.info("Connection monitor started.")
        while self.loop():
            sleep(5)
            for conn in self.worker_instance.connection_list:
                if not conn.connected:
                    self.logging.error("Connection to '%s' is dead.  Trying to reconnect." % (conn.gearman_host))
                    try:
                        conn.connect()
                        self.logging.info("Connection to '%s' is restored." % (conn.gearman_host))
                    except Exception as err:
                        self.logging.error("Failed to reconnect to '%s'. Retry in 5 seconds. Reason: '%s'" % (conn.gearman_host, err))
                else:
                    self.logging.debug("Connection to '%s' is alive." % (conn.gearman_host))