def update(self, key, value, size=None, header=None):
     if (size is None):
         if (typeCheck.isBytearray(value)):
             size = len(value)
         else:
             size = asizeof.asizeof(value)
     if (key in self._cache):
         return True
     if (size > self._maxCacheSize):
         log.warning("unable to insert cache value of size {size} MB, max: ({max}) MB", size=size, max=self._maxCacheSize)
         return False
     while ((self.sumSize + size) > self._maxCacheSize):
         self._remove_oldest()
     with self.lock:
         self._cache[key] = {'timestamp': datetime.datetime.now(), 'size': size, 'value': value, 'header': header}
     self.sumSize += size
     return True
    def _stopAlgorithm(self, options):
        if (self._stopped):
            log.warning('Got stop command while already stopping')
        else:
            self._stopped = True
            try:
                method = self._getMethod('stop')
                if (method is not None):
                    method(options)

                forceStop = options.get('forceStop', False)
                if (forceStop is True):
                    log.info('stopping using force flag')
                else:
                    log.info('stopping gracefully')

                if (self._job.isStreaming):
                    if (forceStop is False):
                        stoppingState = True

                        def stopping():
                            while (stoppingState):
                                self._sendCommand(messages.outgoing.stopping,
                                                  None)
                                time.sleep(1)

                        stoppingThread = Thread(target=stopping)
                        stoppingThread.start()
                        self._hkubeApi.stopStreaming(force=forceStop)
                        stoppingState = False
                        stoppingThread.join()
                        log.info(
                            'Joined threads send stopping and stop streaming')
                        self._checkQueueSize(event='scale down')
                    else:
                        self._hkubeApi.stopStreaming(force=forceStop)

                if (self._runningStartThread):
                    self._runningStartThread.join()
                    log.info('Joined threads algorithm and stop algorithm')

                self._sendCommand(messages.outgoing.stopped, None)

            except Exception as e:
                self.sendError(e)
    def loadAlgorithm(self, options):
        try:
            cwd = os.getcwd()
            algOptions = options.algorithm
            package = algOptions["path"]
            entry = algOptions["entryPoint"]
            entryPoint = Algorunner._getEntryPoint(entry)
            __import__(package)
            os.chdir('{cwd}/{package}'.format(cwd=cwd, package=package))
            log.info('loading {entry}', entry=entry)
            mod = importlib.import_module(
                '.{entryPoint}'.format(entryPoint=entryPoint), package=package)
            log.info('algorithm code loaded')

            for k, v in methods.items():
                methodName = k
                method = v
                isMandatory = method["mandatory"]
                try:
                    self._originalAlgorithm[methodName] = getattr(
                        mod, methodName)
                    # fix start if it has only one argument
                    if methodName == 'start' and self._originalAlgorithm[
                            'start'].__code__.co_argcount == 1:
                        self._originalAlgorithm[
                            'startOrig'] = self._originalAlgorithm['start']
                        self._originalAlgorithm[
                            'start'] = lambda args, api: self._originalAlgorithm[
                                'startOrig'](args)
                    log.info('found method {methodName}',
                             methodName=methodName)
                except Exception as e:
                    mandatory = "mandatory" if isMandatory else "optional"
                    error = 'unable to find {mandatory} method {methodName}'.format(
                        mandatory=mandatory, methodName=methodName)
                    if (isMandatory):
                        raise Exception(error)
                    log.warning(error)
            self._wrapStateless()
            self._tracer = Tracer(options.tracer)
        except Exception as e:
            self._loadAlgorithmError = self._errorMsg(e)
            traceback.print_exc()
            log.error(e)
    def _readMessage(self, timeout=POLL_MS):
        hasMsg = False
        result = self._worker.poll(timeout)
        if (result == zmq.POLLIN):
            self._pollTimeoutCount = 0
            frames = self._worker.recv_multipart()
            signal = frames[0]

            if (signal == signals.PPP_MSG):
                hasMsg = True
                msgResult = self._handleAMessage(frames)
                self._send(signals.PPP_DONE, msgResult)
            else:
                time.sleep(0.005)
        else:
            self._pollTimeoutCount += 1
            log.warning('ZMQListener poll timeout {count}',
                        count=self._pollTimeoutCount)
        return hasMsg
    def loadAlgorithmCallbacks(self,
                               start,
                               init=None,
                               stop=None,
                               exit=None,
                               options=None):
        try:
            log.info('Initializing algorithm callbacks')
            self._originalAlgorithm['start'] = start
            self._originalAlgorithm['init'] = init
            self._originalAlgorithm['stop'] = stop
            self._originalAlgorithm['exit'] = exit
            for k, v in methods.items():
                methodName = k
                method = v
                isMandatory = method["mandatory"]
                if self._originalAlgorithm[methodName] is not None:
                    log.info('found method {methodName}',
                             methodName=methodName)
                else:
                    mandatory = "mandatory" if isMandatory else "optional"
                    error = 'unable to find {mandatory} method {methodName}'.format(
                        mandatory=mandatory, methodName=methodName)
                    if (isMandatory):
                        raise Exception(error)
                    log.warning(error)
            # fix start if it has only one argument
            if start.__code__.co_argcount == 1:
                self._originalAlgorithm['start'] = lambda args, api: start(args
                                                                           )
            self._wrapStateless()
            self._tracer = Tracer(options.tracer)

        except Exception as e:
            self._loadAlgorithmError = self._errorMsg(e)
            log.error(e)
    def fetch(self):
        try:
            if (self._active is False):
                time.sleep(0.2)
                return

            if (self._pollTimeoutCount == MAX_POLLS):
                log.warning('ZMQListener poll timeout reached')
                self._pollTimeoutCount = 0
                self._worker.close()
                self._worker = self._worker_socket(self._remoteAddress)

            if (self._pollTimeoutCount > 0):
                self._readMessage()
                return

            self._send(signals.PPP_READY)
            self._readMessage()

        except Exception as e:
            log.error('ZMQListener.fetch {e}', e=str(e))
        finally:
            if (self._active is False):
                self._working = False
    def close(self, force=True):
        closed = False
        if (self._active is False):
            log.warning('attempting to close inactive ZMQListener')
        else:
            self._active = False
            while self._working and not force:
                time.sleep(0.02)

            if (self._pollTimeoutCount):
                log.warning('trying to read message from socket after close')
                hasMsg = self._readMessage(timeout=POLL_MS * 5)
                if (hasMsg):
                    log.warning(
                        'success reading message from socket after close')

            self._worker.close()
            closed = True
        return closed
    def start(self):  # pylint: disable=too-many-branches
        poll_workers = zmq.Poller()
        poll_workers.register(self._backend, zmq.POLLIN)

        while self._active:  # pylint: disable=too-many-nested-blocks
            try:
                socks = dict(poll_workers.poll(CYCLE_LENGTH_MS))

                if socks.get(self._backend) == zmq.POLLIN:

                    frames = self._backend.recv_multipart() or []

                    if (len(frames) != 4):
                        log.warning("got {len} frames {frames}",
                                    len=len(frames),
                                    frames=frames)
                        continue

                    address, signal, consumer, result = frames  # pylint: disable=unbalanced-tuple-unpacking
                    consumerType = self.encoding.decode(value=consumer,
                                                        plainEncode=True)

                    if (not consumerType in self.consumerTypes):
                        log.warning(
                            "Producer got message from unknown consumer: {consumerType}, dropping the message",
                            consumerType=consumerType)
                        continue

                    if (signal == signals.PPP_DONE):
                        sentTime = self.watingForResponse.get(address)
                        if (sentTime):
                            now = time.time()
                            del self.watingForResponse[address]
                            self.responseAccumulator(
                                result, consumerType,
                                round((now - sentTime) * 1000, 4))
                        else:
                            log.error('missing from watingForResponse:' +
                                      str(signal))

                    elif (signal == signals.PPP_READY):
                        message = self.messageQueue.pop(consumerType)
                        if (message):
                            messageFlowPattern, header, payload, appendTime = message
                            flow = Flow(messageFlowPattern)
                            flowMsg = self.encoding.encode(flow.getRestOfFlow(
                                self.nodeName),
                                                           plainEncode=True)
                            frames = [
                                address, signals.PPP_MSG, flowMsg, header,
                                payload
                            ]
                            self.watingForResponse[address] = time.time()
                            queueTime = round(
                                (time.time() - appendTime) * 1000, 4)
                            self.queueTimeAccumulator(consumerType, queueTime)
                            self._send(frames)
                        else:
                            self._send([address, signals.PPP_NO_MSG])

            except Exception as e:
                log.error('Error in ZMQProducer {e}', e=str(e))

        self._working = False
 def close(self, force=True):
     if not (self.active):
         log.warning("Attempting to close inactive MessageProducer")
     else:
         self.adapter.close(force)
         self.active = False