mirror of https://github.com/grpc/grpc.git
commit
0660eaca00
51 changed files with 2039 additions and 255 deletions
@ -0,0 +1,30 @@ |
||||
# Copyright 2015, Google Inc. |
||||
# All rights reserved. |
||||
# |
||||
# Redistribution and use in source and binary forms, with or without |
||||
# modification, are permitted provided that the following conditions are |
||||
# met: |
||||
# |
||||
# * Redistributions of source code must retain the above copyright |
||||
# notice, this list of conditions and the following disclaimer. |
||||
# * Redistributions in binary form must reproduce the above |
||||
# copyright notice, this list of conditions and the following disclaimer |
||||
# in the documentation and/or other materials provided with the |
||||
# distribution. |
||||
# * Neither the name of Google Inc. nor the names of its |
||||
# contributors may be used to endorse or promote products derived from |
||||
# this software without specific prior written permission. |
||||
# |
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
|
||||
|
@ -0,0 +1,933 @@ |
||||
# Copyright 2015, Google Inc. |
||||
# All rights reserved. |
||||
# |
||||
# Redistribution and use in source and binary forms, with or without |
||||
# modification, are permitted provided that the following conditions are |
||||
# met: |
||||
# |
||||
# * Redistributions of source code must retain the above copyright |
||||
# notice, this list of conditions and the following disclaimer. |
||||
# * Redistributions in binary form must reproduce the above |
||||
# copyright notice, this list of conditions and the following disclaimer |
||||
# in the documentation and/or other materials provided with the |
||||
# distribution. |
||||
# * Neither the name of Google Inc. nor the names of its |
||||
# contributors may be used to endorse or promote products derived from |
||||
# this software without specific prior written permission. |
||||
# |
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
|
||||
"""Interfaces defining the Face layer of RPC Framework.""" |
||||
|
||||
import abc |
||||
import collections |
||||
import enum |
||||
|
||||
# cardinality, style, abandonment, future, and stream are |
||||
# referenced from specification in this module. |
||||
from grpc.framework.common import cardinality # pylint: disable=unused-import |
||||
from grpc.framework.common import style # pylint: disable=unused-import |
||||
from grpc.framework.foundation import abandonment # pylint: disable=unused-import |
||||
from grpc.framework.foundation import future # pylint: disable=unused-import |
||||
from grpc.framework.foundation import stream # pylint: disable=unused-import |
||||
|
||||
|
||||
class NoSuchMethodError(Exception): |
||||
"""Raised by customer code to indicate an unrecognized method. |
||||
|
||||
Attributes: |
||||
group: The group of the unrecognized method. |
||||
name: The name of the unrecognized method. |
||||
""" |
||||
|
||||
def __init__(self, group, method): |
||||
"""Constructor. |
||||
|
||||
Args: |
||||
group: The group identifier of the unrecognized RPC name. |
||||
method: The method identifier of the unrecognized RPC name. |
||||
""" |
||||
super(NoSuchMethodError, self).__init__() |
||||
self.group = group |
||||
self.method = method |
||||
|
||||
def __repr__(self): |
||||
return 'face.NoSuchMethodError(%s, %s)' % (self.group, self.method,) |
||||
|
||||
|
||||
class Abortion( |
||||
collections.namedtuple( |
||||
'Abortion', |
||||
('kind', 'initial_metadata', 'terminal_metadata', 'code', 'details',))): |
||||
"""A value describing RPC abortion. |
||||
|
||||
Attributes: |
||||
kind: A Kind value identifying how the RPC failed. |
||||
initial_metadata: The initial metadata from the other side of the RPC or |
||||
None if no initial metadata value was received. |
||||
terminal_metadata: The terminal metadata from the other side of the RPC or |
||||
None if no terminal metadata value was received. |
||||
code: The code value from the other side of the RPC or None if no code value |
||||
was received. |
||||
details: The details value from the other side of the RPC or None if no |
||||
details value was received. |
||||
""" |
||||
|
||||
@enum.unique |
||||
class Kind(enum.Enum): |
||||
"""Types of RPC abortion.""" |
||||
|
||||
CANCELLED = 'cancelled' |
||||
EXPIRED = 'expired' |
||||
LOCAL_SHUTDOWN = 'local shutdown' |
||||
REMOTE_SHUTDOWN = 'remote shutdown' |
||||
NETWORK_FAILURE = 'network failure' |
||||
LOCAL_FAILURE = 'local failure' |
||||
REMOTE_FAILURE = 'remote failure' |
||||
|
||||
|
||||
class AbortionError(Exception): |
||||
"""Common super type for exceptions indicating RPC abortion. |
||||
|
||||
initial_metadata: The initial metadata from the other side of the RPC or |
||||
None if no initial metadata value was received. |
||||
terminal_metadata: The terminal metadata from the other side of the RPC or |
||||
None if no terminal metadata value was received. |
||||
code: The code value from the other side of the RPC or None if no code value |
||||
was received. |
||||
details: The details value from the other side of the RPC or None if no |
||||
details value was received. |
||||
""" |
||||
__metaclass__ = abc.ABCMeta |
||||
|
||||
def __init__(self, initial_metadata, terminal_metadata, code, details): |
||||
super(AbortionError, self).__init__() |
||||
self.initial_metadata = initial_metadata |
||||
self.terminal_metadata = terminal_metadata |
||||
self.code = code |
||||
self.details = details |
||||
|
||||
|
||||
class CancellationError(AbortionError): |
||||
"""Indicates that an RPC has been cancelled.""" |
||||
|
||||
|
||||
class ExpirationError(AbortionError): |
||||
"""Indicates that an RPC has expired ("timed out").""" |
||||
|
||||
|
||||
class LocalShutdownError(AbortionError): |
||||
"""Indicates that an RPC has terminated due to local shutdown of RPCs.""" |
||||
|
||||
|
||||
class RemoteShutdownError(AbortionError): |
||||
"""Indicates that an RPC has terminated due to remote shutdown of RPCs.""" |
||||
|
||||
|
||||
class NetworkError(AbortionError): |
||||
"""Indicates that some error occurred on the network.""" |
||||
|
||||
|
||||
class LocalError(AbortionError): |
||||
"""Indicates that an RPC has terminated due to a local defect.""" |
||||
|
||||
|
||||
class RemoteError(AbortionError): |
||||
"""Indicates that an RPC has terminated due to a remote defect.""" |
||||
|
||||
|
||||
class RpcContext(object): |
||||
"""Provides RPC-related information and action.""" |
||||
__metaclass__ = abc.ABCMeta |
||||
|
||||
@abc.abstractmethod |
||||
def is_active(self): |
||||
"""Describes whether the RPC is active or has terminated.""" |
||||
raise NotImplementedError() |
||||
|
||||
@abc.abstractmethod |
||||
def time_remaining(self): |
||||
"""Describes the length of allowed time remaining for the RPC. |
||||
|
||||
Returns: |
||||
A nonnegative float indicating the length of allowed time in seconds |
||||
remaining for the RPC to complete before it is considered to have timed |
||||
out. |
||||
""" |
||||
raise NotImplementedError() |
||||
|
||||
@abc.abstractmethod |
||||
def add_abortion_callback(self, abortion_callback): |
||||
"""Registers a callback to be called if the RPC is aborted. |
||||
|
||||
Args: |
||||
abortion_callback: A callable to be called and passed an Abortion value |
||||
in the event of RPC abortion. |
||||
""" |
||||
raise NotImplementedError() |
||||
|
||||
@abc.abstractmethod |
||||
def cancel(self): |
||||
"""Cancels the RPC. |
||||
|
||||
Idempotent and has no effect if the RPC has already terminated. |
||||
""" |
||||
raise NotImplementedError() |
||||
|
||||
|
||||
class Call(RpcContext): |
||||
"""Invocation-side utility object for an RPC.""" |
||||
__metaclass__ = abc.ABCMeta |
||||
|
||||
@abc.abstractmethod |
||||
def initial_metadata(self): |
||||
"""Accesses the initial metadata from the service-side of the RPC. |
||||
|
||||
This method blocks until the value is available or is known not to have been |
||||
emitted from the service-side of the RPC. |
||||
|
||||
Returns: |
||||
The initial metadata object emitted by the service-side of the RPC, or |
||||
None if there was no such value. |
||||
""" |
||||
raise NotImplementedError() |
||||
|
||||
@abc.abstractmethod |
||||
def terminal_metadata(self): |
||||
"""Accesses the terminal metadata from the service-side of the RPC. |
||||
|
||||
This method blocks until the value is available or is known not to have been |
||||
emitted from the service-side of the RPC. |
||||
|
||||
Returns: |
||||
The terminal metadata object emitted by the service-side of the RPC, or |
||||
None if there was no such value. |
||||
""" |
||||
raise NotImplementedError() |
||||
|
||||
@abc.abstractmethod |
||||
def code(self): |
||||
"""Accesses the code emitted by the service-side of the RPC. |
||||
|
||||
This method blocks until the value is available or is known not to have been |
||||
emitted from the service-side of the RPC. |
||||
|
||||
Returns: |
||||
The code object emitted by the service-side of the RPC, or None if there |
||||
was no such value. |
||||
""" |
||||
raise NotImplementedError() |
||||
|
||||
@abc.abstractmethod |
||||
def details(self): |
||||
"""Accesses the details value emitted by the service-side of the RPC. |
||||
|
||||
This method blocks until the value is available or is known not to have been |
||||
emitted from the service-side of the RPC. |
||||
|
||||
Returns: |
||||
The details value emitted by the service-side of the RPC, or None if there |
||||
was no such value. |
||||
""" |
||||
raise NotImplementedError() |
||||
|
||||
|
||||
class ServicerContext(RpcContext): |
||||
"""A context object passed to method implementations.""" |
||||
__metaclass__ = abc.ABCMeta |
||||
|
||||
@abc.abstractmethod |
||||
def invocation_metadata(self): |
||||
"""Accesses the metadata from the invocation-side of the RPC. |
||||
|
||||
This method blocks until the value is available or is known not to have been |
||||
emitted from the invocation-side of the RPC. |
||||
|
||||
Returns: |
||||
The metadata object emitted by the invocation-side of the RPC, or None if |
||||
there was no such value. |
||||
""" |
||||
raise NotImplementedError() |
||||
|
||||
@abc.abstractmethod |
||||
def initial_metadata(self, initial_metadata): |
||||
"""Accepts the service-side initial metadata value of the RPC. |
||||
|
||||
This method need not be called by method implementations if they have no |
||||
service-side initial metadata to transmit. |
||||
|
||||
Args: |
||||
initial_metadata: The service-side initial metadata value of the RPC to |
||||
be transmitted to the invocation side of the RPC. |
||||
""" |
||||
raise NotImplementedError() |
||||
|
||||
@abc.abstractmethod |
||||
def terminal_metadata(self, terminal_metadata): |
||||
"""Accepts the service-side terminal metadata value of the RPC. |
||||
|
||||
This method need not be called by method implementations if they have no |
||||
service-side terminal metadata to transmit. |
||||
|
||||
Args: |
||||
terminal_metadata: The service-side terminal metadata value of the RPC to |
||||
be transmitted to the invocation side of the RPC. |
||||
""" |
||||
raise NotImplementedError() |
||||
|
||||
@abc.abstractmethod |
||||
def code(self, code): |
||||
"""Accepts the service-side code of the RPC. |
||||
|
||||
This method need not be called by method implementations if they have no |
||||
code to transmit. |
||||
|
||||
Args: |
||||
code: The code of the RPC to be transmitted to the invocation side of the |
||||
RPC. |
||||
""" |
||||
raise NotImplementedError() |
||||
|
||||
@abc.abstractmethod |
||||
def details(self, details): |
||||
"""Accepts the service-side details of the RPC. |
||||
|
||||
This method need not be called by method implementations if they have no |
||||
service-side details to transmit. |
||||
|
||||
Args: |
||||
details: The service-side details value of the RPC to be transmitted to |
||||
the invocation side of the RPC. |
||||
""" |
||||
raise NotImplementedError() |
||||
|
||||
|
||||
class ResponseReceiver(object): |
||||
"""Invocation-side object used to accept the output of an RPC.""" |
||||
__metaclass__ = abc.ABCMeta |
||||
|
||||
@abc.abstractmethod |
||||
def initial_metadata(self, initial_metadata): |
||||
"""Receives the initial metadata from the service-side of the RPC. |
||||
|
||||
Args: |
||||
initial_metadata: The initial metadata object emitted from the |
||||
service-side of the RPC. |
||||
""" |
||||
raise NotImplementedError() |
||||
|
||||
@abc.abstractmethod |
||||
def response(self, response): |
||||
"""Receives a response from the service-side of the RPC. |
||||
|
||||
Args: |
||||
response: A response object emitted from the service-side of the RPC. |
||||
""" |
||||
raise NotImplementedError() |
||||
|
||||
@abc.abstractmethod |
||||
def complete(self, terminal_metadata, code, details): |
||||
"""Receives the completion values emitted from the service-side of the RPC. |
||||
|
||||
Args: |
||||
terminal_metadata: The terminal metadata object emitted from the |
||||
service-side of the RPC. |
||||
code: The code object emitted from the service-side of the RPC. |
||||
details: The details object emitted from the service-side of the RPC. |
||||
""" |
||||
raise NotImplementedError() |
||||
|
||||
|
||||
class UnaryUnaryMultiCallable(object): |
||||
"""Affords invoking a unary-unary RPC in any call style.""" |
||||
__metaclass__ = abc.ABCMeta |
||||
|
||||
@abc.abstractmethod |
||||
def __call__( |
||||
self, request, timeout, metadata=None, with_call=False): |
||||
"""Synchronously invokes the underlying RPC. |
||||
|
||||
Args: |
||||
request: The request value for the RPC. |
||||
timeout: A duration of time in seconds to allow for the RPC. |
||||
metadata: A metadata value to be passed to the service-side of |
||||
the RPC. |
||||
with_call: Whether or not to include return a Call for the RPC in addition |
||||
to the reponse. |
||||
|
||||
Returns: |
||||
The response value for the RPC, and a Call for the RPC if with_call was |
||||
set to True at invocation. |
||||
|
||||
Raises: |
||||
AbortionError: Indicating that the RPC was aborted. |
||||
""" |
||||
raise NotImplementedError() |
||||
|
||||
@abc.abstractmethod |
||||
def future(self, request, timeout, metadata=None): |
||||
"""Asynchronously invokes the underlying RPC. |
||||
|
||||
Args: |
||||
request: The request value for the RPC. |
||||
timeout: A duration of time in seconds to allow for the RPC. |
||||
metadata: A metadata value to be passed to the service-side of |
||||
the RPC. |
||||
|
||||
Returns: |
||||
An object that is both a Call for the RPC and a future.Future. In the |
||||
event of RPC completion, the return Future's result value will be the |
||||
response value of the RPC. In the event of RPC abortion, the returned |
||||
Future's exception value will be an AbortionError. |
||||
""" |
||||
raise NotImplementedError() |
||||
|
||||
@abc.abstractmethod |
||||
def event( |
||||
self, request, receiver, abortion_callback, timeout, |
||||
metadata=None): |
||||
"""Asynchronously invokes the underlying RPC. |
||||
|
||||
Args: |
||||
request: The request value for the RPC. |
||||
receiver: A ResponseReceiver to be passed the response data of the RPC. |
||||
abortion_callback: A callback to be called and passed an Abortion value |
||||
in the event of RPC abortion. |
||||
timeout: A duration of time in seconds to allow for the RPC. |
||||
metadata: A metadata value to be passed to the service-side of |
||||
the RPC. |
||||
|
||||
Returns: |
||||
A Call for the RPC. |
||||
""" |
||||
raise NotImplementedError() |
||||
|
||||
|
||||
class UnaryStreamMultiCallable(object): |
||||
"""Affords invoking a unary-stream RPC in any call style.""" |
||||
__metaclass__ = abc.ABCMeta |
||||
|
||||
@abc.abstractmethod |
||||
def __call__(self, request, timeout, metadata=None): |
||||
"""Invokes the underlying RPC. |
||||
|
||||
Args: |
||||
request: The request value for the RPC. |
||||
timeout: A duration of time in seconds to allow for the RPC. |
||||
metadata: A metadata value to be passed to the service-side of |
||||
the RPC. |
||||
|
||||
Returns: |
||||
An object that is both a Call for the RPC and an iterator of response |
||||
values. Drawing response values from the returned iterator may raise |
||||
AbortionError indicating abortion of the RPC. |
||||
""" |
||||
raise NotImplementedError() |
||||
|
||||
@abc.abstractmethod |
||||
def event( |
||||
self, request, receiver, abortion_callback, timeout, |
||||
metadata=None): |
||||
"""Asynchronously invokes the underlying RPC. |
||||
|
||||
Args: |
||||
request: The request value for the RPC. |
||||
receiver: A ResponseReceiver to be passed the response data of the RPC. |
||||
abortion_callback: A callback to be called and passed an Abortion value |
||||
in the event of RPC abortion. |
||||
timeout: A duration of time in seconds to allow for the RPC. |
||||
metadata: A metadata value to be passed to the service-side of |
||||
the RPC. |
||||
|
||||
Returns: |
||||
A Call object for the RPC. |
||||
""" |
||||
raise NotImplementedError() |
||||
|
||||
|
||||
class StreamUnaryMultiCallable(object): |
||||
"""Affords invoking a stream-unary RPC in any call style.""" |
||||
__metaclass__ = abc.ABCMeta |
||||
|
||||
@abc.abstractmethod |
||||
def __call__( |
||||
self, request_iterator, timeout, metadata=None, |
||||
with_call=False): |
||||
"""Synchronously invokes the underlying RPC. |
||||
|
||||
Args: |
||||
request_iterator: An iterator that yields request values for the RPC. |
||||
timeout: A duration of time in seconds to allow for the RPC. |
||||
metadata: A metadata value to be passed to the service-side of |
||||
the RPC. |
||||
with_call: Whether or not to include return a Call for the RPC in addition |
||||
to the reponse. |
||||
|
||||
Returns: |
||||
The response value for the RPC, and a Call for the RPC if with_call was |
||||
set to True at invocation. |
||||
|
||||
Raises: |
||||
AbortionError: Indicating that the RPC was aborted. |
||||
""" |
||||
raise NotImplementedError() |
||||
|
||||
@abc.abstractmethod |
||||
def future(self, request_iterator, timeout, metadata=None): |
||||
"""Asynchronously invokes the underlying RPC. |
||||
|
||||
Args: |
||||
request_iterator: An iterator that yields request values for the RPC. |
||||
timeout: A duration of time in seconds to allow for the RPC. |
||||
metadata: A metadata value to be passed to the service-side of |
||||
the RPC. |
||||
|
||||
Returns: |
||||
An object that is both a Call for the RPC and a future.Future. In the |
||||
event of RPC completion, the return Future's result value will be the |
||||
response value of the RPC. In the event of RPC abortion, the returned |
||||
Future's exception value will be an AbortionError. |
||||
""" |
||||
raise NotImplementedError() |
||||
|
||||
@abc.abstractmethod |
||||
def event( |
||||
self, receiver, abortion_callback, timeout, metadata=None): |
||||
"""Asynchronously invokes the underlying RPC. |
||||
|
||||
Args: |
||||
receiver: A ResponseReceiver to be passed the response data of the RPC. |
||||
abortion_callback: A callback to be called and passed an Abortion value |
||||
in the event of RPC abortion. |
||||
timeout: A duration of time in seconds to allow for the RPC. |
||||
metadata: A metadata value to be passed to the service-side of |
||||
the RPC. |
||||
|
||||
Returns: |
||||
A single object that is both a Call object for the RPC and a |
||||
stream.Consumer to which the request values of the RPC should be passed. |
||||
""" |
||||
raise NotImplementedError() |
||||
|
||||
|
||||
class StreamStreamMultiCallable(object): |
||||
"""Affords invoking a stream-stream RPC in any call style.""" |
||||
__metaclass__ = abc.ABCMeta |
||||
|
||||
@abc.abstractmethod |
||||
def __call__(self, request_iterator, timeout, metadata=None): |
||||
"""Invokes the underlying RPC. |
||||
|
||||
Args: |
||||
request_iterator: An iterator that yields request values for the RPC. |
||||
timeout: A duration of time in seconds to allow for the RPC. |
||||
metadata: A metadata value to be passed to the service-side of |
||||
the RPC. |
||||
|
||||
Returns: |
||||
An object that is both a Call for the RPC and an iterator of response |
||||
values. Drawing response values from the returned iterator may raise |
||||
AbortionError indicating abortion of the RPC. |
||||
""" |
||||
raise NotImplementedError() |
||||
|
||||
@abc.abstractmethod |
||||
def event( |
||||
self, receiver, abortion_callback, timeout, metadata=None): |
||||
"""Asynchronously invokes the underlying RPC. |
||||
|
||||
Args: |
||||
receiver: A ResponseReceiver to be passed the response data of the RPC. |
||||
abortion_callback: A callback to be called and passed an Abortion value |
||||
in the event of RPC abortion. |
||||
timeout: A duration of time in seconds to allow for the RPC. |
||||
metadata: A metadata value to be passed to the service-side of |
||||
the RPC. |
||||
|
||||
Returns: |
||||
A single object that is both a Call object for the RPC and a |
||||
stream.Consumer to which the request values of the RPC should be passed. |
||||
""" |
||||
raise NotImplementedError() |
||||
|
||||
|
||||
class MethodImplementation(object): |
||||
"""A sum type that describes a method implementation. |
||||
|
||||
Attributes: |
||||
cardinality: A cardinality.Cardinality value. |
||||
style: A style.Service value. |
||||
unary_unary_inline: The implementation of the method as a callable value |
||||
that takes a request value and a ServicerContext object and returns a |
||||
response value. Only non-None if cardinality is |
||||
cardinality.Cardinality.UNARY_UNARY and style is style.Service.INLINE. |
||||
unary_stream_inline: The implementation of the method as a callable value |
||||
that takes a request value and a ServicerContext object and returns an |
||||
iterator of response values. Only non-None if cardinality is |
||||
cardinality.Cardinality.UNARY_STREAM and style is style.Service.INLINE. |
||||
stream_unary_inline: The implementation of the method as a callable value |
||||
that takes an iterator of request values and a ServicerContext object and |
||||
returns a response value. Only non-None if cardinality is |
||||
cardinality.Cardinality.STREAM_UNARY and style is style.Service.INLINE. |
||||
stream_stream_inline: The implementation of the method as a callable value |
||||
that takes an iterator of request values and a ServicerContext object and |
||||
returns an iterator of response values. Only non-None if cardinality is |
||||
cardinality.Cardinality.STREAM_STREAM and style is style.Service.INLINE. |
||||
unary_unary_event: The implementation of the method as a callable value that |
||||
takes a request value, a response callback to which to pass the response |
||||
value of the RPC, and a ServicerContext. Only non-None if cardinality is |
||||
cardinality.Cardinality.UNARY_UNARY and style is style.Service.EVENT. |
||||
unary_stream_event: The implementation of the method as a callable value |
||||
that takes a request value, a stream.Consumer to which to pass the |
||||
response values of the RPC, and a ServicerContext. Only non-None if |
||||
cardinality is cardinality.Cardinality.UNARY_STREAM and style is |
||||
style.Service.EVENT. |
||||
stream_unary_event: The implementation of the method as a callable value |
||||
that takes a response callback to which to pass the response value of the |
||||
RPC and a ServicerContext and returns a stream.Consumer to which the |
||||
request values of the RPC should be passed. Only non-None if cardinality |
||||
is cardinality.Cardinality.STREAM_UNARY and style is style.Service.EVENT. |
||||
stream_stream_event: The implementation of the method as a callable value |
||||
that takes a stream.Consumer to which to pass the response values of the |
||||
RPC and a ServicerContext and returns a stream.Consumer to which the |
||||
request values of the RPC should be passed. Only non-None if cardinality |
||||
is cardinality.Cardinality.STREAM_STREAM and style is |
||||
style.Service.EVENT. |
||||
""" |
||||
__metaclass__ = abc.ABCMeta |
||||
|
||||
|
||||
class MultiMethodImplementation(object): |
||||
"""A general type able to service many methods.""" |
||||
__metaclass__ = abc.ABCMeta |
||||
|
||||
@abc.abstractmethod |
||||
def service(self, group, method, response_consumer, context): |
||||
"""Services an RPC. |
||||
|
||||
Args: |
||||
group: The group identifier of the RPC. |
||||
method: The method identifier of the RPC. |
||||
response_consumer: A stream.Consumer to be called to accept the response |
||||
values of the RPC. |
||||
context: a ServicerContext object. |
||||
|
||||
Returns: |
||||
A stream.Consumer with which to accept the request values of the RPC. The |
||||
consumer returned from this method may or may not be invoked to |
||||
completion: in the case of RPC abortion, RPC Framework will simply stop |
||||
passing values to this object. Implementations must not assume that this |
||||
object will be called to completion of the request stream or even called |
||||
at all. |
||||
|
||||
Raises: |
||||
abandonment.Abandoned: May or may not be raised when the RPC has been |
||||
aborted. |
||||
NoSuchMethodError: If this MultiMethod does not recognize the given group |
||||
and name for the RPC and is not able to service the RPC. |
||||
""" |
||||
raise NotImplementedError() |
||||
|
||||
|
||||
class GenericStub(object): |
||||
"""Affords RPC invocation via generic methods.""" |
||||
__metaclass__ = abc.ABCMeta |
||||
|
||||
@abc.abstractmethod |
||||
def blocking_unary_unary( |
||||
self, group, method, request, timeout, metadata=None, |
||||
with_call=False): |
||||
"""Invokes a unary-request-unary-response method. |
||||
|
||||
This method blocks until either returning the response value of the RPC |
||||
(in the event of RPC completion) or raising an exception (in the event of |
||||
RPC abortion). |
||||
|
||||
Args: |
||||
group: The group identifier of the RPC. |
||||
method: The method identifier of the RPC. |
||||
request: The request value for the RPC. |
||||
timeout: A duration of time in seconds to allow for the RPC. |
||||
metadata: A metadata value to be passed to the service-side of the RPC. |
||||
with_call: Whether or not to include return a Call for the RPC in addition |
||||
to the reponse. |
||||
|
||||
Returns: |
||||
The response value for the RPC, and a Call for the RPC if with_call was |
||||
set to True at invocation. |
||||
|
||||
Raises: |
||||
AbortionError: Indicating that the RPC was aborted. |
||||
""" |
||||
raise NotImplementedError() |
||||
|
||||
@abc.abstractmethod |
||||
def future_unary_unary( |
||||
self, group, method, request, timeout, metadata=None): |
||||
"""Invokes a unary-request-unary-response method. |
||||
|
||||
Args: |
||||
group: The group identifier of the RPC. |
||||
method: The method identifier of the RPC. |
||||
request: The request value for the RPC. |
||||
timeout: A duration of time in seconds to allow for the RPC. |
||||
metadata: A metadata value to be passed to the service-side of the RPC. |
||||
|
||||
Returns: |
||||
An object that is both a Call for the RPC and a future.Future. In the |
||||
event of RPC completion, the return Future's result value will be the |
||||
response value of the RPC. In the event of RPC abortion, the returned |
||||
Future's exception value will be an AbortionError. |
||||
""" |
||||
raise NotImplementedError() |
||||
|
||||
@abc.abstractmethod |
||||
def inline_unary_stream( |
||||
self, group, method, request, timeout, metadata=None): |
||||
"""Invokes a unary-request-stream-response method. |
||||
|
||||
Args: |
||||
group: The group identifier of the RPC. |
||||
method: The method identifier of the RPC. |
||||
request: The request value for the RPC. |
||||
timeout: A duration of time in seconds to allow for the RPC. |
||||
metadata: A metadata value to be passed to the service-side of the RPC. |
||||
|
||||
Returns: |
||||
An object that is both a Call for the RPC and an iterator of response |
||||
values. Drawing response values from the returned iterator may raise |
||||
AbortionError indicating abortion of the RPC. |
||||
""" |
||||
raise NotImplementedError() |
||||
|
||||
@abc.abstractmethod |
||||
def blocking_stream_unary( |
||||
self, group, method, request_iterator, timeout, metadata=None, |
||||
with_call=False): |
||||
"""Invokes a stream-request-unary-response method. |
||||
|
||||
This method blocks until either returning the response value of the RPC |
||||
(in the event of RPC completion) or raising an exception (in the event of |
||||
RPC abortion). |
||||
|
||||
Args: |
||||
group: The group identifier of the RPC. |
||||
method: The method identifier of the RPC. |
||||
request_iterator: An iterator that yields request values for the RPC. |
||||
timeout: A duration of time in seconds to allow for the RPC. |
||||
metadata: A metadata value to be passed to the service-side of the RPC. |
||||
with_call: Whether or not to include return a Call for the RPC in addition |
||||
to the reponse. |
||||
|
||||
Returns: |
||||
The response value for the RPC, and a Call for the RPC if with_call was |
||||
set to True at invocation. |
||||
|
||||
Raises: |
||||
AbortionError: Indicating that the RPC was aborted. |
||||
""" |
||||
raise NotImplementedError() |
||||
|
||||
@abc.abstractmethod |
||||
def future_stream_unary( |
||||
self, group, method, request_iterator, timeout, metadata=None): |
||||
"""Invokes a stream-request-unary-response method. |
||||
|
||||
Args: |
||||
group: The group identifier of the RPC. |
||||
method: The method identifier of the RPC. |
||||
request_iterator: An iterator that yields request values for the RPC. |
||||
timeout: A duration of time in seconds to allow for the RPC. |
||||
metadata: A metadata value to be passed to the service-side of the RPC. |
||||
|
||||
Returns: |
||||
An object that is both a Call for the RPC and a future.Future. In the |
||||
event of RPC completion, the return Future's result value will be the |
||||
response value of the RPC. In the event of RPC abortion, the returned |
||||
Future's exception value will be an AbortionError. |
||||
""" |
||||
raise NotImplementedError() |
||||
|
||||
@abc.abstractmethod |
||||
def inline_stream_stream( |
||||
self, group, method, request_iterator, timeout, metadata=None): |
||||
"""Invokes a stream-request-stream-response method. |
||||
|
||||
Args: |
||||
group: The group identifier of the RPC. |
||||
method: The method identifier of the RPC. |
||||
request_iterator: An iterator that yields request values for the RPC. |
||||
timeout: A duration of time in seconds to allow for the RPC. |
||||
metadata: A metadata value to be passed to the service-side of the RPC. |
||||
|
||||
Returns: |
||||
An object that is both a Call for the RPC and an iterator of response |
||||
values. Drawing response values from the returned iterator may raise |
||||
AbortionError indicating abortion of the RPC. |
||||
""" |
||||
raise NotImplementedError() |
||||
|
||||
@abc.abstractmethod |
||||
def event_unary_unary( |
||||
self, group, method, request, receiver, abortion_callback, timeout, |
||||
metadata=None): |
||||
"""Event-driven invocation of a unary-request-unary-response method. |
||||
|
||||
Args: |
||||
group: The group identifier of the RPC. |
||||
method: The method identifier of the RPC. |
||||
request: The request value for the RPC. |
||||
receiver: A ResponseReceiver to be passed the response data of the RPC. |
||||
abortion_callback: A callback to be called and passed an Abortion value |
||||
in the event of RPC abortion. |
||||
timeout: A duration of time in seconds to allow for the RPC. |
||||
metadata: A metadata value to be passed to the service-side of the RPC. |
||||
|
||||
Returns: |
||||
A Call for the RPC. |
||||
""" |
||||
raise NotImplementedError() |
||||
|
||||
@abc.abstractmethod |
||||
def event_unary_stream( |
||||
self, group, method, request, receiver, abortion_callback, timeout, |
||||
metadata=None): |
||||
"""Event-driven invocation of a unary-request-stream-response method. |
||||
|
||||
Args: |
||||
group: The group identifier of the RPC. |
||||
method: The method identifier of the RPC. |
||||
request: The request value for the RPC. |
||||
receiver: A ResponseReceiver to be passed the response data of the RPC. |
||||
abortion_callback: A callback to be called and passed an Abortion value |
||||
in the event of RPC abortion. |
||||
timeout: A duration of time in seconds to allow for the RPC. |
||||
metadata: A metadata value to be passed to the service-side of the RPC. |
||||
|
||||
Returns: |
||||
A Call for the RPC. |
||||
""" |
||||
raise NotImplementedError() |
||||
|
||||
@abc.abstractmethod |
||||
def event_stream_unary( |
||||
self, group, method, receiver, abortion_callback, timeout, |
||||
metadata=None): |
||||
"""Event-driven invocation of a unary-request-unary-response method. |
||||
|
||||
Args: |
||||
group: The group identifier of the RPC. |
||||
method: The method identifier of the RPC. |
||||
receiver: A ResponseReceiver to be passed the response data of the RPC. |
||||
abortion_callback: A callback to be called and passed an Abortion value |
||||
in the event of RPC abortion. |
||||
timeout: A duration of time in seconds to allow for the RPC. |
||||
metadata: A metadata value to be passed to the service-side of the RPC. |
||||
|
||||
Returns: |
||||
A pair of a Call object for the RPC and a stream.Consumer to which the |
||||
request values of the RPC should be passed. |
||||
""" |
||||
raise NotImplementedError() |
||||
|
||||
@abc.abstractmethod |
||||
def event_stream_stream( |
||||
self, group, method, receiver, abortion_callback, timeout, |
||||
metadata=None): |
||||
"""Event-driven invocation of a unary-request-stream-response method. |
||||
|
||||
Args: |
||||
group: The group identifier of the RPC. |
||||
method: The method identifier of the RPC. |
||||
receiver: A ResponseReceiver to be passed the response data of the RPC. |
||||
abortion_callback: A callback to be called and passed an Abortion value |
||||
in the event of RPC abortion. |
||||
timeout: A duration of time in seconds to allow for the RPC. |
||||
metadata: A metadata value to be passed to the service-side of the RPC. |
||||
|
||||
Returns: |
||||
A pair of a Call object for the RPC and a stream.Consumer to which the |
||||
request values of the RPC should be passed. |
||||
""" |
||||
raise NotImplementedError() |
||||
|
||||
@abc.abstractmethod |
||||
def unary_unary(self, group, method): |
||||
"""Creates a UnaryUnaryMultiCallable for a unary-unary method. |
||||
|
||||
Args: |
||||
group: The group identifier of the RPC. |
||||
method: The method identifier of the RPC. |
||||
|
||||
Returns: |
||||
A UnaryUnaryMultiCallable value for the named unary-unary method. |
||||
""" |
||||
raise NotImplementedError() |
||||
|
||||
@abc.abstractmethod |
||||
def unary_stream(self, group, method): |
||||
"""Creates a UnaryStreamMultiCallable for a unary-stream method. |
||||
|
||||
Args: |
||||
group: The group identifier of the RPC. |
||||
method: The method identifier of the RPC. |
||||
|
||||
Returns: |
||||
A UnaryStreamMultiCallable value for the name unary-stream method. |
||||
""" |
||||
raise NotImplementedError() |
||||
|
||||
@abc.abstractmethod |
||||
def stream_unary(self, group, method): |
||||
"""Creates a StreamUnaryMultiCallable for a stream-unary method. |
||||
|
||||
Args: |
||||
group: The group identifier of the RPC. |
||||
method: The method identifier of the RPC. |
||||
|
||||
Returns: |
||||
A StreamUnaryMultiCallable value for the named stream-unary method. |
||||
""" |
||||
raise NotImplementedError() |
||||
|
||||
@abc.abstractmethod |
||||
def stream_stream(self, group, method): |
||||
"""Creates a StreamStreamMultiCallable for a stream-stream method. |
||||
|
||||
Args: |
||||
group: The group identifier of the RPC. |
||||
method: The method identifier of the RPC. |
||||
|
||||
Returns: |
||||
A StreamStreamMultiCallable value for the named stream-stream method. |
||||
""" |
||||
raise NotImplementedError() |
||||
|
||||
|
||||
class DynamicStub(object): |
||||
"""Affords RPC invocation via attributes corresponding to afforded methods. |
||||
|
||||
Instances of this type may be scoped to a single group so that attribute |
||||
access is unambiguous. |
||||
|
||||
Instances of this type respond to attribute access as follows: if the |
||||
requested attribute is the name of a unary-unary method, the value of the |
||||
attribute will be a UnaryUnaryMultiCallable with which to invoke an RPC; if |
||||
the requested attribute is the name of a unary-stream method, the value of the |
||||
attribute will be a UnaryStreamMultiCallable with which to invoke an RPC; if |
||||
the requested attribute is the name of a stream-unary method, the value of the |
||||
attribute will be a StreamUnaryMultiCallable with which to invoke an RPC; and |
||||
if the requested attribute is the name of a stream-stream method, the value of |
||||
the attribute will be a StreamStreamMultiCallable with which to invoke an RPC. |
||||
""" |
||||
__metaclass__ = abc.ABCMeta |
@ -0,0 +1,178 @@ |
||||
# Copyright 2015, Google Inc. |
||||
# All rights reserved. |
||||
# |
||||
# Redistribution and use in source and binary forms, with or without |
||||
# modification, are permitted provided that the following conditions are |
||||
# met: |
||||
# |
||||
# * Redistributions of source code must retain the above copyright |
||||
# notice, this list of conditions and the following disclaimer. |
||||
# * Redistributions in binary form must reproduce the above |
||||
# copyright notice, this list of conditions and the following disclaimer |
||||
# in the documentation and/or other materials provided with the |
||||
# distribution. |
||||
# * Neither the name of Google Inc. nor the names of its |
||||
# contributors may be used to endorse or promote products derived from |
||||
# this software without specific prior written permission. |
||||
# |
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
|
||||
"""Utilities for RPC Framework's Face interface.""" |
||||
|
||||
import collections |
||||
|
||||
# stream is referenced from specification in this module. |
||||
from grpc.framework.common import cardinality |
||||
from grpc.framework.common import style |
||||
from grpc.framework.foundation import stream # pylint: disable=unused-import |
||||
from grpc.framework.interfaces.face import face |
||||
|
||||
|
||||
class _MethodImplementation( |
||||
face.MethodImplementation, |
||||
collections.namedtuple( |
||||
'_MethodImplementation', |
||||
['cardinality', 'style', 'unary_unary_inline', 'unary_stream_inline', |
||||
'stream_unary_inline', 'stream_stream_inline', 'unary_unary_event', |
||||
'unary_stream_event', 'stream_unary_event', 'stream_stream_event',])): |
||||
pass |
||||
|
||||
|
||||
def unary_unary_inline(behavior): |
||||
"""Creates an face.MethodImplementation for the given behavior. |
||||
|
||||
Args: |
||||
behavior: The implementation of a unary-unary RPC method as a callable value |
||||
that takes a request value and an face.ServicerContext object and |
||||
returns a response value. |
||||
|
||||
Returns: |
||||
An face.MethodImplementation derived from the given behavior. |
||||
""" |
||||
return _MethodImplementation( |
||||
cardinality.Cardinality.UNARY_UNARY, style.Service.INLINE, behavior, |
||||
None, None, None, None, None, None, None) |
||||
|
||||
|
||||
def unary_stream_inline(behavior): |
||||
"""Creates an face.MethodImplementation for the given behavior. |
||||
|
||||
Args: |
||||
behavior: The implementation of a unary-stream RPC method as a callable |
||||
value that takes a request value and an face.ServicerContext object and |
||||
returns an iterator of response values. |
||||
|
||||
Returns: |
||||
An face.MethodImplementation derived from the given behavior. |
||||
""" |
||||
return _MethodImplementation( |
||||
cardinality.Cardinality.UNARY_STREAM, style.Service.INLINE, None, |
||||
behavior, None, None, None, None, None, None) |
||||
|
||||
|
||||
def stream_unary_inline(behavior): |
||||
"""Creates an face.MethodImplementation for the given behavior. |
||||
|
||||
Args: |
||||
behavior: The implementation of a stream-unary RPC method as a callable |
||||
value that takes an iterator of request values and an |
||||
face.ServicerContext object and returns a response value. |
||||
|
||||
Returns: |
||||
An face.MethodImplementation derived from the given behavior. |
||||
""" |
||||
return _MethodImplementation( |
||||
cardinality.Cardinality.STREAM_UNARY, style.Service.INLINE, None, None, |
||||
behavior, None, None, None, None, None) |
||||
|
||||
|
||||
def stream_stream_inline(behavior): |
||||
"""Creates an face.MethodImplementation for the given behavior. |
||||
|
||||
Args: |
||||
behavior: The implementation of a stream-stream RPC method as a callable |
||||
value that takes an iterator of request values and an |
||||
face.ServicerContext object and returns an iterator of response values. |
||||
|
||||
Returns: |
||||
An face.MethodImplementation derived from the given behavior. |
||||
""" |
||||
return _MethodImplementation( |
||||
cardinality.Cardinality.STREAM_STREAM, style.Service.INLINE, None, None, |
||||
None, behavior, None, None, None, None) |
||||
|
||||
|
||||
def unary_unary_event(behavior): |
||||
"""Creates an face.MethodImplementation for the given behavior. |
||||
|
||||
Args: |
||||
behavior: The implementation of a unary-unary RPC method as a callable |
||||
value that takes a request value, a response callback to which to pass |
||||
the response value of the RPC, and an face.ServicerContext. |
||||
|
||||
Returns: |
||||
An face.MethodImplementation derived from the given behavior. |
||||
""" |
||||
return _MethodImplementation( |
||||
cardinality.Cardinality.UNARY_UNARY, style.Service.EVENT, None, None, |
||||
None, None, behavior, None, None, None) |
||||
|
||||
|
||||
def unary_stream_event(behavior): |
||||
"""Creates an face.MethodImplementation for the given behavior. |
||||
|
||||
Args: |
||||
behavior: The implementation of a unary-stream RPC method as a callable |
||||
value that takes a request value, a stream.Consumer to which to pass the |
||||
the response values of the RPC, and an face.ServicerContext. |
||||
|
||||
Returns: |
||||
An face.MethodImplementation derived from the given behavior. |
||||
""" |
||||
return _MethodImplementation( |
||||
cardinality.Cardinality.UNARY_STREAM, style.Service.EVENT, None, None, |
||||
None, None, None, behavior, None, None) |
||||
|
||||
|
||||
def stream_unary_event(behavior): |
||||
"""Creates an face.MethodImplementation for the given behavior. |
||||
|
||||
Args: |
||||
behavior: The implementation of a stream-unary RPC method as a callable |
||||
value that takes a response callback to which to pass the response value |
||||
of the RPC and an face.ServicerContext and returns a stream.Consumer to |
||||
which the request values of the RPC should be passed. |
||||
|
||||
Returns: |
||||
An face.MethodImplementation derived from the given behavior. |
||||
""" |
||||
return _MethodImplementation( |
||||
cardinality.Cardinality.STREAM_UNARY, style.Service.EVENT, None, None, |
||||
None, None, None, None, behavior, None) |
||||
|
||||
|
||||
def stream_stream_event(behavior): |
||||
"""Creates an face.MethodImplementation for the given behavior. |
||||
|
||||
Args: |
||||
behavior: The implementation of a stream-stream RPC method as a callable |
||||
value that takes a stream.Consumer to which to pass the response values |
||||
of the RPC and an face.ServicerContext and returns a stream.Consumer to |
||||
which the request values of the RPC should be passed. |
||||
|
||||
Returns: |
||||
An face.MethodImplementation derived from the given behavior. |
||||
""" |
||||
return _MethodImplementation( |
||||
cardinality.Cardinality.STREAM_STREAM, style.Service.EVENT, None, None, |
||||
None, None, None, None, None, behavior) |
@ -0,0 +1,141 @@ |
||||
/*
|
||||
* |
||||
* Copyright 2015, Google Inc. |
||||
* All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without |
||||
* modification, are permitted provided that the following conditions are |
||||
* met: |
||||
* |
||||
* * Redistributions of source code must retain the above copyright |
||||
* notice, this list of conditions and the following disclaimer. |
||||
* * Redistributions in binary form must reproduce the above |
||||
* copyright notice, this list of conditions and the following disclaimer |
||||
* in the documentation and/or other materials provided with the |
||||
* distribution. |
||||
* * Neither the name of Google Inc. nor the names of its |
||||
* contributors may be used to endorse or promote products derived from |
||||
* this software without specific prior written permission. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
* |
||||
*/ |
||||
|
||||
#include <string.h> |
||||
|
||||
#include <grpc/support/log.h> |
||||
#include <grpc/support/useful.h> |
||||
|
||||
#include "src/core/channel/channel_args.h" |
||||
|
||||
#include "test/core/util/test_config.h" |
||||
|
||||
static void test_create(void) { |
||||
grpc_arg arg_int; |
||||
grpc_arg arg_string; |
||||
grpc_arg to_add[2]; |
||||
grpc_channel_args *ch_args; |
||||
|
||||
arg_int.key = "int_arg"; |
||||
arg_int.type = GRPC_ARG_INTEGER; |
||||
arg_int.value.integer = 123; |
||||
|
||||
arg_string.key = "str key"; |
||||
arg_string.type = GRPC_ARG_STRING; |
||||
arg_string.value.string = "str value"; |
||||
|
||||
to_add[0] = arg_int; |
||||
to_add[1] = arg_string; |
||||
ch_args = grpc_channel_args_copy_and_add(NULL, to_add, 2); |
||||
|
||||
GPR_ASSERT(ch_args->num_args == 2); |
||||
GPR_ASSERT(strcmp(ch_args->args[0].key, arg_int.key) == 0); |
||||
GPR_ASSERT(ch_args->args[0].type == arg_int.type); |
||||
GPR_ASSERT(ch_args->args[0].value.integer == arg_int.value.integer); |
||||
|
||||
GPR_ASSERT(strcmp(ch_args->args[1].key, arg_string.key) == 0); |
||||
GPR_ASSERT(ch_args->args[1].type == arg_string.type); |
||||
GPR_ASSERT(strcmp(ch_args->args[1].value.string, arg_string.value.string) == |
||||
0); |
||||
|
||||
grpc_channel_args_destroy(ch_args); |
||||
} |
||||
|
||||
static void test_set_compression_algorithm(void) { |
||||
grpc_channel_args *ch_args; |
||||
|
||||
ch_args = |
||||
grpc_channel_args_set_compression_algorithm(NULL, GRPC_COMPRESS_GZIP); |
||||
GPR_ASSERT(ch_args->num_args == 1); |
||||
GPR_ASSERT(strcmp(ch_args->args[0].key, GRPC_COMPRESSION_ALGORITHM_ARG) == 0); |
||||
GPR_ASSERT(ch_args->args[0].type == GRPC_ARG_INTEGER); |
||||
|
||||
grpc_channel_args_destroy(ch_args); |
||||
} |
||||
|
||||
static void test_compression_algorithm_states(void) { |
||||
grpc_channel_args *ch_args, *ch_args_wo_gzip, *ch_args_wo_gzip_deflate; |
||||
int states_bitset; |
||||
size_t i; |
||||
|
||||
ch_args = grpc_channel_args_copy_and_add(NULL, NULL, 0); |
||||
/* by default, all enabled */ |
||||
states_bitset = grpc_channel_args_compression_algorithm_get_states(ch_args); |
||||
|
||||
for (i = 0; i < GRPC_COMPRESS_ALGORITHMS_COUNT; i++) { |
||||
GPR_ASSERT(GPR_BITGET(states_bitset, i)); |
||||
} |
||||
|
||||
/* disable gzip and deflate */ |
||||
ch_args_wo_gzip = grpc_channel_args_compression_algorithm_set_state( |
||||
&ch_args, GRPC_COMPRESS_GZIP, 0); |
||||
GPR_ASSERT(ch_args == ch_args_wo_gzip); |
||||
ch_args_wo_gzip_deflate = grpc_channel_args_compression_algorithm_set_state( |
||||
&ch_args_wo_gzip, GRPC_COMPRESS_DEFLATE, 0); |
||||
GPR_ASSERT(ch_args_wo_gzip == ch_args_wo_gzip_deflate); |
||||
|
||||
states_bitset = grpc_channel_args_compression_algorithm_get_states( |
||||
ch_args_wo_gzip_deflate); |
||||
for (i = 0; i < GRPC_COMPRESS_ALGORITHMS_COUNT; i++) { |
||||
if (i == GRPC_COMPRESS_GZIP || i == GRPC_COMPRESS_DEFLATE) { |
||||
GPR_ASSERT(GPR_BITGET(states_bitset, i) == 0); |
||||
} else { |
||||
GPR_ASSERT(GPR_BITGET(states_bitset, i) != 0); |
||||
} |
||||
} |
||||
|
||||
/* re-enabled gzip only */ |
||||
ch_args_wo_gzip = grpc_channel_args_compression_algorithm_set_state( |
||||
&ch_args_wo_gzip_deflate, GRPC_COMPRESS_GZIP, 1); |
||||
GPR_ASSERT(ch_args_wo_gzip == ch_args_wo_gzip_deflate); |
||||
|
||||
states_bitset = |
||||
grpc_channel_args_compression_algorithm_get_states(ch_args_wo_gzip); |
||||
for (i = 0; i < GRPC_COMPRESS_ALGORITHMS_COUNT; i++) { |
||||
if (i == GRPC_COMPRESS_DEFLATE) { |
||||
GPR_ASSERT(GPR_BITGET(states_bitset, i) == 0); |
||||
} else { |
||||
GPR_ASSERT(GPR_BITGET(states_bitset, i) != 0); |
||||
} |
||||
} |
||||
|
||||
grpc_channel_args_destroy(ch_args); |
||||
} |
||||
|
||||
int main(int argc, char **argv) { |
||||
grpc_test_init(argc, argv); |
||||
test_create(); |
||||
test_set_compression_algorithm(); |
||||
test_compression_algorithm_states(); |
||||
return 0; |
||||
} |
File diff suppressed because one or more lines are too long
Loading…
Reference in new issue