def setDelay(self, delay):
        """
        Returns void
        Parameters:
            delay: int


        """
        _transDelay = ternary(delay > 0, delay, 0)
    def setDelay(self, delay):
        """
        Returns void
        Parameters:
            delay: int


        """
        _transDelay = ternary(delay > 0, delay, 0)
    def createHandler(self, message, context):
        """
        Returns MessageHandler
        Parameters:
            message: Messagecontext: NotificationContext
        @Override


        """
        # String
        type = message.getMsgType()
        if not (type == MessageType.toString(MessageType.STATE_TRANSITION)):
            raise HelixException("Unexpected msg type for message " + message.getMsgId() + " type:" + message.getMsgType())


        # String
        partitionKey = message.getPartitionName()
        # String
        stateModelName = message.getStateModelDef()
        # String
        resourceName = message.getResourceName()
        # String
        sessionId = message.getTgtSessionId()
        # int
        bucketSize = message.getBucketSize()
        if stateModelName == None: 
            self.logger.error("message does not contain stateModelDef")
            return None

        # String
        factoryName = message.getStateModelFactoryName()
        if factoryName == None: 
            factoryName = HelixConstants.DEFAULT_STATE_MODEL_FACTORY

        # StateModelFactory
        stateModelFactory = self.getStateModelFactory(stateModelName, factoryName)
        if stateModelFactory == None: 
            self.logger.warn("Cannot find stateModelFactory for model:" + stateModelName + " using factoryName:" + factoryName + " for resourceGroup:" + resourceName)
            return None

        if not self._stateModelDefs.__contains__(stateModelName):
            # HelixDataAccessor
            accessor = self._manager.getHelixDataAccessor()
            # Builder
            keyBuilder = accessor.keyBuilder()
            # StateModelDefinition
            stateModelDef = accessor.getProperty(keyBuilder.stateModelDef(stateModelName))
            if stateModelDef == None: 
                raise HelixException("stateModelDef for " + stateModelName + " does NOT exists")


            self._stateModelDefs.__setitem__(stateModelName, stateModelDef)

        # String
        initState = self._stateModelDefs.get(message.getStateModelDef()).getInitialState()
        # StateModel
        stateModel = stateModelFactory.getStateModel(partitionKey)
        if stateModel == None: 
            stateModelFactory.createAndAddStateModel(partitionKey)
            stateModel = stateModelFactory.getStateModel(partitionKey)
            stateModel.updateState(initState)

        # CurrentState
        currentStateDelta = CurrentState(resourceName)
        currentStateDelta.setSessionId(sessionId)
        currentStateDelta.setStateModelDefRef(stateModelName)
        currentStateDelta.setStateModelFactoryName(factoryName)
        currentStateDelta.setBucketSize(bucketSize)
        currentStateDelta.setState(partitionKey, ternary((stateModel.getCurrentState() == None), initState, stateModel.getCurrentState()))
        # HelixTaskExecutor
        executor = context.get(NotificationContext.TASK_EXECUTOR_KEY)
#        executor = (HelixTaskExecutor) context.get(NotificationContext.TASK_EXECUTOR_KEY)
        return HelixStateTransitionHandler(stateModel, message, context, currentStateDelta, executor)
    def create_paths(self, paths, records, needCreate, pathsCreated, options):
        """
        Returns CreateCallbackHandler[]
        Parameters:
            paths: List<String>records: List<T>needCreate: boolean[]pathsCreated: List<List<String>>options: int


        """
        if (records != None and records.__len__() != paths.__len__()
            ) or needCreate.__len__() != paths.__len__() or (
                pathsCreated != None
                and pathsCreated.__len__() != paths.__len__()):
            raise IllegalArgumentException(
                "paths, records, needCreate, and pathsCreated should be of same size"
            )

        # CreateCallbackHandler[]
        cbList = [CreateCallbackHandler() for path in paths]
        # CreateMode
        mode = AccessOption.getMode(options)
        if mode == None:
            self.LOG.error("Invalid async set mode. options: " + str(options))
            return cbList

        # boolean
        retry = True

        while retry:
            retry = False
            for i in range(paths.__len__()):
                if not needCreate[i]:
                    continue
                # String
                path = paths[i]
                # T
                record = ternary(records == None, None, records[i])
                cbList[i] = CreateCallbackHandler()
                self._zkClient.asyncCreate(path, record, mode, cbList[i])

            # List<String>
