Home | History | Annotate | Download | only in protobuf
      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 
     31 """DEPRECATED:  Declares the RPC service interfaces.
     32 
     33 This module declares the abstract interfaces underlying proto2 RPC
     34 services.  These are intended to be independent of any particular RPC
     35 implementation, so that proto2 services can be used on top of a variety
     36 of implementations.  Starting with version 2.3.0, RPC implementations should
     37 not try to build on these, but should instead provide code generator plugins
     38 which generate code specific to the particular RPC implementation.  This way
     39 the generated code can be more appropriate for the implementation in use
     40 and can avoid unnecessary layers of indirection.
     41 """
     42 
     43 __author__ = 'petar (at] google.com (Petar Petrov)'
     44 
     45 
     46 class RpcException(Exception):
     47   """Exception raised on failed blocking RPC method call."""
     48   pass
     49 
     50 
     51 class Service(object):
     52 
     53   """Abstract base interface for protocol-buffer-based RPC services.
     54 
     55   Services themselves are abstract classes (implemented either by servers or as
     56   stubs), but they subclass this base interface. The methods of this
     57   interface can be used to call the methods of the service without knowing
     58   its exact type at compile time (analogous to the Message interface).
     59   """
     60 
     61   def GetDescriptor():
     62     """Retrieves this service's descriptor."""
     63     raise NotImplementedError
     64 
     65   def CallMethod(self, method_descriptor, rpc_controller,
     66                  request, done):
     67     """Calls a method of the service specified by method_descriptor.
     68 
     69     If "done" is None then the call is blocking and the response
     70     message will be returned directly.  Otherwise the call is asynchronous
     71     and "done" will later be called with the response value.
     72 
     73     In the blocking case, RpcException will be raised on error.
     74 
     75     Preconditions:
     76     * method_descriptor.service == GetDescriptor
     77     * request is of the exact same classes as returned by
     78       GetRequestClass(method).
     79     * After the call has started, the request must not be modified.
     80     * "rpc_controller" is of the correct type for the RPC implementation being
     81       used by this Service.  For stubs, the "correct type" depends on the
     82       RpcChannel which the stub is using.
     83 
     84     Postconditions:
     85     * "done" will be called when the method is complete.  This may be
     86       before CallMethod() returns or it may be at some point in the future.
     87     * If the RPC failed, the response value passed to "done" will be None.
     88       Further details about the failure can be found by querying the
     89       RpcController.
     90     """
     91     raise NotImplementedError
     92 
     93   def GetRequestClass(self, method_descriptor):
     94     """Returns the class of the request message for the specified method.
     95 
     96     CallMethod() requires that the request is of a particular subclass of
     97     Message. GetRequestClass() gets the default instance of this required
     98     type.
     99 
    100     Example:
    101       method = service.GetDescriptor().FindMethodByName("Foo")
    102       request = stub.GetRequestClass(method)()
    103       request.ParseFromString(input)
    104       service.CallMethod(method, request, callback)
    105     """
    106     raise NotImplementedError
    107 
    108   def GetResponseClass(self, method_descriptor):
    109     """Returns the class of the response message for the specified method.
    110 
    111     This method isn't really needed, as the RpcChannel's CallMethod constructs
    112     the response protocol message. It's provided anyway in case it is useful
    113     for the caller to know the response type in advance.
    114     """
    115     raise NotImplementedError
    116 
    117 
    118 class RpcController(object):
    119 
    120   """An RpcController mediates a single method call.
    121 
    122   The primary purpose of the controller is to provide a way to manipulate
    123   settings specific to the RPC implementation and to find out about RPC-level
    124   errors. The methods provided by the RpcController interface are intended
    125   to be a "least common denominator" set of features which we expect all
    126   implementations to support.  Specific implementations may provide more
    127   advanced features (e.g. deadline propagation).
    128   """
    129 
    130   # Client-side methods below
    131 
    132   def Reset(self):
    133     """Resets the RpcController to its initial state.
    134 
    135     After the RpcController has been reset, it may be reused in
    136     a new call. Must not be called while an RPC is in progress.
    137     """
    138     raise NotImplementedError
    139 
    140   def Failed(self):
    141     """Returns true if the call failed.
    142 
    143     After a call has finished, returns true if the call failed.  The possible
    144     reasons for failure depend on the RPC implementation.  Failed() must not
    145     be called before a call has finished.  If Failed() returns true, the
    146     contents of the response message are undefined.
    147     """
    148     raise NotImplementedError
    149 
    150   def ErrorText(self):
    151     """If Failed is true, returns a human-readable description of the error."""
    152     raise NotImplementedError
    153 
    154   def StartCancel(self):
    155     """Initiate cancellation.
    156 
    157     Advises the RPC system that the caller desires that the RPC call be
    158     canceled.  The RPC system may cancel it immediately, may wait awhile and
    159     then cancel it, or may not even cancel the call at all.  If the call is
    160     canceled, the "done" callback will still be called and the RpcController
    161     will indicate that the call failed at that time.
    162     """
    163     raise NotImplementedError
    164 
    165   # Server-side methods below
    166 
    167   def SetFailed(self, reason):
    168     """Sets a failure reason.
    169 
    170     Causes Failed() to return true on the client side.  "reason" will be
    171     incorporated into the message returned by ErrorText().  If you find
    172     you need to return machine-readable information about failures, you
    173     should incorporate it into your response protocol buffer and should
    174     NOT call SetFailed().
    175     """
    176     raise NotImplementedError
    177 
    178   def IsCanceled(self):
    179     """Checks if the client cancelled the RPC.
    180 
    181     If true, indicates that the client canceled the RPC, so the server may
    182     as well give up on replying to it.  The server should still call the
    183     final "done" callback.
    184     """
    185     raise NotImplementedError
    186 
    187   def NotifyOnCancel(self, callback):
    188     """Sets a callback to invoke on cancel.
    189 
    190     Asks that the given callback be called when the RPC is canceled.  The
    191     callback will always be called exactly once.  If the RPC completes without
    192     being canceled, the callback will be called after completion.  If the RPC
    193     has already been canceled when NotifyOnCancel() is called, the callback
    194     will be called immediately.
    195 
    196     NotifyOnCancel() must be called no more than once per request.
    197     """
    198     raise NotImplementedError
    199 
    200 
    201 class RpcChannel(object):
    202 
    203   """Abstract interface for an RPC channel.
    204 
    205   An RpcChannel represents a communication line to a service which can be used
    206   to call that service's methods.  The service may be running on another
    207   machine. Normally, you should not use an RpcChannel directly, but instead
    208   construct a stub {@link Service} wrapping it.  Example:
    209 
    210   Example:
    211     RpcChannel channel = rpcImpl.Channel("remotehost.example.com:1234")
    212     RpcController controller = rpcImpl.Controller()
    213     MyService service = MyService_Stub(channel)
    214     service.MyMethod(controller, request, callback)
    215   """
    216 
    217   def CallMethod(self, method_descriptor, rpc_controller,
    218                  request, response_class, done):
    219     """Calls the method identified by the descriptor.
    220 
    221     Call the given method of the remote service.  The signature of this
    222     procedure looks the same as Service.CallMethod(), but the requirements
    223     are less strict in one important way:  the request object doesn't have to
    224     be of any specific class as long as its descriptor is method.input_type.
    225     """
    226     raise NotImplementedError
    227