1 # Protocol Buffers - Google's data interchange format
2 # Copyright 2008 Google Inc.
3 # http://code.google.com/p/protobuf/
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
9 # http://www.apache.org/licenses/LICENSE-2.0
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.
17 """Declares the RPC service interfaces.
19 This module declares the abstract interfaces underlying proto2 RPC
20 services. These are intented to be independent of any particular RPC
21 implementation, so that proto2 services can be used on top of a variety
25 __author__
= 'petar@google.com (Petar Petrov)'
28 class Service(object):
30 """Abstract base interface for protocol-buffer-based RPC services.
32 Services themselves are abstract classes (implemented either by servers or as
33 stubs), but they subclass this base interface. The methods of this
34 interface can be used to call the methods of the service without knowing
35 its exact type at compile time (analogous to the Message interface).
38 def GetDescriptor(self
):
39 """Retrieves this service's descriptor."""
40 raise NotImplementedError
42 def CallMethod(self
, method_descriptor
, rpc_controller
,
44 """Calls a method of the service specified by method_descriptor.
47 * method_descriptor.service == GetDescriptor
48 * request is of the exact same classes as returned by
49 GetRequestClass(method).
50 * After the call has started, the request must not be modified.
51 * "rpc_controller" is of the correct type for the RPC implementation being
52 used by this Service. For stubs, the "correct type" depends on the
53 RpcChannel which the stub is using.
56 * "done" will be called when the method is complete. This may be
57 before CallMethod() returns or it may be at some point in the future.
59 raise NotImplementedError
61 def GetRequestClass(self
, method_descriptor
):
62 """Returns the class of the request message for the specified method.
64 CallMethod() requires that the request is of a particular subclass of
65 Message. GetRequestClass() gets the default instance of this required
69 method = service.GetDescriptor().FindMethodByName("Foo")
70 request = stub.GetRequestClass(method)()
71 request.ParseFromString(input)
72 service.CallMethod(method, request, callback)
74 raise NotImplementedError
76 def GetResponseClass(self
, method_descriptor
):
77 """Returns the class of the response message for the specified method.
79 This method isn't really needed, as the RpcChannel's CallMethod constructs
80 the response protocol message. It's provided anyway in case it is useful
81 for the caller to know the response type in advance.
83 raise NotImplementedError
86 class RpcController(object):
88 """Abstract interface for an RPC channel.
90 An RpcChannel represents a communication line to a service which can be used
91 to call that service's methods. The service may be running on another
92 machine. Normally, you should not use an RpcChannel directly, but instead
93 construct a stub {@link Service} wrapping it. Example:
96 RpcChannel channel = rpcImpl.Channel("remotehost.example.com:1234")
97 RpcController controller = rpcImpl.Controller()
98 MyService service = MyService_Stub(channel)
99 service.MyMethod(controller, request, callback)
102 # Client-side methods below
105 """Resets the RpcController to its initial state.
107 After the RpcController has been reset, it may be reused in
108 a new call. Must not be called while an RPC is in progress.
110 raise NotImplementedError
113 """Returns true if the call failed.
115 After a call has finished, returns true if the call failed. The possible
116 reasons for failure depend on the RPC implementation. Failed() must not
117 be called before a call has finished. If Failed() returns true, the
118 contents of the response message are undefined.
120 raise NotImplementedError
123 """If Failed is true, returns a human-readable description of the error."""
124 raise NotImplementedError
126 def StartCancel(self
):
127 """Initiate cancellation.
129 Advises the RPC system that the caller desires that the RPC call be
130 canceled. The RPC system may cancel it immediately, may wait awhile and
131 then cancel it, or may not even cancel the call at all. If the call is
132 canceled, the "done" callback will still be called and the RpcController
133 will indicate that the call failed at that time.
135 raise NotImplementedError
137 # Server-side methods below
139 def SetFailed(self
, reason
):
140 """Sets a failure reason.
142 Causes Failed() to return true on the client side. "reason" will be
143 incorporated into the message returned by ErrorText(). If you find
144 you need to return machine-readable information about failures, you
145 should incorporate it into your response protocol buffer and should
146 NOT call SetFailed().
148 raise NotImplementedError
150 def IsCanceled(self
):
151 """Checks if the client cancelled the RPC.
153 If true, indicates that the client canceled the RPC, so the server may
154 as well give up on replying to it. The server should still call the
155 final "done" callback.
157 raise NotImplementedError
159 def NotifyOnCancel(self
, callback
):
160 """Sets a callback to invoke on cancel.
162 Asks that the given callback be called when the RPC is canceled. The
163 callback will always be called exactly once. If the RPC completes without
164 being canceled, the callback will be called after completion. If the RPC
165 has already been canceled when NotifyOnCancel() is called, the callback
166 will be called immediately.
168 NotifyOnCancel() must be called no more than once per request.
170 raise NotImplementedError
173 class RpcChannel(object):
175 """An RpcController mediates a single method call.
177 The primary purpose of the controller is to provide a way to manipulate
178 settings specific to the RPC implementation and to find out about RPC-level
179 errors. The methods provided by the RpcController interface are intended
180 to be a "least common denominator" set of features which we expect all
181 implementations to support. Specific implementations may provide more
182 advanced features (e.g. deadline propagation).
185 def CallMethod(self
, method_descriptor
, rpc_controller
,
186 request
, response_class
, done
):
187 """Calls the method identified by the descriptor.
189 Call the given method of the remote service. The signature of this
190 procedure looks the same as Service.CallMethod(), but the requirements
191 are less strict in one important way: the request object doesn't have to
192 be of any specific class as long as its descriptor is method.input_type.
194 raise NotImplementedError