#            parentPaths = ArrayList<String>(Collections.nCopies(paths.__len__(), None))
            parentPaths = [None for path in paths]
            # boolean
            failOnNoNode = False
            for i in range(paths.__len__()):
                if not needCreate[i]:
                    continue
                # CreateCallbackHandler
                cb = cbList[i]
                cb.waitForSuccess()
                # String
                path = paths[i]
                #                if Code.get(cb.getRc()) == Code.NONODE:
                if cb.isNoNodeError():
                    # String
                    parentPath = os.path.abspath(
                        os.path.join(path, os.path.pardir))
                    #                    parentPath = File(path).getParent()
                    parentPaths[i] = parentPath
                    failOnNoNode = True
                else:
                    needCreate[i] = False
                    #                    if Code.get(cb.getRc()) == Code.OK and pathsCreated != None:
                    if cb.isSuccessful() and pathsCreated != None:
                        if pathsCreated[i] == None:
                            pathsCreated[i] = []
                        pathsCreated[i].add(path)

            if failOnNoNode:
                # boolean[]
                #                needCreateParent = Arrays.copyOf(needCreate, needCreate.length)
                needCreateParent = [x for x in needCreate]
                # CreateCallbackHandler[]
                parentCbList = self.create(parentPaths, None, needCreateParent,
                                           pathsCreated,
                                           AccessOption.PERSISTENT)
                for parentCb in parentCbList:  # CreateCallbackHandler
                    #                    parentCb = parentCbList[i]
                    if parentCb == None:
                        continue
                    # Code
                    if parentCb.isSuccessful() or parentCb.isNodeExistError():
                        #                    rc = Code.get(parentCb.getRc())
                        #                    if rc == Code.OK or rc == Code.NODEEXISTS:
                        retry = True
                        break

        return cbList
    def create_paths(self, paths, records, needCreate, pathsCreated, options):
        """
        Returns CreateCallbackHandler[]
        Parameters:
            paths: List<String>records: List<T>needCreate: boolean[]pathsCreated: List<List<String>>options: int


        """
        if (records != None and records.__len__() != paths.__len__()) or needCreate.__len__() != paths.__len__() or (pathsCreated != None and pathsCreated.__len__() != paths.__len__()):
            raise IllegalArgumentException("paths, records, needCreate, and pathsCreated should be of same size")


        # CreateCallbackHandler[]
        cbList = [CreateCallbackHandler() for path in paths]
        # CreateMode
        mode = AccessOption.getMode(options)
        if mode == None: 
            self.LOG.error("Invalid async set mode. options: " + str(options))
            return cbList

        # boolean
        retry = True
        
        while retry:
            retry = False
            for i in range(paths.__len__()):
                if not needCreate[i]:
                    continue
                # String
                path = paths[i]
                # T
                record = ternary(records == None, None, records[i])
                cbList[i] = CreateCallbackHandler()
                self._zkClient.asyncCreate(path, record, mode, cbList[i])

            # List<String>
#            parentPaths = ArrayList<String>(Collections.nCopies(paths.__len__(), None))
            parentPaths = [None for path in paths]
            # boolean
            failOnNoNode = False
            for i in range(paths.__len__()):
                if not needCreate[i]:
                    continue
                # CreateCallbackHandler
                cb = cbList[i]
                cb.waitForSuccess()
                # String
                path = paths[i]
#                if Code.get(cb.getRc()) == Code.NONODE:
                if cb.isNoNodeError():
                    # String
                    parentPath = os.path.abspath(os.path.join(path, os.path.pardir))
#                    parentPath = File(path).getParent()
                    parentPaths[i] = parentPath
                    failOnNoNode = True
                else:
                    needCreate[i] = False
#                    if Code.get(cb.getRc()) == Code.OK and pathsCreated != None:
                    if cb.isSuccessful() and pathsCreated != None:
                        if pathsCreated[i] == None:
                            pathsCreated[i] = []
                        pathsCreated[i].add(path)

            if failOnNoNode:
                # boolean[]
#                needCreateParent = Arrays.copyOf(needCreate, needCreate.length)
                needCreateParent = [x for x in needCreate]
                # CreateCallbackHandler[]
                parentCbList = self.create(parentPaths, None, needCreateParent, pathsCreated, AccessOption.PERSISTENT)
                for parentCb in parentCbList: # CreateCallbackHandler
#                    parentCb = parentCbList[i]
                    if parentCb == None: 
                        continue
                    # Code
                    if parentCb.isSuccessful() or parentCb.isNodeExistError():
#                    rc = Code.get(parentCb.getRc())
#                    if rc == Code.OK or rc == Code.NODEEXISTS:
                        retry = True
                        break

        return cbList
예제 #6
0
class HelixTask():
#class HelixTask(Callable<HelixTaskResult>):

    """
    Java modifiers:
         private static
    Type:
        Logger
    """
    logger = get_logger(__name__)

