service.py 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. # Protocol Buffers - Google's data interchange format
  2. # Copyright 2008 Google Inc. All rights reserved.
  3. # http://code.google.com/p/protobuf/
  4. #
  5. # Redistribution and use in source and binary forms, with or without
  6. # modification, are permitted provided that the following conditions are
  7. # met:
  8. #
  9. # * Redistributions of source code must retain the above copyright
  10. # notice, this list of conditions and the following disclaimer.
  11. # * Redistributions in binary form must reproduce the above
  12. # copyright notice, this list of conditions and the following disclaimer
  13. # in the documentation and/or other materials provided with the
  14. # distribution.
  15. # * Neither the name of Google Inc. nor the names of its
  16. # contributors may be used to endorse or promote products derived from
  17. # this software without specific prior written permission.
  18. #
  19. # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  20. # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  21. # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  22. # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  23. # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  24. # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  25. # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  26. # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  27. # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  28. # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  29. # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  30. """Declares the RPC service interfaces.
  31. This module declares the abstract interfaces underlying proto2 RPC
  32. services. These are intented to be independent of any particular RPC
  33. implementation, so that proto2 services can be used on top of a variety
  34. of implementations.
  35. """
  36. __author__ = 'petar@google.com (Petar Petrov)'
  37. class Service(object):
  38. """Abstract base interface for protocol-buffer-based RPC services.
  39. Services themselves are abstract classes (implemented either by servers or as
  40. stubs), but they subclass this base interface. The methods of this
  41. interface can be used to call the methods of the service without knowing
  42. its exact type at compile time (analogous to the Message interface).
  43. """
  44. def GetDescriptor(self):
  45. """Retrieves this service's descriptor."""
  46. raise NotImplementedError
  47. def CallMethod(self, method_descriptor, rpc_controller,
  48. request, done):
  49. """Calls a method of the service specified by method_descriptor.
  50. Preconditions:
  51. * method_descriptor.service == GetDescriptor
  52. * request is of the exact same classes as returned by
  53. GetRequestClass(method).
  54. * After the call has started, the request must not be modified.
  55. * "rpc_controller" is of the correct type for the RPC implementation being
  56. used by this Service. For stubs, the "correct type" depends on the
  57. RpcChannel which the stub is using.
  58. Postconditions:
  59. * "done" will be called when the method is complete. This may be
  60. before CallMethod() returns or it may be at some point in the future.
  61. """
  62. raise NotImplementedError
  63. def GetRequestClass(self, method_descriptor):
  64. """Returns the class of the request message for the specified method.
  65. CallMethod() requires that the request is of a particular subclass of
  66. Message. GetRequestClass() gets the default instance of this required
  67. type.
  68. Example:
  69. method = service.GetDescriptor().FindMethodByName("Foo")
  70. request = stub.GetRequestClass(method)()
  71. request.ParseFromString(input)
  72. service.CallMethod(method, request, callback)
  73. """
  74. raise NotImplementedError
  75. def GetResponseClass(self, method_descriptor):
  76. """Returns the class of the response message for the specified method.
  77. This method isn't really needed, as the RpcChannel's CallMethod constructs
  78. the response protocol message. It's provided anyway in case it is useful
  79. for the caller to know the response type in advance.
  80. """
  81. raise NotImplementedError
  82. class RpcController(object):
  83. """An RpcController mediates a single method call.
  84. The primary purpose of the controller is to provide a way to manipulate
  85. settings specific to the RPC implementation and to find out about RPC-level
  86. errors. The methods provided by the RpcController interface are intended
  87. to be a "least common denominator" set of features which we expect all
  88. implementations to support. Specific implementations may provide more
  89. advanced features (e.g. deadline propagation).
  90. """
  91. # Client-side methods below
  92. def Reset(self):
  93. """Resets the RpcController to its initial state.
  94. After the RpcController has been reset, it may be reused in
  95. a new call. Must not be called while an RPC is in progress.
  96. """
  97. raise NotImplementedError
  98. def Failed(self):
  99. """Returns true if the call failed.
  100. After a call has finished, returns true if the call failed. The possible
  101. reasons for failure depend on the RPC implementation. Failed() must not
  102. be called before a call has finished. If Failed() returns true, the
  103. contents of the response message are undefined.
  104. """
  105. raise NotImplementedError
  106. def ErrorText(self):
  107. """If Failed is true, returns a human-readable description of the error."""
  108. raise NotImplementedError
  109. def StartCancel(self):
  110. """Initiate cancellation.
  111. Advises the RPC system that the caller desires that the RPC call be
  112. canceled. The RPC system may cancel it immediately, may wait awhile and
  113. then cancel it, or may not even cancel the call at all. If the call is
  114. canceled, the "done" callback will still be called and the RpcController
  115. will indicate that the call failed at that time.
  116. """
  117. raise NotImplementedError
  118. # Server-side methods below
  119. def SetFailed(self, reason):
  120. """Sets a failure reason.
  121. Causes Failed() to return true on the client side. "reason" will be
  122. incorporated into the message returned by ErrorText(). If you find
  123. you need to return machine-readable information about failures, you
  124. should incorporate it into your response protocol buffer and should
  125. NOT call SetFailed().
  126. """
  127. raise NotImplementedError
  128. def IsCanceled(self):
  129. """Checks if the client cancelled the RPC.
  130. If true, indicates that the client canceled the RPC, so the server may
  131. as well give up on replying to it. The server should still call the
  132. final "done" callback.
  133. """
  134. raise NotImplementedError
  135. def NotifyOnCancel(self, callback):
  136. """Sets a callback to invoke on cancel.
  137. Asks that the given callback be called when the RPC is canceled. The
  138. callback will always be called exactly once. If the RPC completes without
  139. being canceled, the callback will be called after completion. If the RPC
  140. has already been canceled when NotifyOnCancel() is called, the callback
  141. will be called immediately.
  142. NotifyOnCancel() must be called no more than once per request.
  143. """
  144. raise NotImplementedError
  145. class RpcChannel(object):
  146. """Abstract interface for an RPC channel.
  147. An RpcChannel represents a communication line to a service which can be used
  148. to call that service's methods. The service may be running on another
  149. machine. Normally, you should not use an RpcChannel directly, but instead
  150. construct a stub {@link Service} wrapping it. Example:
  151. Example:
  152. RpcChannel channel = rpcImpl.Channel("remotehost.example.com:1234")
  153. RpcController controller = rpcImpl.Controller()
  154. MyService service = MyService_Stub(channel)
  155. service.MyMethod(controller, request, callback)
  156. """
  157. def CallMethod(self, method_descriptor, rpc_controller,
  158. request, response_class, done):
  159. """Calls the method identified by the descriptor.
  160. Call the given method of the remote service. The signature of this
  161. procedure looks the same as Service.CallMethod(), but the requirements
  162. are less strict in one important way: the request object doesn't have to
  163. be of any specific class as long as its descriptor is method.input_type.
  164. """
  165. raise NotImplementedError