Skip to content

Commit 95321d7

Browse files
committed
fixed with changes
1 parent a785c34 commit 95321d7

2 files changed

Lines changed: 129 additions & 20 deletions

File tree

src/dubbo/proxy/handlers.py

Lines changed: 128 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,3 @@
1-
#
2-
# Licensed to the Apache Software Foundation (ASF) under one or more
3-
# contributor license agreements. See the NOTICE file distributed with
4-
# this work for additional information regarding copyright ownership.
5-
# The ASF licenses this file to You under the Apache License, Version 2.0
6-
# (the "License"); you may not use this file except in compliance with
7-
# the License. You may obtain a copy of the License at
8-
#
9-
# http://www.apache.org/licenses/LICENSE-2.0
10-
#
11-
# Unless required by applicable law or agreed to in writing, software
12-
# distributed under the License is distributed on an "AS IS" BASIS,
13-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14-
# See the License for the specific language governing permissions and
15-
# limitations under the License.
16-
171
import inspect
182
from typing import Callable, Optional, List, Type, Any, get_type_hints
193
from dubbo.classes import MethodDescriptor
@@ -27,33 +11,75 @@
2711
__all__ = ["RpcMethodHandler", "RpcServiceHandler"]
2812

2913

14+
class RpcMethodConfigurationError(Exception):
15+
"""
16+
Raised when RPC method is configured incorrectly.
17+
"""
18+
pass
19+
20+
3021
class RpcMethodHandler:
22+
"""
23+
Rpc method handler that wraps metadata and serialization logic for a callable.
24+
"""
25+
3126
__slots__ = ["_method_descriptor"]
3227

3328
def __init__(self, method_descriptor: MethodDescriptor):
29+
"""
30+
Initialize the RpcMethodHandler
31+
:param method_descriptor: the method descriptor.
32+
:type method_descriptor: MethodDescriptor
33+
"""
3434
self._method_descriptor = method_descriptor
3535

3636
@property
3737
def method_descriptor(self) -> MethodDescriptor:
38+
"""
39+
Get the method descriptor
40+
:return: the method descriptor
41+
:rtype: MethodDescriptor
42+
"""
3843
return self._method_descriptor
3944

4045
@staticmethod
4146
def get_codec(**kwargs) -> tuple:
47+
"""
48+
Get the serialization and deserialization functions based on codec
49+
:param kwargs: codec settings like transport_type, parameter_types, return_type
50+
:return: serializer and deserializer functions
51+
:rtype: Tuple[SerializingFunction, DeserializingFunction]
52+
"""
4253
return DubboTransportService.create_serialization_functions(**kwargs)
4354

4455
@classmethod
4556
def _infer_types_from_method(cls, method: Callable) -> tuple:
57+
"""
58+
Infer method name, parameter types, and return type from a callable
59+
:param method: the method to analyze
60+
:type method: Callable
61+
:return: tuple of method name, parameter types, return type
62+
:rtype: Tuple[str, List[Type], Type]
63+
"""
4664
try:
4765
type_hints = get_type_hints(method)
4866
sig = inspect.signature(method)
4967
method_name = method.__name__
5068
params = list(sig.parameters.values())
69+
5170
if params and params[0].name == "self":
52-
params = params[1:]
71+
raise RpcMethodConfigurationError(
72+
f"Method '{method_name}' appears to be an unbound method with 'self' parameter. "
73+
"RPC methods should be bound methods (e.g., instance.method) or standalone functions. "
74+
"If you're registering a class method, ensure you pass a bound method: "
75+
"RpcMethodHandler.unary(instance.method) not RpcMethodHandler.unary(Class.method)"
76+
)
5377

5478
params_types = [type_hints.get(p.name, Any) for p in params]
5579
return_type = type_hints.get("return", Any)
5680
return method_name, params_types, return_type
81+
except RpcMethodConfigurationError:
82+
raise
5783
except Exception:
5884
return method.__name__, [Any], Any
5985