#    class TimeoutCancelTask(TimerTask):
#
#        """
#
#        Parameters:
#            HelixTaskExecutor executor
#            Message message
#            NotificationContext context
#        """
#        def __init__(self, executor, message, context):
#            self._executor = executor
#            self._message = message
#            self._context = context
#
#
#        def run(self):
#            """
#            Returns void
#            @Override
#
#
#            """
#            self._isTimeout = True
#            self.logger.warn("Message time out, canceling. id:" + self._message.getMsgId() + " timeout : " + self._message.getExecutionTimeout())
#            self._handler.onTimeout()
#            self._executor.cancelTask(self._message, self._context)
#


    """

    Parameters:
        Message message
        NotificationContext notificationContext
        MessageHandler handler
        HelixTaskExecutor executor
    Throws:
        Exception
    """
    def __init__(self, message, notificationContext, handler, executor):
        self._notificationContext = notificationContext
        self._message = message
        self._handler = handler
        self._manager = notificationContext.getManager()
        self._statusUpdateUtil = StatusUpdateUtil()
        self._executor = executor
        self._isTimeout = False


    def call(self):
        """
        Returns HelixTaskResult
        @Override


        """
        # Timer
        # TODO: enable timer
        timer = None
#        if self._message.getExecutionTimeout() > 0:
#            timer = Timer(True)
#            timer.schedule(TimeoutCancelTask(self._executor, self._message, self._notificationContext), self._message.getExecutionTimeout())
#            self.logger.info("Message starts with timeout " + self._message.getExecutionTimeout() + " MsgId:" + self._message.getMsgId())
#        else:
#            self.logger.info("Message does not have timeout. MsgId:" + self._message.getMsgId() + "/" + self._message.getPartitionName())

        # HelixTaskResult
        taskResult = HelixTaskResult()
        # Exception
        exception = None
        # ErrorType
        type = ErrorType.INTERNAL
        # ErrorCode
        code = ErrorCode.ERROR
        # long
        start = time.time()
        self.logger.info("msg:" + str(self._message.getMsgId()) + " handling task begin, at: " + str(start))
        # HelixDataAccessor
        accessor = self._manager.getHelixDataAccessor()
        self._statusUpdateUtil.logInfo(self._message, HelixTask, "Message handling task begin execute", accessor)
        self._message.setExecuteStartTimeStamp(time.time())
        try:
            taskResult = self._handler.handleMessage()
            exception = taskResult.getException()
#        except Exception, e:
        except KeyboardInterrupt, e:
            self._statusUpdateUtil.logError(self._message, HelixTask, e, "State transition interrupted, timeout:" + str(self._isTimeout),  accessor)
            self.logger.info("Message " + self._message.getMsgId() + " is interrupted")
            taskResult.setInterrupted(True)
            taskResult.setException(e)
            exception = e
#        except Exception, e:
#            # String
#            errorMessage = "Exception while executing a message. " + e + " msgId: " + self._message.getMsgId() + " type: " + self._message.getMsgType()
#            self.logger.error(errorMessage+ str(e))
#            self._statusUpdateUtil.logError(self._message, HelixTask, e, errorMessage, accessor)
#            taskResult.setSuccess(False)
#            taskResult.setException(e)
#            taskResult.setMessage(e.getMessage())
#            exception = e

        if timer != None: 
            timer.cancel()

        if taskResult.isSucess(): 
            self._statusUpdateUtil.logInfo(self._message, self._handler.__class__, "Message handling task completed successfully", accessor)
            self.logger.info("Message " + self._message.getMsgId() + " completed.")
        else:
            if taskResult.isInterrupted(): 
                self.logger.info("Message " + self._message.getMsgId() + " is interrupted")
                code = ternary(self._isTimeout, ErrorCode.TIMEOUT, ErrorCode.CANCEL)
                if self._isTimeout: 
                    # int
                    retryCount = self._message.getRetryCount()
                    self.logger.info("Message timeout, retry count: " + retryCount + " MSGID:" + self._message.getMsgId())
                    self._statusUpdateUtil.logInfo(self._message, self._handler.__class__, "Message handling task timeout, retryCount:" + retryCount, accessor)
                    if retryCount > 0: 
                        self._message.setRetryCount(retryCount - 1)
                        self._executor.scheduleTask(self._message, self._handler, self._notificationContext)
                        return taskResult


            else:
                # String
                errorMsg = "Message execution failed. msgId: " + self._message.getMsgId() + taskResult.getMessage()
                if exception is not None:
                    errorMsg += exception

                self.logger.error(errorMsg+ str(exception))
                self._statusUpdateUtil.logError(self._message, self._handler.getClass(), errorMsg, accessor)

        try:
            if not self._message.getGroupMessageMode(): 
                self.removeMessageFromZk(accessor, self._message)
                self.reportMessageStat(self._manager, self._message, taskResult)
                self.sendReply(accessor, self._message, taskResult)
            else:
                # GroupMessageInfo
                info = self._executor._groupMsgHandler.onCompleteSubMessage(self._message)
                if info is not None:
                    # Map<PropertyKey, CurrentState>
                    curStateMap = info.merge()
                    for key in curStateMap.keys():
                        accessor.updateProperty(key, curStateMap.get(key))

                    self.removeMessageFromZk(accessor, self._message)
                    self.reportMessageStat(self._manager, self._message, taskResult)
                    self.sendReply(accessor, self._message, taskResult)


            self._executor.reportCompletion(self._message)
        # except KeyboardInterrupt, e:
        #TODO: should we print the error
        except Exception as e:
            # String
            errorMessage = "Exception after executing a message, msgId: " + self._message.getMsgId() + e
            self.logger.error(errorMessage+ str(e))
            self._statusUpdateUtil.logError(self._message, HelixTask, errorMessage, accessor)
            exception = e
            type = ErrorType.FRAMEWORK
            code = ErrorCode.ERROR
        finally:
                # long
                end = time.time()
