docs: add aimrt_py rpc context (#58)
* docs: clarify context type enumeration description Enhance the explanation of the `aimrt_channel_context_type_t` enumeration to clearly indicate its role in defining publisher and subscriber contexts. This improves understanding for users implementing the interface. * feat: enhance RpcContext with additional features Add new methods for managing context metadata, timeout settings, and target addresses. Improve logging to provide better visibility into RPC calls and responses, aiding in debugging and performance monitoring. * feat: enhance RPC context logging with metadata Add the ability to log metadata in RPC calls, improving traceability and debugging. Update the client to set a metadata value and enhance server logging to print out all metadata associated with requests. * feat: add RPC context types to Python bindings Introduce enum values for client and server RPC context types in Python bindings to enhance type support and improve clarity in interactions with RPC features.
This commit is contained in:
parent
0b2427dc75
commit
328a99512b
@ -114,7 +114,7 @@ protoc --python_out=. example.proto
|
||||
|
||||
`ContextRef`是`Context`的引用类型,除不具备`Reset`接口外,其他接口与`Context`完全相同。
|
||||
|
||||
`aimrt_channel_context_type_t` 是一个枚举类型,定义了上下文类型,具体值为`AIMRT_CHANNEL_PUBLISHER_CONTEXT`或`AIMRT_CHANNEL_SUBSCRIBER_CONTEXT`。
|
||||
`aimrt_channel_context_type_t` 是一个枚举类型,定义了上下文类型,具体值为`AIMRT_CHANNEL_PUBLISHER_CONTEXT`或`AIMRT_CHANNEL_SUBSCRIBER_CONTEXT`,表明这是发布者还是订阅者的上下文。
|
||||
|
||||
|
||||
## 使用示例
|
||||
|
@ -85,6 +85,30 @@ protoc --aimrt_rpc_out=. --plugin=protoc-gen-aimrt_rpc=./protoc_plugin_py_gen_ai
|
||||
|
||||
请注意,`RpcStatus`中的错误信息一般仅表示框架层面的错误,例如服务未找到、网络错误或者序列化错误等,供开发者排查框架层面的问题。如果开发者需要返回业务层面的错误,建议在业务包中添加相应的字段。
|
||||
|
||||
## RpcContext
|
||||
|
||||
RpcContext 是 RPC 调用时上下文信息,开发者可以在 RPC 调用时设置一些上下文信息,例如超时时间、Meta 信息等,具体接口如下:
|
||||
- `CheckUsed()->bool` :检查 Context 是否被使用;
|
||||
- `SetUsed()->None` :设置 Context 为已使用;
|
||||
- `Reset()->None` :重置 Context;
|
||||
- `GetType()->aimrt_rpc_context_type_t` :获取 Context 类型;
|
||||
- `Timeout()->datetime.timedelta` :获取超时时间;
|
||||
- `SetTimeout(timeout: datetime.timedelta)->None` :设置超时时间;
|
||||
- `SetMetaValue(key: str, value: str)->None` :设置元数据;
|
||||
- `GetMetaValue(key: str)->str` :获取元数据;
|
||||
- `GetMetaKeys()->List[str]` :获取所有元数据键值对中的键列表;
|
||||
- `SetToAddr(addr: str)->None` :设置目标地址;
|
||||
- `GetToAddr()->str` :获取目标地址;
|
||||
- `SetSerializationType(serialization_type: str)->None` :设置序列化类型;
|
||||
- `GetSerializationType()->str` :获取序列化类型;
|
||||
- `GetFunctionName()->str` :获取函数名称;
|
||||
- `SetFunctionName(func_name: str)->None` :设置函数名称;
|
||||
- `ToString()->str` :获取上下文信息,以字符串形式返回可读性高的信息;
|
||||
|
||||
`RpcContextRef`是`RpcContext`的引用类型,除不具备`Reset`接口外,其他接口与`RpcContext`完全相同。
|
||||
|
||||
`aimrt_rpc_context_type_t` 是一个枚举类型,定义了上下文类型,具体值为`AIMRT_RPC_CLIENT_CONTEXT`或`AIMRT_RPC_SERVER_CONTEXT`,表明这是客户端还是服务端的上下文。
|
||||
|
||||
|
||||
## Client
|
||||
|
||||
@ -147,11 +171,14 @@ def main():
|
||||
|
||||
ctx = aimrt_py.RpcContext()
|
||||
ctx.SetTimeout(datetime.timedelta(seconds=30))
|
||||
ctx.SetMetaValue("key1", "value1")
|
||||
status, rsp = proxy.GetFooData(ctx, req)
|
||||
|
||||
aimrt_py.info(module_handle.GetLogger(),
|
||||
"Call rpc done, status: {}, req: {}, rsp: {}"
|
||||
.format(status.ToString(), MessageToJson(req), MessageToJson(rsp)))
|
||||
f"Call rpc done, "
|
||||
f"status: {status.ToString()}, "
|
||||
f"req: {MessageToJson(req)}, "
|
||||
f"rsp: {MessageToJson(rsp)}")
|
||||
|
||||
# Shutdown
|
||||
aimrt_core.Shutdown()
|
||||
@ -201,13 +228,27 @@ def signal_handler(sig, frame):
|
||||
|
||||
|
||||
class ExampleServiceImpl(rpc_aimrt_rpc_pb2.ExampleService):
|
||||
def __init__(self):
|
||||
def __init__(self, logger):
|
||||
super().__init__()
|
||||
self.logger = logger
|
||||
|
||||
@staticmethod
|
||||
def PrintMetaInfo(logger, ctx_ref):
|
||||
meta_keys = ctx_ref.GetMetaKeys()
|
||||
for key in meta_keys:
|
||||
aimrt_py.info(logger, f"meta key: {key}, value: {ctx_ref.GetMetaValue(key)}")
|
||||
|
||||
def GetFooData(self, ctx_ref, req):
|
||||
rsp = rpc_pb2.GetFooDataRsp()
|
||||
rsp.msg = "echo " + req.msg
|
||||
|
||||
ExampleServiceImpl.PrintMetaInfo(self.logger, ctx_ref)
|
||||
aimrt_py.info(self.logger,
|
||||
f"Server handle new rpc call. "
|
||||
f"context: {ctx_ref.ToString()}, "
|
||||
f"req: {MessageToJson(req)}, "
|
||||
f"return rsp: {MessageToJson(rsp)}")
|
||||
|
||||
return aimrt_py.RpcStatus(), rsp
|
||||
|
||||
def main():
|
||||
@ -228,7 +269,7 @@ def main():
|
||||
module_handle = aimrt_core.CreateModule("NormalRpcServerPymodule")
|
||||
|
||||
# Register rpc service
|
||||
service = ExampleServiceImpl()
|
||||
service = ExampleServiceImpl(module_handle.GetLogger())
|
||||
ret = module_handle.GetRpcHandle().RegisterService(service)
|
||||
assert ret, "Register service failed."
|
||||
|
||||
|
@ -49,11 +49,13 @@ def main():
|
||||
|
||||
ctx = aimrt_py.RpcContext()
|
||||
ctx.SetTimeout(datetime.timedelta(seconds=30))
|
||||
ctx.SetMetaValue("key1", "value1")
|
||||
status, rsp = proxy.GetFooData(ctx, req)
|
||||
|
||||
aimrt_py.info(module_handle.GetLogger(),
|
||||
"Call rpc done, status: {}, req: {}, rsp: {}"
|
||||
.format(status.ToString(), MessageToJson(req), MessageToJson(rsp)))
|
||||
f"Call rpc done, status: {status.ToString()}, "
|
||||
f"req: {MessageToJson(req)}, "
|
||||
f"rsp: {MessageToJson(rsp)}")
|
||||
|
||||
# Shutdown
|
||||
aimrt_core.Shutdown()
|
||||
|
@ -29,13 +29,22 @@ class ExampleServiceImpl(rpc_aimrt_rpc_pb2.ExampleService):
|
||||
super().__init__()
|
||||
self.logger = logger
|
||||
|
||||
@staticmethod
|
||||
def PrintMetaInfo(logger, ctx_ref):
|
||||
meta_keys = ctx_ref.GetMetaKeys()
|
||||
for key in meta_keys:
|
||||
aimrt_py.info(logger, f"meta key: {key}, value: {ctx_ref.GetMetaValue(key)}")
|
||||
|
||||
def GetFooData(self, ctx_ref, req):
|
||||
rsp = rpc_pb2.GetFooDataRsp()
|
||||
rsp.msg = "echo " + req.msg
|
||||
|
||||
ExampleServiceImpl.PrintMetaInfo(self.logger, ctx_ref)
|
||||
aimrt_py.info(self.logger,
|
||||
"Server handle new rpc call. context:{}, req: {}, return rsp: {}"
|
||||
.format(ctx_ref.ToString(), MessageToJson(req), MessageToJson(rsp)))
|
||||
f"Server handle new rpc call. "
|
||||
f"context: {ctx_ref.ToString()}, "
|
||||
f"req: {MessageToJson(req)}, "
|
||||
f"return rsp: {MessageToJson(rsp)}")
|
||||
|
||||
return aimrt_py.RpcStatus(), rsp
|
||||
|
||||
@ -43,9 +52,12 @@ class ExampleServiceImpl(rpc_aimrt_rpc_pb2.ExampleService):
|
||||
rsp = rpc_pb2.GetBarDataRsp()
|
||||
rsp.msg = "echo " + req.msg
|
||||
|
||||
ExampleServiceImpl.PrintMetaInfo(self.logger, ctx_ref)
|
||||
aimrt_py.info(self.logger,
|
||||
"Server handle new rpc call. context:{}, req: {}, return rsp: {}"
|
||||
.format(ctx_ref.ToString(), MessageToJson(req), MessageToJson(rsp)))
|
||||
f"Server handle new rpc call. "
|
||||
f"context: {ctx_ref.ToString()}, "
|
||||
f"req: {MessageToJson(req)}, "
|
||||
f"return rsp: {MessageToJson(rsp)}")
|
||||
|
||||
return aimrt_py.RpcStatus(), rsp
|
||||
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "python_runtime/export_type_support.h"
|
||||
|
||||
#include "pybind11/pybind11.h"
|
||||
#include "rpc/rpc_context_base.h"
|
||||
|
||||
namespace aimrt::runtime::python_runtime {
|
||||
|
||||
@ -58,6 +59,10 @@ inline void ExportRpcContext(const pybind11::object& m) {
|
||||
using aimrt::rpc::Context;
|
||||
using aimrt::rpc::ContextRef;
|
||||
|
||||
pybind11::enum_<aimrt_rpc_context_type_t>(m, "RpcContextType")
|
||||
.value("AIMRT_RPC_CLIENT_CONTEXT", AIMRT_RPC_CLIENT_CONTEXT)
|
||||
.value("AIMRT_RPC_SERVER_CONTEXT", AIMRT_RPC_SERVER_CONTEXT);
|
||||
|
||||
pybind11::class_<Context, std::shared_ptr<Context>>(m, "RpcContext")
|
||||
.def(pybind11::init<>())
|
||||
.def("CheckUsed", &Context::CheckUsed)
|
||||
|
Loading…
x
Reference in New Issue
Block a user