@@ -70,6 +96,20 @@ def _create_method_descriptor(
7096
return_decoder: Optional[SerializingFunction] = None,
7197
**kwargs,
7298
) -> MethodDescriptor:
99+
"""
100+
Create a MethodDescriptor with serialization configuration
101+
:param method: the actual function/method
102+
:param method_name: RPC method name
103+
:param params_types: parameter type hints
104+
:param return_type: return type hint
105+
:param rpc_type: type of RPC (unary, stream, etc.)
106+
:param codec: serialization codec (json, pb, etc.)
107+
:param param_encoder: deserialization function
108+
:param return_decoder: serialization function
109+
:param kwargs: additional codec args
110+
:return: MethodDescriptor instance
111+
:rtype: MethodDescriptor
112+
"""
73113
if param_encoder is None or return_decoder is None:
74114
codec_kwargs = {
75115
"transport_type": codec or "json",
@@ -101,6 +141,18 @@ def unary(
101141
response_serializer: Optional[SerializingFunction] = None,
102142
**kwargs,
103143
) -> "RpcMethodHandler":
144+
"""
145+
Register a unary RPC method handler
146+
:param method: the callable function
147+
:param method_name: RPC method name
148+
:param params_types: input types
149+
:param return_type: output type
150+
:param codec: serialization codec
151+
:param request_deserializer: custom deserializer
152+
:param response_serializer: custom serializer
153+
:return: RpcMethodHandler instance
154+
:rtype: RpcMethodHandler
155+
"""
104156
inferred_name, inferred_param_types, inferred_return_type = cls._infer_types_from_method(method)
105157
resolved_method_name = method_name or inferred_name
106158
resolved_param_types = params_types or inferred_param_types
@@ -133,6 +185,18 @@ def client_stream(
133185
response_serializer: Optional[SerializingFunction] = None,
134186
**kwargs,
135187
) -> "RpcMethodHandler":
188+
"""
189+
Register a client-streaming RPC method handler
190+
:param method: the callable function
191+
:param method_name: RPC method name
192+
:param params_types: input types
193+
:param return_type: output type
194+
:param codec: serialization codec
195+
:param request_deserializer: custom deserializer
196+
:param response_serializer: custom serializer
197+
:return: RpcMethodHandler instance
198+
:rtype: RpcMethodHandler
199+
"""
136200
inferred_name, inferred_param_types, inferred_return_type = cls._infer_types_from_method(method)
137201
resolved_method_name = method_name or inferred_name
138202
resolved_param_types = params_types or inferred_param_types
@@ -165,6 +229,18 @@ def server_stream(
165229
response_serializer: Optional[SerializingFunction] = None,
166230
**kwargs,
167231
) -> "RpcMethodHandler":
232+
"""
233+
Register a server-streaming RPC method handler
234+
:param method: the callable function
235+
:param method_name: RPC method name
236+
:param params_types: input types
237+
:param return_type: output type
238+
:param codec: serialization codec
239+
:param request_deserializer: custom deserializer
240+
:param response_serializer: custom serializer
241+
:return: RpcMethodHandler instance
242+
:rtype: RpcMethodHandler
243+
"""
168244
inferred_name, inferred_param_types, inferred_return_type = cls._infer_types_from_method(method)
169245
resolved_method_name = method_name or inferred_name
170246
resolved_param_types = params_types or inferred_param_types
@@ -197,6 +273,18 @@ def bi_stream(
197273
response_serializer: Optional[SerializingFunction] = None,
198274
**kwargs,
199275
) -> "RpcMethodHandler":
276+
"""
277+
Register a bidirectional streaming RPC method handler
278+
:param method: the callable function
279+
:param method_name: RPC method name
280+
:param params_types: input types
281+
:param return_type: output type
282+
:param codec: serialization codec
283+
:param request_deserializer: custom deserializer
284+
:param response_serializer: custom serializer
285+
:return: RpcMethodHandler instance
286+
:rtype: RpcMethodHandler
287+
"""
200288
inferred_name, inferred_param_types, inferred_return_type = cls._infer_types_from_method(method)
201289
resolved_method_name = method_name or inferred_name
202290
resolved_param_types = params_types or inferred_param_types
@@ -219,9 +307,20 @@ def bi_stream(
219307

220308

221309
class RpcServiceHandler:
310+
"""
311+
Rpc service handler that maps method names to their corresponding RpcMethodHandler.
312+
"""
313+
222314
__slots__ = ["_service_name", "_method_handlers"]
223315

224-
def __init__(self, service_name: str, method_handlers: list[RpcMethodHandler]):
316+
def __init__(self, service_name: str, method_handlers: List[RpcMethodHandler]):
317+
"""
318+
Initialize the RpcServiceHandler
319+
:param service_name: the name of the service.
320+
:type service_name: str
321+
:param method_handlers: list of RpcMethodHandler instances
322+
:type method_handlers: List[RpcMethodHandler]
323+
"""
225324
self._service_name = service_name
226325
self._method_handlers: dict[str, RpcMethodHandler] = {}
227326

@@ -231,8 +330,18 @@ def __init__(self, service_name: str, method_handlers: list[RpcMethodHandler]):
231330

232331
@property
233332
def service_name(self) -> str:
333+
"""
334+
Get the service name
335+
:return: the service name
336+
:rtype: str
337+
"""
234338
return self._service_name
235339

236340
@property
237341
def method_handlers(self) -> dict[str, RpcMethodHandler]:
238-
return self._method_handlers
342+
"""
343+
Get the registered RPC method handlers
344+
:return: mapping of method names to handlers
345+
:rtype: Dict[str, RpcMethodHandler]
346+
"""
347+
return self._method_handlers

src/dubbo/server.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,4 +81,4 @@ def start(self):
8181

8282
self._protocol.export(self._url)
8383

84-
self._exported = True
84+
self._exported = True

0 commit comments

Comments
 (0)