#                end = System.currentTimeMillis()
                self.logger.info("msg:" + self._message.getMsgId() + " handling task completed, results:" + str(taskResult.isSucess()) + ", at: " + str(end) + ", took:" + str(end - start))
                if exception is not None:
                    self._handler.onError(exception, code, type)


        return taskResult
예제 #7
0
    def createHandler(self, message, context):
        """
        Returns MessageHandler
        Parameters:
            message: Messagecontext: NotificationContext
        @Override


        """
        # String
        type = message.getMsgType()
        if not (type == MessageType.toString(MessageType.STATE_TRANSITION)):
            raise HelixException("Unexpected msg type for message " +
                                 message.getMsgId() + " type:" +
                                 message.getMsgType())

        # String
        partitionKey = message.getPartitionName()
        # String
        stateModelName = message.getStateModelDef()
        # String
        resourceName = message.getResourceName()
        # String
        sessionId = message.getTgtSessionId()
        # int
        bucketSize = message.getBucketSize()
        if stateModelName == None:
            self.logger.error("message does not contain stateModelDef")
            return None

        # String
        factoryName = message.getStateModelFactoryName()
        if factoryName == None:
            factoryName = HelixConstants.DEFAULT_STATE_MODEL_FACTORY

        # StateModelFactory
        stateModelFactory = self.getStateModelFactory(stateModelName,
                                                      factoryName)
        if stateModelFactory == None:
            self.logger.warn("Cannot find stateModelFactory for model:" +
                             stateModelName + " using factoryName:" +
                             factoryName + " for resourceGroup:" +
                             resourceName)
            return None

        if not self._stateModelDefs.__contains__(stateModelName):
            # HelixDataAccessor
            accessor = self._manager.getHelixDataAccessor()
            # Builder
            keyBuilder = accessor.keyBuilder()
            # StateModelDefinition
            stateModelDef = accessor.getProperty(
                keyBuilder.stateModelDef(stateModelName))
            if stateModelDef == None:
                raise HelixException("stateModelDef for " + stateModelName +
                                     " does NOT exists")

            self._stateModelDefs.__setitem__(stateModelName, stateModelDef)

        # String
        initState = self._stateModelDefs.get(
            message.getStateModelDef()).getInitialState()
        # StateModel
        stateModel = stateModelFactory.getStateModel(partitionKey)
        if stateModel == None:
            stateModelFactory.createAndAddStateModel(partitionKey)
            stateModel = stateModelFactory.getStateModel(partitionKey)
            stateModel.updateState(initState)

        # CurrentState
        currentStateDelta = CurrentState(resourceName)
        currentStateDelta.setSessionId(sessionId)
        currentStateDelta.setStateModelDefRef(stateModelName)
        currentStateDelta.setStateModelFactoryName(factoryName)
        currentStateDelta.setBucketSize(bucketSize)
        currentStateDelta.setState(
            partitionKey,
            ternary((stateModel.getCurrentState() == None), initState,
                    stateModel.getCurrentState()))
        # HelixTaskExecutor
        executor = context.get(NotificationContext.TASK_EXECUTOR_KEY)
        #        executor = (HelixTaskExecutor) context.get(NotificationContext.TASK_EXECUTOR_KEY)
        return HelixStateTransitionHandler(stateModel, message, context,
                                           currentStateDelta, executor)