def persist(self, session, reason, finished_name, next_name): """ 提供必要的持久化实现 .. Note:: session中的控制消息应在处理完成之后被清理,否则会造成重复触发 :param object session: 状态机的session :param str reason: 持久化的原因 :param str finished_name: 已经完成的节点名 :param str next_name: 下一个将处理的节点名 :return: 无返回 :rtype: None """ if reason == graph.PersistedStateMachineHelper.Reason.CONTROL: message_name = "PERSIST_SESSION_MESSAGE" elif reason == graph.PersistedStateMachineHelper.Reason.STARTED: message_name = "STATE_COMPLETE_MESSAGE" elif reason == graph.PersistedStateMachineHelper.Reason.NODE_CHANGED: message_name = "STATE_COMPLETE_MESSAGE" if session is not None: params = { "session": session, "finished_node": finished_name, "current_node": next_name, "timestamp": int(time.time()) } notice = framework.OperationMessage( message_name, str(session.id), params) self._result_queue.put(notice) else: log.e("operation persist but session is None")
def on_error(self, header, message): """ 响应错误,本处只打印日志,便于追查问题 :param dict header: 消息头 :param dict message: 消息体 :return: 无返回 :rtype: None """ log.e("receive an error:{}".format(message))
def save_operation(self, operation): """ 持久化状态机信息 :param operation: :return: """ if not self.lock: log.e("current guardian instance no privilege to save operation") raise exception.EInvalidOperation( "current guardian instance no privilege to save operation") operation_path = config.GuardianConfig.get_persistent_path("operations") + "/" + operation.operation_id if not persistence.PersistenceDriver().exists(operation_path): persistence.PersistenceDriver().create_node(path=operation_path) persistence.PersistenceDriver().save_data(operation_path, pickle.dumps(operation)) log.d("save operation_id:{} success".format(operation.operation_id))
def save_context(self): """ 运行数据持久化,当当前Guardian为主(lock属性为True)时,可持久化数据,否则失败 :return: 无返回 :rtype: None :raises EInvalidOperation: 非法操作 """ if not self.lock: log.e("current guardian instance no privilege to save context") raise exception.EInvalidOperation( "current guardian instance no privilege to save context") context_path = config.GuardianConfig.get_persistent_path("context") context_to_persist = copy.deepcopy(self) # 考虑反序列化时可能异常,不使用del删除属性operations context_to_persist.operations = {} persistence.PersistenceDriver().save_data( context_path, pickle.dumps(context_to_persist)) log.i("save context success")
def save_context(self): """ 运行数据持久化,当当前Guardian为主(lock属性为True)时,可持久化数据,否则失败 :return: 无返回 :rtype: None :raises EInvalidOperation: 非法操作 """ if not self.lock: log.e("current guardian instance no privilege to save context") raise exception.EInvalidOperation( "current guardian instance no privilege to save context") context_path = config.GuardianConfig.get_persistent_path("context") context_to_persist = self operations_tmp = self.operations context_to_persist.operations = {} try: persistence.PersistenceDriver().save_data(context_path, pickle.dumps(context_to_persist)) except Exception as e: self.operations = operations_tmp log.r(e, "save context fail") self.operations = operations_tmp log.d("save context success")
def http_request(self, host, port, method, url, header=None, data=None, timeout=30, retry_times=2, response_code=None, response_json=True): """ http请求接口 :param str host: 服务器地址 :param int port: 服务器端口 :param str method: http方法 :param str url: url地址 :param dict header: http消息头 :param str data: http body数据 :param int timeout: 请求超时时间 :param int retry_times: 请求重试次数 :param list response_code: 请求正确时的返回码 :param bool response_json: True 返回json格式的数据,False 返回字符串 :return: http 请求的数据 :rtype: str :raises EFailedRequest: 请求失败 """ log.d("http request, host:{}, port:{}, method:{}, url:{}, header:" "{}, data:{}, timeout:{}, retry_times:{}, response code:{}, " "response_json:{}".format(host, port, method, url, header, data, timeout, retry_times, response_code, response_json)) header = header or {} res_data = None for i in range(retry_times + 1): stop_tag = True if i == retry_times else False sleep_time = (i + 1) * (i + 1) try: conn = httplib.HTTPConnection(host=host, port=port, timeout=timeout) conn.request(method=method, url=url, body=data, headers=header) resp = conn.getresponse() res_data = resp.read() log.d("http request ret:{}".format(res_data)) except Exception as e: log.f("http request exe{}".format(res_data)) if stop_tag: raise exception.EFailedRequest( "http request failed,error:{}".format(e)) else: time.sleep(sleep_time) continue else: log.d("http request ok") if not response_code or not isinstance(response_code, list): if 200 <= resp.status < 300: break elif stop_tag: log.e("request failed,code:{},msg:{}".format( resp.status, resp.msg)) raise exception.EFailedRequest( "request failed,code:{},msg:{}".format( resp.status, resp.msg)) else: time.sleep((i + 1) * (i + 1)) continue else: if resp.status in response_code: break elif stop_tag: log.e("request failed,error,code:{},data:{}".format( resp.status, data)) raise exception.EFailedRequest( "request failed,error,code:{},data:{}".format( resp.status, data)) else: time.sleep(sleep_time) continue log.d("http response data:{}".format(res_data)) if response_json: return json.loads(res_data) else: return res_data