aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/python/grpcio
diff options
context:
space:
mode:
Diffstat (limited to 'src/python/grpcio')
-rw-r--r--src/python/grpcio/_spawn_patch.py46
-rw-r--r--src/python/grpcio/commands.py352
-rw-r--r--src/python/grpcio/grpc/__init__.py744
-rw-r--r--src/python/grpcio/grpc/_auth.py83
-rw-r--r--src/python/grpcio/grpc/_channel.py1529
-rw-r--r--src/python/grpcio/grpc/_common.py123
-rw-r--r--src/python/grpcio/grpc/_credential_composition.py18
-rw-r--r--src/python/grpcio/grpc/_plugin_wrapping.py123
-rw-r--r--src/python/grpcio/grpc/_server.py1092
-rw-r--r--src/python/grpcio/grpc/_utilities.py235
-rw-r--r--src/python/grpcio/grpc/beta/_client_adaptations.py1028
-rw-r--r--src/python/grpcio/grpc/beta/_connectivity_channel.py213
-rw-r--r--src/python/grpcio/grpc/beta/_server_adaptations.py544
-rw-r--r--src/python/grpcio/grpc/beta/implementations.py173
-rw-r--r--src/python/grpcio/grpc/beta/interfaces.py78
-rw-r--r--src/python/grpcio/grpc/beta/utilities.py202
-rw-r--r--src/python/grpcio/grpc/framework/__init__.py2
-rw-r--r--src/python/grpcio/grpc/framework/common/__init__.py2
-rw-r--r--src/python/grpcio/grpc/framework/common/cardinality.py11
-rw-r--r--src/python/grpcio/grpc/framework/common/style.py7
-rw-r--r--src/python/grpcio/grpc/framework/foundation/__init__.py2
-rw-r--r--src/python/grpcio/grpc/framework/foundation/abandonment.py3
-rw-r--r--src/python/grpcio/grpc/framework/foundation/callable_util.py47
-rw-r--r--src/python/grpcio/grpc/framework/foundation/future.py129
-rw-r--r--src/python/grpcio/grpc/framework/foundation/logging_pool.py55
-rw-r--r--src/python/grpcio/grpc/framework/foundation/stream.py28
-rw-r--r--src/python/grpcio/grpc/framework/foundation/stream_util.py227
-rw-r--r--src/python/grpcio/grpc/framework/interfaces/__init__.py2
-rw-r--r--src/python/grpcio/grpc/framework/interfaces/base/__init__.py2
-rw-r--r--src/python/grpcio/grpc/framework/interfaces/base/base.py184
-rw-r--r--src/python/grpcio/grpc/framework/interfaces/base/utilities.py42
-rw-r--r--src/python/grpcio/grpc/framework/interfaces/face/__init__.py2
-rw-r--r--src/python/grpcio/grpc/framework/interfaces/face/face.py610
-rw-r--r--src/python/grpcio/grpc/framework/interfaces/face/utilities.py87
-rw-r--r--src/python/grpcio/support.py103
35 files changed, 4228 insertions, 3900 deletions
diff --git a/src/python/grpcio/_spawn_patch.py b/src/python/grpcio/_spawn_patch.py
index 24306f0dd9..75d0a8b352 100644
--- a/src/python/grpcio/_spawn_patch.py
+++ b/src/python/grpcio/_spawn_patch.py
@@ -26,7 +26,6 @@
# 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.
-
"""Patches the spawn() command for windows compilers.
Windows has an 8191 character command line limit, but some compilers
@@ -45,29 +44,32 @@ MAX_COMMAND_LENGTH = 8191
_classic_spawn = ccompiler.CCompiler.spawn
+
def _commandfile_spawn(self, command):
- command_length = sum([len(arg) for arg in command])
- if os.name == 'nt' and command_length > MAX_COMMAND_LENGTH:
- # Even if this command doesn't support the @command_file, it will
- # fail as is so we try blindly
- print('Command line length exceeded, using command file')
- print(' '.join(command))
- temporary_directory = tempfile.mkdtemp()
- command_filename = os.path.abspath(
- os.path.join(temporary_directory, 'command'))
- with open(command_filename, 'w') as command_file:
- escaped_args = ['"' + arg.replace('\\', '\\\\') + '"' for arg in command[1:]]
- command_file.write(' '.join(escaped_args))
- modified_command = command[:1] + ['@{}'.format(command_filename)]
- try:
- _classic_spawn(self, modified_command)
- finally:
- shutil.rmtree(temporary_directory)
- else:
- _classic_spawn(self, command)
+ command_length = sum([len(arg) for arg in command])
+ if os.name == 'nt' and command_length > MAX_COMMAND_LENGTH:
+ # Even if this command doesn't support the @command_file, it will
+ # fail as is so we try blindly
+ print('Command line length exceeded, using command file')
+ print(' '.join(command))
+ temporary_directory = tempfile.mkdtemp()
+ command_filename = os.path.abspath(
+ os.path.join(temporary_directory, 'command'))
+ with open(command_filename, 'w') as command_file:
+ escaped_args = [
+ '"' + arg.replace('\\', '\\\\') + '"' for arg in command[1:]
+ ]
+ command_file.write(' '.join(escaped_args))
+ modified_command = command[:1] + ['@{}'.format(command_filename)]
+ try:
+ _classic_spawn(self, modified_command)
+ finally:
+ shutil.rmtree(temporary_directory)
+ else:
+ _classic_spawn(self, command)
def monkeypatch_spawn():
- """Monkeypatching is dumb, but it's either that or we become maintainers of
+ """Monkeypatching is dumb, but it's either that or we become maintainers of
something much, much bigger."""
- ccompiler.CCompiler.spawn = _commandfile_spawn
+ ccompiler.CCompiler.spawn = _commandfile_spawn
diff --git a/src/python/grpcio/commands.py b/src/python/grpcio/commands.py
index 701c6af017..e09f922591 100644
--- a/src/python/grpcio/commands.py
+++ b/src/python/grpcio/commands.py
@@ -26,7 +26,6 @@
# 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.
-
"""Provides distutils command classes for the GRPC Python setup process."""
import distutils
@@ -87,138 +86,144 @@ Glossary
class CommandError(Exception):
- """Simple exception class for GRPC custom commands."""
+ """Simple exception class for GRPC custom commands."""
# TODO(atash): Remove this once PyPI has better Linux bdist support. See
# https://bitbucket.org/pypa/pypi/issues/120/binary-wheels-for-linux-are-not-supported
def _get_grpc_custom_bdist(decorated_basename, target_bdist_basename):
- """Returns a string path to a bdist file for Linux to install.
+ """Returns a string path to a bdist file for Linux to install.
If we can retrieve a pre-compiled bdist from online, uses it. Else, emits a
warning and builds from source.
"""
- # TODO(atash): somehow the name that's returned from `wheel` is different
- # between different versions of 'wheel' (but from a compatibility standpoint,
- # the names are compatible); we should have some way of determining name
- # compatibility in the same way `wheel` does to avoid having to rename all of
- # the custom wheels that we build/upload to GCS.
-
- # Break import style to ensure that setup.py has had a chance to install the
- # relevant package.
- from six.moves.urllib import request
- decorated_path = decorated_basename + GRPC_CUSTOM_BDIST_EXT
- try:
- url = BINARIES_REPOSITORY + '/{target}'.format(target=decorated_path)
- bdist_data = request.urlopen(url).read()
- except IOError as error:
- raise CommandError(
- '{}\n\nCould not find the bdist {}: {}'
- .format(traceback.format_exc(), decorated_path, error.message))
- # Our chosen local bdist path.
- bdist_path = target_bdist_basename + GRPC_CUSTOM_BDIST_EXT
- try:
- with open(bdist_path, 'w') as bdist_file:
- bdist_file.write(bdist_data)
- except IOError as error:
- raise CommandError(
- '{}\n\nCould not write grpcio bdist: {}'
- .format(traceback.format_exc(), error.message))
- return bdist_path
+ # TODO(atash): somehow the name that's returned from `wheel` is different
+ # between different versions of 'wheel' (but from a compatibility standpoint,
+ # the names are compatible); we should have some way of determining name
+ # compatibility in the same way `wheel` does to avoid having to rename all of
+ # the custom wheels that we build/upload to GCS.
+
+ # Break import style to ensure that setup.py has had a chance to install the
+ # relevant package.
+ from six.moves.urllib import request
+ decorated_path = decorated_basename + GRPC_CUSTOM_BDIST_EXT
+ try:
+ url = BINARIES_REPOSITORY + '/{target}'.format(target=decorated_path)
+ bdist_data = request.urlopen(url).read()
+ except IOError as error:
+ raise CommandError('{}\n\nCould not find the bdist {}: {}'.format(
+ traceback.format_exc(), decorated_path, error.message))
+ # Our chosen local bdist path.
+ bdist_path = target_bdist_basename + GRPC_CUSTOM_BDIST_EXT
+ try:
+ with open(bdist_path, 'w') as bdist_file:
+ bdist_file.write(bdist_data)
+ except IOError as error:
+ raise CommandError('{}\n\nCould not write grpcio bdist: {}'
+ .format(traceback.format_exc(), error.message))
+ return bdist_path
class SphinxDocumentation(setuptools.Command):
- """Command to generate documentation via sphinx."""
-
- description = 'generate sphinx documentation'
- user_options = []
-
- def initialize_options(self):
- pass
-
- def finalize_options(self):
- pass
-
- def run(self):
- # We import here to ensure that setup.py has had a chance to install the
- # relevant package eggs first.
- import sphinx
- import sphinx.apidoc
- metadata = self.distribution.metadata
- src_dir = os.path.join(PYTHON_STEM, 'grpc')
- sys.path.append(src_dir)
- sphinx.apidoc.main([
- '', '--force', '--full', '-H', metadata.name, '-A', metadata.author,
- '-V', metadata.version, '-R', metadata.version,
- '-o', os.path.join('doc', 'src'), src_dir])
- conf_filepath = os.path.join('doc', 'src', 'conf.py')
- with open(conf_filepath, 'a') as conf_file:
- conf_file.write(CONF_PY_ADDENDUM)
- glossary_filepath = os.path.join('doc', 'src', 'grpc.rst')
- with open(glossary_filepath, 'a') as glossary_filepath:
- glossary_filepath.write(API_GLOSSARY)
- sphinx.main(['', os.path.join('doc', 'src'), os.path.join('doc', 'build')])
+ """Command to generate documentation via sphinx."""
+
+ description = 'generate sphinx documentation'
+ user_options = []
+
+ def initialize_options(self):
+ pass
+
+ def finalize_options(self):
+ pass
+
+ def run(self):
+ # We import here to ensure that setup.py has had a chance to install the
+ # relevant package eggs first.
+ import sphinx
+ import sphinx.apidoc
+ metadata = self.distribution.metadata
+ src_dir = os.path.join(PYTHON_STEM, 'grpc')
+ sys.path.append(src_dir)
+ sphinx.apidoc.main([
+ '', '--force', '--full', '-H', metadata.name, '-A', metadata.author,
+ '-V', metadata.version, '-R', metadata.version, '-o',
+ os.path.join('doc', 'src'), src_dir
+ ])
+ conf_filepath = os.path.join('doc', 'src', 'conf.py')
+ with open(conf_filepath, 'a') as conf_file:
+ conf_file.write(CONF_PY_ADDENDUM)
+ glossary_filepath = os.path.join('doc', 'src', 'grpc.rst')
+ with open(glossary_filepath, 'a') as glossary_filepath:
+ glossary_filepath.write(API_GLOSSARY)
+ sphinx.main(
+ ['', os.path.join('doc', 'src'), os.path.join('doc', 'build')])
class BuildProjectMetadata(setuptools.Command):
- """Command to generate project metadata in a module."""
+ """Command to generate project metadata in a module."""
- description = 'build grpcio project metadata files'
- user_options = []
+ description = 'build grpcio project metadata files'
+ user_options = []
- def initialize_options(self):
- pass
+ def initialize_options(self):
+ pass
- def finalize_options(self):
- pass
+ def finalize_options(self):
+ pass
- def run(self):
- with open(os.path.join(PYTHON_STEM, 'grpc/_grpcio_metadata.py'), 'w') as module_file:
- module_file.write('__version__ = """{}"""'.format(
- self.distribution.get_version()))
+ def run(self):
+ with open(os.path.join(PYTHON_STEM, 'grpc/_grpcio_metadata.py'),
+ 'w') as module_file:
+ module_file.write('__version__ = """{}"""'.format(
+ self.distribution.get_version()))
class BuildPy(build_py.build_py):
- """Custom project build command."""
+ """Custom project build command."""
- def run(self):
- self.run_command('build_project_metadata')
- build_py.build_py.run(self)
+ def run(self):
+ self.run_command('build_project_metadata')
+ build_py.build_py.run(self)
def _poison_extensions(extensions, message):
- """Includes a file that will always fail to compile in all extensions."""
- poison_filename = os.path.join(PYTHON_STEM, 'poison.c')
- with open(poison_filename, 'w') as poison:
- poison.write('#error {}'.format(message))
- for extension in extensions:
- extension.sources = [poison_filename]
+ """Includes a file that will always fail to compile in all extensions."""
+ poison_filename = os.path.join(PYTHON_STEM, 'poison.c')
+ with open(poison_filename, 'w') as poison:
+ poison.write('#error {}'.format(message))
+ for extension in extensions:
+ extension.sources = [poison_filename]
+
def check_and_update_cythonization(extensions):
- """Replace .pyx files with their generated counterparts and return whether or
+ """Replace .pyx files with their generated counterparts and return whether or
not cythonization still needs to occur."""
- for extension in extensions:
- generated_pyx_sources = []
- other_sources = []
- for source in extension.sources:
- base, file_ext = os.path.splitext(source)
- if file_ext == '.pyx':
- generated_pyx_source = next(
- (base + gen_ext for gen_ext in ('.c', '.cpp',)
- if os.path.isfile(base + gen_ext)), None)
- if generated_pyx_source:
- generated_pyx_sources.append(generated_pyx_source)
- else:
- sys.stderr.write('Cython-generated files are missing...\n')
- return False
- else:
- other_sources.append(source)
- extension.sources = generated_pyx_sources + other_sources
- sys.stderr.write('Found cython-generated files...\n')
- return True
+ for extension in extensions:
+ generated_pyx_sources = []
+ other_sources = []
+ for source in extension.sources:
+ base, file_ext = os.path.splitext(source)
+ if file_ext == '.pyx':
+ generated_pyx_source = next((base + gen_ext
+ for gen_ext in (
+ '.c',
+ '.cpp',)
+ if os.path.isfile(base + gen_ext)),
+ None)
+ if generated_pyx_source:
+ generated_pyx_sources.append(generated_pyx_source)
+ else:
+ sys.stderr.write('Cython-generated files are missing...\n')
+ return False
+ else:
+ other_sources.append(source)
+ extension.sources = generated_pyx_sources + other_sources
+ sys.stderr.write('Found cython-generated files...\n')
+ return True
+
def try_cythonize(extensions, linetracing=False, mandatory=True):
- """Attempt to cythonize the extensions.
+ """Attempt to cythonize the extensions.
Args:
extensions: A list of `distutils.extension.Extension`.
@@ -226,78 +231,83 @@ def try_cythonize(extensions, linetracing=False, mandatory=True):
mandatory: Whether or not having Cython-generated files is mandatory. If it
is, extensions will be poisoned when they can't be fully generated.
"""
- try:
- # Break import style to ensure we have access to Cython post-setup_requires
- import Cython.Build
- except ImportError:
- if mandatory:
- sys.stderr.write(
- "This package needs to generate C files with Cython but it cannot. "
- "Poisoning extension sources to disallow extension commands...")
- _poison_extensions(
- extensions,
- "Extensions have been poisoned due to missing Cython-generated code.")
- return extensions
- cython_compiler_directives = {}
- if linetracing:
- additional_define_macros = [('CYTHON_TRACE_NOGIL', '1')]
- cython_compiler_directives['linetrace'] = True
- return Cython.Build.cythonize(
- extensions,
- include_path=[
- include_dir for extension in extensions for include_dir in extension.include_dirs
- ] + [CYTHON_STEM],
- compiler_directives=cython_compiler_directives
- )
+ try:
+ # Break import style to ensure we have access to Cython post-setup_requires
+ import Cython.Build
+ except ImportError:
+ if mandatory:
+ sys.stderr.write(
+ "This package needs to generate C files with Cython but it cannot. "
+ "Poisoning extension sources to disallow extension commands...")
+ _poison_extensions(
+ extensions,
+ "Extensions have been poisoned due to missing Cython-generated code."
+ )
+ return extensions
+ cython_compiler_directives = {}
+ if linetracing:
+ additional_define_macros = [('CYTHON_TRACE_NOGIL', '1')]
+ cython_compiler_directives['linetrace'] = True
+ return Cython.Build.cythonize(
+ extensions,
+ include_path=[
+ include_dir
+ for extension in extensions
+ for include_dir in extension.include_dirs
+ ] + [CYTHON_STEM],
+ compiler_directives=cython_compiler_directives)
class BuildExt(build_ext.build_ext):
- """Custom build_ext command to enable compiler-specific flags."""
-
- C_OPTIONS = {
- 'unix': ('-pthread', '-std=gnu99'),
- 'msvc': (),
- }
- LINK_OPTIONS = {}
-
- def build_extensions(self):
- compiler = self.compiler.compiler_type
- if compiler in BuildExt.C_OPTIONS:
- for extension in self.extensions:
- extension.extra_compile_args += list(BuildExt.C_OPTIONS[compiler])
- if compiler in BuildExt.LINK_OPTIONS:
- for extension in self.extensions:
- extension.extra_link_args += list(BuildExt.LINK_OPTIONS[compiler])
- if not check_and_update_cythonization(self.extensions):
- self.extensions = try_cythonize(self.extensions)
- try:
- build_ext.build_ext.build_extensions(self)
- except Exception as error:
- formatted_exception = traceback.format_exc()
- support.diagnose_build_ext_error(self, error, formatted_exception)
- raise CommandError(
- "Failed `build_ext` step:\n{}".format(formatted_exception))
+ """Custom build_ext command to enable compiler-specific flags."""
+
+ C_OPTIONS = {
+ 'unix': ('-pthread', '-std=gnu99'),
+ 'msvc': (),
+ }
+ LINK_OPTIONS = {}
+
+ def build_extensions(self):
+ compiler = self.compiler.compiler_type
+ if compiler in BuildExt.C_OPTIONS:
+ for extension in self.extensions:
+ extension.extra_compile_args += list(BuildExt.C_OPTIONS[
+ compiler])
+ if compiler in BuildExt.LINK_OPTIONS:
+ for extension in self.extensions:
+ extension.extra_link_args += list(BuildExt.LINK_OPTIONS[
+ compiler])
+ if not check_and_update_cythonization(self.extensions):
+ self.extensions = try_cythonize(self.extensions)
+ try:
+ build_ext.build_ext.build_extensions(self)
+ except Exception as error:
+ formatted_exception = traceback.format_exc()
+ support.diagnose_build_ext_error(self, error, formatted_exception)
+ raise CommandError("Failed `build_ext` step:\n{}".format(
+ formatted_exception))
class Gather(setuptools.Command):
- """Command to gather project dependencies."""
-
- description = 'gather dependencies for grpcio'
- user_options = [
- ('test', 't', 'flag indicating to gather test dependencies'),
- ('install', 'i', 'flag indicating to gather install dependencies')
- ]
-
- def initialize_options(self):
- self.test = False
- self.install = False
-
- def finalize_options(self):
- # distutils requires this override.
- pass
-
- def run(self):
- if self.install and self.distribution.install_requires:
- self.distribution.fetch_build_eggs(self.distribution.install_requires)
- if self.test and self.distribution.tests_require:
- self.distribution.fetch_build_eggs(self.distribution.tests_require)
+ """Command to gather project dependencies."""
+
+ description = 'gather dependencies for grpcio'
+ user_options = [
+ ('test', 't', 'flag indicating to gather test dependencies'),
+ ('install', 'i', 'flag indicating to gather install dependencies')
+ ]
+
+ def initialize_options(self):
+ self.test = False
+ self.install = False
+
+ def finalize_options(self):
+ # distutils requires this override.
+ pass
+
+ def run(self):
+ if self.install and self.distribution.install_requires:
+ self.distribution.fetch_build_eggs(
+ self.distribution.install_requires)
+ if self.test and self.distribution.tests_require:
+ self.distribution.fetch_build_eggs(self.distribution.tests_require)
diff --git a/src/python/grpcio/grpc/__init__.py b/src/python/grpcio/grpc/__init__.py
index e3c10156d0..abe14e7049 100644
--- a/src/python/grpcio/grpc/__init__.py
+++ b/src/python/grpcio/grpc/__init__.py
@@ -26,7 +26,6 @@
# 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.
-
"""gRPC's Python API."""
import abc
@@ -37,28 +36,27 @@ import six
from grpc._cython import cygrpc as _cygrpc
-
############################## Future Interface ###############################
class FutureTimeoutError(Exception):
- """Indicates that a method call on a Future timed out."""
+ """Indicates that a method call on a Future timed out."""
class FutureCancelledError(Exception):
- """Indicates that the computation underlying a Future was cancelled."""
+ """Indicates that the computation underlying a Future was cancelled."""
class Future(six.with_metaclass(abc.ABCMeta)):
- """A representation of a computation in another control flow.
+ """A representation of a computation in another control flow.
Computations represented by a Future may be yet to be begun, may be ongoing,
or may have already completed.
"""
- @abc.abstractmethod
- def cancel(self):
- """Attempts to cancel the computation.
+ @abc.abstractmethod
+ def cancel(self):
+ """Attempts to cancel the computation.
This method does not block.
@@ -71,11 +69,11 @@ class Future(six.with_metaclass(abc.ABCMeta)):
remote system for which a determination of whether or not it commenced
before being cancelled cannot be made without blocking.
"""
- raise NotImplementedError()
+ raise NotImplementedError()
- @abc.abstractmethod
- def cancelled(self):
- """Describes whether the computation was cancelled.
+ @abc.abstractmethod
+ def cancelled(self):
+ """Describes whether the computation was cancelled.
This method does not block.
@@ -85,11 +83,11 @@ class Future(six.with_metaclass(abc.ABCMeta)):
not limited to this object's cancel method not having been called and
the computation's result having become immediately available.
"""
- raise NotImplementedError()
+ raise NotImplementedError()
- @abc.abstractmethod
- def running(self):
- """Describes whether the computation is taking place.
+ @abc.abstractmethod
+ def running(self):
+ """Describes whether the computation is taking place.
This method does not block.
@@ -98,11 +96,11 @@ class Future(six.with_metaclass(abc.ABCMeta)):
taking place now, or False if the computation took place in the past or
was cancelled.
"""
- raise NotImplementedError()
+ raise NotImplementedError()
- @abc.abstractmethod
- def done(self):
- """Describes whether the computation has taken place.
+ @abc.abstractmethod
+ def done(self):
+ """Describes whether the computation has taken place.
This method does not block.
@@ -111,11 +109,11 @@ class Future(six.with_metaclass(abc.ABCMeta)):
unscheduled or interrupted. False if the computation may possibly be
executing or scheduled to execute later.
"""
- raise NotImplementedError()
+ raise NotImplementedError()
- @abc.abstractmethod
- def result(self, timeout=None):
- """Accesses the outcome of the computation or raises its exception.
+ @abc.abstractmethod
+ def result(self, timeout=None):
+ """Accesses the outcome of the computation or raises its exception.
This method may return immediately or may block.
@@ -134,11 +132,11 @@ class Future(six.with_metaclass(abc.ABCMeta)):
Exception: If the computation raised an exception, this call will raise
the same exception.
"""
- raise NotImplementedError()
+ raise NotImplementedError()
- @abc.abstractmethod
- def exception(self, timeout=None):
- """Return the exception raised by the computation.
+ @abc.abstractmethod
+ def exception(self, timeout=None):
+ """Return the exception raised by the computation.
This method may return immediately or may block.
@@ -157,11 +155,11 @@ class Future(six.with_metaclass(abc.ABCMeta)):
not terminate within the allotted time.
FutureCancelledError: If the computation was cancelled.
"""
- raise NotImplementedError()
+ raise NotImplementedError()
- @abc.abstractmethod
- def traceback(self, timeout=None):
- """Access the traceback of the exception raised by the computation.
+ @abc.abstractmethod
+ def traceback(self, timeout=None):
+ """Access the traceback of the exception raised by the computation.
This method may return immediately or may block.
@@ -180,11 +178,11 @@ class Future(six.with_metaclass(abc.ABCMeta)):
not terminate within the allotted time.
FutureCancelledError: If the computation was cancelled.
"""
- raise NotImplementedError()
+ raise NotImplementedError()
- @abc.abstractmethod
- def add_done_callback(self, fn):
- """Adds a function to be called at completion of the computation.
+ @abc.abstractmethod
+ def add_done_callback(self, fn):
+ """Adds a function to be called at completion of the computation.
The callback will be passed this Future object describing the outcome of
the computation.
@@ -195,7 +193,7 @@ class Future(six.with_metaclass(abc.ABCMeta)):
Args:
fn: A callable taking this Future object as its single parameter.
"""
- raise NotImplementedError()
+ raise NotImplementedError()
################################ gRPC Enums ##################################
@@ -203,7 +201,7 @@ class Future(six.with_metaclass(abc.ABCMeta)):
@enum.unique
class ChannelConnectivity(enum.Enum):
- """Mirrors grpc_connectivity_state in the gRPC Core.
+ """Mirrors grpc_connectivity_state in the gRPC Core.
Attributes:
IDLE: The channel is idle.
@@ -213,81 +211,80 @@ class ChannelConnectivity(enum.Enum):
recover.
SHUTDOWN: The channel has seen a failure from which it cannot recover.
"""
- IDLE = (_cygrpc.ConnectivityState.idle, 'idle')
- CONNECTING = (_cygrpc.ConnectivityState.connecting, 'connecting')
- READY = (_cygrpc.ConnectivityState.ready, 'ready')
- TRANSIENT_FAILURE = (
- _cygrpc.ConnectivityState.transient_failure, 'transient failure')
- SHUTDOWN = (_cygrpc.ConnectivityState.shutdown, 'shutdown')
+ IDLE = (_cygrpc.ConnectivityState.idle, 'idle')
+ CONNECTING = (_cygrpc.ConnectivityState.connecting, 'connecting')
+ READY = (_cygrpc.ConnectivityState.ready, 'ready')
+ TRANSIENT_FAILURE = (_cygrpc.ConnectivityState.transient_failure,
+ 'transient failure')
+ SHUTDOWN = (_cygrpc.ConnectivityState.shutdown, 'shutdown')
@enum.unique
class StatusCode(enum.Enum):
- """Mirrors grpc_status_code in the gRPC Core."""
- OK = (_cygrpc.StatusCode.ok, 'ok')
- CANCELLED = (_cygrpc.StatusCode.cancelled, 'cancelled')
- UNKNOWN = (_cygrpc.StatusCode.unknown, 'unknown')
- INVALID_ARGUMENT = (
- _cygrpc.StatusCode.invalid_argument, 'invalid argument')
- DEADLINE_EXCEEDED = (
- _cygrpc.StatusCode.deadline_exceeded, 'deadline exceeded')
- NOT_FOUND = (_cygrpc.StatusCode.not_found, 'not found')
- ALREADY_EXISTS = (_cygrpc.StatusCode.already_exists, 'already exists')
- PERMISSION_DENIED = (
- _cygrpc.StatusCode.permission_denied, 'permission denied')
- RESOURCE_EXHAUSTED = (
- _cygrpc.StatusCode.resource_exhausted, 'resource exhausted')
- FAILED_PRECONDITION = (
- _cygrpc.StatusCode.failed_precondition, 'failed precondition')
- ABORTED = (_cygrpc.StatusCode.aborted, 'aborted')
- OUT_OF_RANGE = (_cygrpc.StatusCode.out_of_range, 'out of range')
- UNIMPLEMENTED = (_cygrpc.StatusCode.unimplemented, 'unimplemented')
- INTERNAL = (_cygrpc.StatusCode.internal, 'internal')
- UNAVAILABLE = (_cygrpc.StatusCode.unavailable, 'unavailable')
- DATA_LOSS = (_cygrpc.StatusCode.data_loss, 'data loss')
- UNAUTHENTICATED = (_cygrpc.StatusCode.unauthenticated, 'unauthenticated')
+ """Mirrors grpc_status_code in the gRPC Core."""
+ OK = (_cygrpc.StatusCode.ok, 'ok')
+ CANCELLED = (_cygrpc.StatusCode.cancelled, 'cancelled')
+ UNKNOWN = (_cygrpc.StatusCode.unknown, 'unknown')
+ INVALID_ARGUMENT = (_cygrpc.StatusCode.invalid_argument, 'invalid argument')
+ DEADLINE_EXCEEDED = (_cygrpc.StatusCode.deadline_exceeded,
+ 'deadline exceeded')
+ NOT_FOUND = (_cygrpc.StatusCode.not_found, 'not found')
+ ALREADY_EXISTS = (_cygrpc.StatusCode.already_exists, 'already exists')
+ PERMISSION_DENIED = (_cygrpc.StatusCode.permission_denied,
+ 'permission denied')
+ RESOURCE_EXHAUSTED = (_cygrpc.StatusCode.resource_exhausted,
+ 'resource exhausted')
+ FAILED_PRECONDITION = (_cygrpc.StatusCode.failed_precondition,
+ 'failed precondition')
+ ABORTED = (_cygrpc.StatusCode.aborted, 'aborted')
+ OUT_OF_RANGE = (_cygrpc.StatusCode.out_of_range, 'out of range')
+ UNIMPLEMENTED = (_cygrpc.StatusCode.unimplemented, 'unimplemented')
+ INTERNAL = (_cygrpc.StatusCode.internal, 'internal')
+ UNAVAILABLE = (_cygrpc.StatusCode.unavailable, 'unavailable')
+ DATA_LOSS = (_cygrpc.StatusCode.data_loss, 'data loss')
+ UNAUTHENTICATED = (_cygrpc.StatusCode.unauthenticated, 'unauthenticated')
############################# gRPC Exceptions ################################
class RpcError(Exception):
- """Raised by the gRPC library to indicate non-OK-status RPC termination."""
+ """Raised by the gRPC library to indicate non-OK-status RPC termination."""
############################## Shared Context ################################
class RpcContext(six.with_metaclass(abc.ABCMeta)):
- """Provides RPC-related information and action."""
+ """Provides RPC-related information and action."""
- @abc.abstractmethod
- def is_active(self):
- """Describes whether the RPC is active or has terminated."""
- raise NotImplementedError()
+ @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.
+ @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, or None if no deadline was specified for the RPC.
"""
- raise NotImplementedError()
+ raise NotImplementedError()
- @abc.abstractmethod
- def cancel(self):
- """Cancels the RPC.
+ @abc.abstractmethod
+ def cancel(self):
+ """Cancels the RPC.
Idempotent and has no effect if the RPC has already terminated.
"""
- raise NotImplementedError()
+ raise NotImplementedError()
- @abc.abstractmethod
- def add_callback(self, callback):
- """Registers a callback to be called on RPC termination.
+ @abc.abstractmethod
+ def add_callback(self, callback):
+ """Registers a callback to be called on RPC termination.
Args:
callback: A no-parameter callable to be called on RPC termination.
@@ -297,76 +294,76 @@ class RpcContext(six.with_metaclass(abc.ABCMeta)):
callback was not added and will not later be called (because the RPC
already terminated or some other reason).
"""
- raise NotImplementedError()
+ raise NotImplementedError()
######################### Invocation-Side Context ############################
class Call(six.with_metaclass(abc.ABCMeta, RpcContext)):
- """Invocation-side utility object for an RPC."""
+ """Invocation-side utility object for an RPC."""
- @abc.abstractmethod
- def initial_metadata(self):
- """Accesses the initial metadata from the service-side of the RPC.
+ @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.
Returns:
The initial :term:`metadata`.
"""
- raise NotImplementedError()
+ raise NotImplementedError()
- @abc.abstractmethod
- def trailing_metadata(self):
- """Accesses the trailing metadata from the service-side of the RPC.
+ @abc.abstractmethod
+ def trailing_metadata(self):
+ """Accesses the trailing metadata from the service-side of the RPC.
This method blocks until the value is available.
Returns:
The trailing :term:`metadata`.
"""
- raise NotImplementedError()
+ raise NotImplementedError()
- @abc.abstractmethod
- def code(self):
- """Accesses the status code emitted by the service-side of the RPC.
+ @abc.abstractmethod
+ def code(self):
+ """Accesses the status code emitted by the service-side of the RPC.
This method blocks until the value is available.
Returns:
The StatusCode value for the RPC.
"""
- raise NotImplementedError()
+ raise NotImplementedError()
- @abc.abstractmethod
- def details(self):
- """Accesses the details value emitted by the service-side of the RPC.
+ @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.
Returns:
The details string of the RPC.
"""
- raise NotImplementedError()
+ raise NotImplementedError()
############ Authentication & Authorization Interfaces & Classes #############
class ChannelCredentials(object):
- """A value encapsulating the data required to create a secure Channel.
+ """A value encapsulating the data required to create a secure Channel.
This class has no supported interface - it exists to define the type of its
instances and its instances exist to be passed to other functions.
"""
- def __init__(self, credentials):
- self._credentials = credentials
+ def __init__(self, credentials):
+ self._credentials = credentials
class CallCredentials(object):
- """A value encapsulating data asserting an identity over a channel.
+ """A value encapsulating data asserting an identity over a channel.
A CallCredentials may be composed with ChannelCredentials to always assert
identity for every call over that Channel.
@@ -375,12 +372,12 @@ class CallCredentials(object):
instances and its instances exist to be passed to other functions.
"""
- def __init__(self, credentials):
- self._credentials = credentials
+ def __init__(self, credentials):
+ self._credentials = credentials
class AuthMetadataContext(six.with_metaclass(abc.ABCMeta)):
- """Provides information to call credentials metadata plugins.
+ """Provides information to call credentials metadata plugins.
Attributes:
service_url: A string URL of the service being called into.
@@ -389,23 +386,23 @@ class AuthMetadataContext(six.with_metaclass(abc.ABCMeta)):
class AuthMetadataPluginCallback(six.with_metaclass(abc.ABCMeta)):
- """Callback object received by a metadata plugin."""
+ """Callback object received by a metadata plugin."""
- def __call__(self, metadata, error):
- """Inform the gRPC runtime of the metadata to construct a CallCredentials.
+ def __call__(self, metadata, error):
+ """Inform the gRPC runtime of the metadata to construct a CallCredentials.
Args:
metadata: The :term:`metadata` used to construct the CallCredentials.
error: An Exception to indicate error or None to indicate success.
"""
- raise NotImplementedError()
+ raise NotImplementedError()
class AuthMetadataPlugin(six.with_metaclass(abc.ABCMeta)):
- """A specification for custom authentication."""
+ """A specification for custom authentication."""
- def __call__(self, context, callback):
- """Implements authentication by passing metadata to a callback.
+ def __call__(self, context, callback):
+ """Implements authentication by passing metadata to a callback.
Implementations of this method must not block.
@@ -415,29 +412,29 @@ class AuthMetadataPlugin(six.with_metaclass(abc.ABCMeta)):
callback: An AuthMetadataPluginCallback to be invoked either synchronously
or asynchronously.
"""
- raise NotImplementedError()
+ raise NotImplementedError()
class ServerCredentials(object):
- """A value encapsulating the data required to open a secure port on a Server.
+ """A value encapsulating the data required to open a secure port on a Server.
This class has no supported interface - it exists to define the type of its
instances and its instances exist to be passed to other functions.
"""
- def __init__(self, credentials):
- self._credentials = credentials
+ def __init__(self, credentials):
+ self._credentials = credentials
######################## Multi-Callable Interfaces ###########################
class UnaryUnaryMultiCallable(six.with_metaclass(abc.ABCMeta)):
- """Affords invoking a unary-unary RPC."""
+ """Affords invoking a unary-unary RPC."""
- @abc.abstractmethod
- def __call__(self, request, timeout=None, metadata=None, credentials=None):
- """Synchronously invokes the underlying RPC.
+ @abc.abstractmethod
+ def __call__(self, request, timeout=None, metadata=None, credentials=None):
+ """Synchronously invokes the underlying RPC.
Args:
request: The request value for the RPC.
@@ -454,11 +451,11 @@ class UnaryUnaryMultiCallable(six.with_metaclass(abc.ABCMeta)):
raised RpcError will also be a Call for the RPC affording the RPC's
metadata, status code, and details.
"""
- raise NotImplementedError()
+ raise NotImplementedError()
- @abc.abstractmethod
- def with_call(self, request, timeout=None, metadata=None, credentials=None):
- """Synchronously invokes the underlying RPC.
+ @abc.abstractmethod
+ def with_call(self, request, timeout=None, metadata=None, credentials=None):
+ """Synchronously invokes the underlying RPC.
Args:
request: The request value for the RPC.
@@ -475,11 +472,11 @@ class UnaryUnaryMultiCallable(six.with_metaclass(abc.ABCMeta)):
raised RpcError will also be a Call for the RPC affording the RPC's
metadata, status code, and details.
"""
- raise NotImplementedError()
+ raise NotImplementedError()
- @abc.abstractmethod
- def future(self, request, timeout=None, metadata=None, credentials=None):
- """Asynchronously invokes the underlying RPC.
+ @abc.abstractmethod
+ def future(self, request, timeout=None, metadata=None, credentials=None):
+ """Asynchronously invokes the underlying RPC.
Args:
request: The request value for the RPC.
@@ -494,15 +491,15 @@ class UnaryUnaryMultiCallable(six.with_metaclass(abc.ABCMeta)):
message of the RPC. Should the event terminate with non-OK status, the
returned Future's exception value will be an RpcError.
"""
- raise NotImplementedError()
+ raise NotImplementedError()
class UnaryStreamMultiCallable(six.with_metaclass(abc.ABCMeta)):
- """Affords invoking a unary-stream RPC."""
+ """Affords invoking a unary-stream RPC."""
- @abc.abstractmethod
- def __call__(self, request, timeout=None, metadata=None, credentials=None):
- """Invokes the underlying RPC.
+ @abc.abstractmethod
+ def __call__(self, request, timeout=None, metadata=None, credentials=None):
+ """Invokes the underlying RPC.
Args:
request: The request value for the RPC.
@@ -516,16 +513,19 @@ class UnaryStreamMultiCallable(six.with_metaclass(abc.ABCMeta)):
values. Drawing response values from the returned iterator may raise
RpcError indicating termination of the RPC with non-OK status.
"""
- raise NotImplementedError()
+ raise NotImplementedError()
class StreamUnaryMultiCallable(six.with_metaclass(abc.ABCMeta)):
- """Affords invoking a stream-unary RPC in any call style."""
+ """Affords invoking a stream-unary RPC in any call style."""
- @abc.abstractmethod
- def __call__(
- self, request_iterator, timeout=None, metadata=None, credentials=None):
- """Synchronously invokes the underlying RPC.
+ @abc.abstractmethod
+ def __call__(self,
+ request_iterator,
+ timeout=None,
+ metadata=None,
+ credentials=None):
+ """Synchronously invokes the underlying RPC.
Args:
request_iterator: An iterator that yields request values for the RPC.
@@ -543,12 +543,15 @@ class StreamUnaryMultiCallable(six.with_metaclass(abc.ABCMeta)):
raised RpcError will also be a Call for the RPC affording the RPC's
metadata, status code, and details.
"""
- raise NotImplementedError()
+ raise NotImplementedError()
- @abc.abstractmethod
- def with_call(
- self, request_iterator, timeout=None, metadata=None, credentials=None):
- """Synchronously invokes the underlying RPC.
+ @abc.abstractmethod
+ def with_call(self,
+ request_iterator,
+ timeout=None,
+ metadata=None,
+ credentials=None):
+ """Synchronously invokes the underlying RPC.
Args:
request_iterator: An iterator that yields request values for the RPC.
@@ -565,12 +568,15 @@ class StreamUnaryMultiCallable(six.with_metaclass(abc.ABCMeta)):
raised RpcError will also be a Call for the RPC affording the RPC's
metadata, status code, and details.
"""
- raise NotImplementedError()
+ raise NotImplementedError()
- @abc.abstractmethod
- def future(
- self, request_iterator, timeout=None, metadata=None, credentials=None):
- """Asynchronously invokes the underlying RPC.
+ @abc.abstractmethod
+ def future(self,
+ request_iterator,
+ timeout=None,
+ metadata=None,
+ credentials=None):
+ """Asynchronously invokes the underlying RPC.
Args:
request_iterator: An iterator that yields request values for the RPC.
@@ -585,16 +591,19 @@ class StreamUnaryMultiCallable(six.with_metaclass(abc.ABCMeta)):
message of the RPC. Should the event terminate with non-OK status, the
returned Future's exception value will be an RpcError.
"""
- raise NotImplementedError()
+ raise NotImplementedError()
class StreamStreamMultiCallable(six.with_metaclass(abc.ABCMeta)):
- """Affords invoking a stream-stream RPC in any call style."""
+ """Affords invoking a stream-stream RPC in any call style."""
- @abc.abstractmethod
- def __call__(
- self, request_iterator, timeout=None, metadata=None, credentials=None):
- """Invokes the underlying RPC.
+ @abc.abstractmethod
+ def __call__(self,
+ request_iterator,
+ timeout=None,
+ metadata=None,
+ credentials=None):
+ """Invokes the underlying RPC.
Args:
request_iterator: An iterator that yields request values for the RPC.
@@ -608,18 +617,18 @@ class StreamStreamMultiCallable(six.with_metaclass(abc.ABCMeta)):
values. Drawing response values from the returned iterator may raise
RpcError indicating termination of the RPC with non-OK status.
"""
- raise NotImplementedError()
+ raise NotImplementedError()
############################# Channel Interface ##############################
class Channel(six.with_metaclass(abc.ABCMeta)):
- """Affords RPC invocation via generic methods."""
+ """Affords RPC invocation via generic methods."""
- @abc.abstractmethod
- def subscribe(self, callback, try_to_connect=False):
- """Subscribes to this Channel's connectivity.
+ @abc.abstractmethod
+ def subscribe(self, callback, try_to_connect=False):
+ """Subscribes to this Channel's connectivity.
Args:
callback: A callable to be invoked and passed a ChannelConnectivity value
@@ -631,22 +640,24 @@ class Channel(six.with_metaclass(abc.ABCMeta)):
attempt to connect if it is not already connected and ready to conduct
RPCs.
"""
- raise NotImplementedError()
+ raise NotImplementedError()
- @abc.abstractmethod
- def unsubscribe(self, callback):
- """Unsubscribes a callback from this Channel's connectivity.
+ @abc.abstractmethod
+ def unsubscribe(self, callback):
+ """Unsubscribes a callback from this Channel's connectivity.
Args:
callback: A callable previously registered with this Channel from having
been passed to its "subscribe" method.
"""
- raise NotImplementedError()
+ raise NotImplementedError()
- @abc.abstractmethod
- def unary_unary(
- self, method, request_serializer=None, response_deserializer=None):
- """Creates a UnaryUnaryMultiCallable for a unary-unary method.
+ @abc.abstractmethod
+ def unary_unary(self,
+ method,
+ request_serializer=None,
+ response_deserializer=None):
+ """Creates a UnaryUnaryMultiCallable for a unary-unary method.
Args:
method: The name of the RPC method.
@@ -658,12 +669,14 @@ class Channel(six.with_metaclass(abc.ABCMeta)):
Returns:
A UnaryUnaryMultiCallable value for the named unary-unary method.
"""
- raise NotImplementedError()
+ raise NotImplementedError()
- @abc.abstractmethod
- def unary_stream(
- self, method, request_serializer=None, response_deserializer=None):
- """Creates a UnaryStreamMultiCallable for a unary-stream method.
+ @abc.abstractmethod
+ def unary_stream(self,
+ method,
+ request_serializer=None,
+ response_deserializer=None):
+ """Creates a UnaryStreamMultiCallable for a unary-stream method.
Args:
method: The name of the RPC method.
@@ -675,12 +688,14 @@ class Channel(six.with_metaclass(abc.ABCMeta)):
Returns:
A UnaryStreamMultiCallable value for the name unary-stream method.
"""
- raise NotImplementedError()
+ raise NotImplementedError()
- @abc.abstractmethod
- def stream_unary(
- self, method, request_serializer=None, response_deserializer=None):
- """Creates a StreamUnaryMultiCallable for a stream-unary method.
+ @abc.abstractmethod
+ def stream_unary(self,
+ method,
+ request_serializer=None,
+ response_deserializer=None):
+ """Creates a StreamUnaryMultiCallable for a stream-unary method.
Args:
method: The name of the RPC method.
@@ -692,12 +707,14 @@ class Channel(six.with_metaclass(abc.ABCMeta)):
Returns:
A StreamUnaryMultiCallable value for the named stream-unary method.
"""
- raise NotImplementedError()
+ raise NotImplementedError()
- @abc.abstractmethod
- def stream_stream(
- self, method, request_serializer=None, response_deserializer=None):
- """Creates a StreamStreamMultiCallable for a stream-stream method.
+ @abc.abstractmethod
+ def stream_stream(self,
+ method,
+ request_serializer=None,
+ response_deserializer=None):
+ """Creates a StreamStreamMultiCallable for a stream-stream method.
Args:
method: The name of the RPC method.
@@ -709,36 +726,36 @@ class Channel(six.with_metaclass(abc.ABCMeta)):
Returns:
A StreamStreamMultiCallable value for the named stream-stream method.
"""
- raise NotImplementedError()
+ raise NotImplementedError()
########################## Service-Side Context ##############################
class ServicerContext(six.with_metaclass(abc.ABCMeta, RpcContext)):
- """A context object passed to method implementations."""
+ """A context object passed to method implementations."""
- @abc.abstractmethod
- def invocation_metadata(self):
- """Accesses the metadata from the invocation-side of the RPC.
+ @abc.abstractmethod
+ def invocation_metadata(self):
+ """Accesses the metadata from the invocation-side of the RPC.
Returns:
The invocation :term:`metadata`.
"""
- raise NotImplementedError()
+ raise NotImplementedError()
- @abc.abstractmethod
- def peer(self):
- """Identifies the peer that invoked the RPC being serviced.
+ @abc.abstractmethod
+ def peer(self):
+ """Identifies the peer that invoked the RPC being serviced.
Returns:
A string identifying the peer that invoked the RPC being serviced.
"""
- raise NotImplementedError()
+ raise NotImplementedError()
- @abc.abstractmethod
- def send_initial_metadata(self, initial_metadata):
- """Sends the initial metadata value to the invocation-side of the RPC.
+ @abc.abstractmethod
+ def send_initial_metadata(self, initial_metadata):
+ """Sends the initial metadata value to the invocation-side of the RPC.
This method need not be called by method implementations if they have no
service-side initial metadata to transmit.
@@ -746,11 +763,11 @@ class ServicerContext(six.with_metaclass(abc.ABCMeta, RpcContext)):
Args:
initial_metadata: The initial :term:`metadata`.
"""
- raise NotImplementedError()
+ raise NotImplementedError()
- @abc.abstractmethod
- def set_trailing_metadata(self, trailing_metadata):
- """Accepts the trailing metadata value of the RPC.
+ @abc.abstractmethod
+ def set_trailing_metadata(self, trailing_metadata):
+ """Accepts the trailing metadata value of the RPC.
This method need not be called by method implementations if they have no
service-side trailing metadata to transmit.
@@ -758,11 +775,11 @@ class ServicerContext(six.with_metaclass(abc.ABCMeta, RpcContext)):
Args:
trailing_metadata: The trailing :term:`metadata`.
"""
- raise NotImplementedError()
+ raise NotImplementedError()
- @abc.abstractmethod
- def set_code(self, code):
- """Accepts the status code of the RPC.
+ @abc.abstractmethod
+ def set_code(self, code):
+ """Accepts the status code of the RPC.
This method need not be called by method implementations if they wish the
gRPC runtime to determine the status code of the RPC.
@@ -771,11 +788,11 @@ class ServicerContext(six.with_metaclass(abc.ABCMeta, RpcContext)):
code: A StatusCode value to be transmitted to the invocation side of the
RPC as the status code of the RPC.
"""
- raise NotImplementedError()
+ raise NotImplementedError()
- @abc.abstractmethod
- def set_details(self, details):
- """Accepts the service-side details of the RPC.
+ @abc.abstractmethod
+ def set_details(self, details):
+ """Accepts the service-side details of the RPC.
This method need not be called by method implementations if they have no
details to transmit.
@@ -784,14 +801,14 @@ class ServicerContext(six.with_metaclass(abc.ABCMeta, RpcContext)):
details: A string to be transmitted to the invocation side of the RPC as
the status details of the RPC.
"""
- raise NotImplementedError()
+ raise NotImplementedError()
##################### Service-Side Handler Interfaces ########################
class RpcMethodHandler(six.with_metaclass(abc.ABCMeta)):
- """An implementation of a single RPC method.
+ """An implementation of a single RPC method.
Attributes:
request_streaming: Whether the RPC supports exactly one request message or
@@ -826,7 +843,7 @@ class RpcMethodHandler(six.with_metaclass(abc.ABCMeta)):
class HandlerCallDetails(six.with_metaclass(abc.ABCMeta)):
- """Describes an RPC that has just arrived for service.
+ """Describes an RPC that has just arrived for service.
Attributes:
method: The method name of the RPC.
invocation_metadata: The :term:`metadata` from the invocation side of the RPC.
@@ -834,11 +851,11 @@ class HandlerCallDetails(six.with_metaclass(abc.ABCMeta)):
class GenericRpcHandler(six.with_metaclass(abc.ABCMeta)):
- """An implementation of arbitrarily many RPC methods."""
+ """An implementation of arbitrarily many RPC methods."""
- @abc.abstractmethod
- def service(self, handler_call_details):
- """Services an RPC (or not).
+ @abc.abstractmethod
+ def service(self, handler_call_details):
+ """Services an RPC (or not).
Args:
handler_call_details: A HandlerCallDetails describing the RPC.
@@ -847,11 +864,11 @@ class GenericRpcHandler(six.with_metaclass(abc.ABCMeta)):
An RpcMethodHandler with which the RPC may be serviced, or None to
indicate that this object will not be servicing the RPC.
"""
- raise NotImplementedError()
+ raise NotImplementedError()
class ServiceRpcHandler(six.with_metaclass(abc.ABCMeta, GenericRpcHandler)):
- """An implementation of RPC methods belonging to a service.
+ """An implementation of RPC methods belonging to a service.
A service handles RPC methods with structured names of the form
'/Service.Name/Service.MethodX', where 'Service.Name' is the value
@@ -860,25 +877,25 @@ class ServiceRpcHandler(six.with_metaclass(abc.ABCMeta, GenericRpcHandler)):
service name.
"""
- @abc.abstractmethod
- def service_name(self):
- """Returns this services name.
+ @abc.abstractmethod
+ def service_name(self):
+ """Returns this services name.
Returns:
The service name.
"""
- raise NotImplementedError()
+ raise NotImplementedError()
############################# Server Interface ###############################
class Server(six.with_metaclass(abc.ABCMeta)):
- """Services RPCs."""
+ """Services RPCs."""
- @abc.abstractmethod
- def add_generic_rpc_handlers(self, generic_rpc_handlers):
- """Registers GenericRpcHandlers with this Server.
+ @abc.abstractmethod
+ def add_generic_rpc_handlers(self, generic_rpc_handlers):
+ """Registers GenericRpcHandlers with this Server.
This method is only safe to call before the server is started.
@@ -886,11 +903,11 @@ class Server(six.with_metaclass(abc.ABCMeta)):
generic_rpc_handlers: An iterable of GenericRpcHandlers that will be used
to service RPCs after this Server is started.
"""
- raise NotImplementedError()
+ raise NotImplementedError()
- @abc.abstractmethod
- def add_insecure_port(self, address):
- """Reserves a port for insecure RPC service once this Server becomes active.
+ @abc.abstractmethod
+ def add_insecure_port(self, address):
+ """Reserves a port for insecure RPC service once this Server becomes active.
This method may only be called before calling this Server's start method is
called.
@@ -904,11 +921,11 @@ class Server(six.with_metaclass(abc.ABCMeta)):
in the passed address, but will likely be different if the port number
contained in the passed address was zero.
"""
- raise NotImplementedError()
+ raise NotImplementedError()
- @abc.abstractmethod
- def add_secure_port(self, address, server_credentials):
- """Reserves a port for secure RPC service after this Server becomes active.
+ @abc.abstractmethod
+ def add_secure_port(self, address, server_credentials):
+ """Reserves a port for secure RPC service after this Server becomes active.
This method may only be called before calling this Server's start method is
called.
@@ -923,20 +940,20 @@ class Server(six.with_metaclass(abc.ABCMeta)):
in the passed address, but will likely be different if the port number
contained in the passed address was zero.
"""
- raise NotImplementedError()
+ raise NotImplementedError()
- @abc.abstractmethod
- def start(self):
- """Starts this Server's service of RPCs.
+ @abc.abstractmethod
+ def start(self):
+ """Starts this Server's service of RPCs.
This method may only be called while the server is not serving RPCs (i.e. it
is not idempotent).
"""
- raise NotImplementedError()
+ raise NotImplementedError()
- @abc.abstractmethod
- def stop(self, grace):
- """Stops this Server's service of RPCs.
+ @abc.abstractmethod
+ def stop(self, grace):
+ """Stops this Server's service of RPCs.
All calls to this method immediately stop service of new RPCs. When existing
RPCs are aborted is controlled by the grace period parameter passed to this
@@ -967,15 +984,16 @@ class Server(six.with_metaclass(abc.ABCMeta)):
at the time it was stopped or if all RPCs that it had underway completed
very early in the grace period).
"""
- raise NotImplementedError()
+ raise NotImplementedError()
################################# Functions ################################
-def unary_unary_rpc_method_handler(
- behavior, request_deserializer=None, response_serializer=None):
- """Creates an RpcMethodHandler for a unary-unary RPC method.
+def unary_unary_rpc_method_handler(behavior,
+ request_deserializer=None,
+ response_serializer=None):
+ """Creates an RpcMethodHandler for a unary-unary RPC method.
Args:
behavior: The implementation of an RPC method as a callable behavior taking
@@ -987,15 +1005,16 @@ def unary_unary_rpc_method_handler(
An RpcMethodHandler for a unary-unary RPC method constructed from the given
parameters.
"""
- from grpc import _utilities
- return _utilities.RpcMethodHandler(
- False, False, request_deserializer, response_serializer, behavior, None,
- None, None)
+ from grpc import _utilities
+ return _utilities.RpcMethodHandler(False, False, request_deserializer,
+ response_serializer, behavior, None,
+ None, None)
-def unary_stream_rpc_method_handler(
- behavior, request_deserializer=None, response_serializer=None):
- """Creates an RpcMethodHandler for a unary-stream RPC method.
+def unary_stream_rpc_method_handler(behavior,
+ request_deserializer=None,
+ response_serializer=None):
+ """Creates an RpcMethodHandler for a unary-stream RPC method.
Args:
behavior: The implementation of an RPC method as a callable behavior taking
@@ -1007,15 +1026,16 @@ def unary_stream_rpc_method_handler(
An RpcMethodHandler for a unary-stream RPC method constructed from the
given parameters.
"""
- from grpc import _utilities
- return _utilities.RpcMethodHandler(
- False, True, request_deserializer, response_serializer, None, behavior,
- None, None)
+ from grpc import _utilities
+ return _utilities.RpcMethodHandler(False, True, request_deserializer,
+ response_serializer, None, behavior,
+ None, None)
-def stream_unary_rpc_method_handler(
- behavior, request_deserializer=None, response_serializer=None):
- """Creates an RpcMethodHandler for a stream-unary RPC method.
+def stream_unary_rpc_method_handler(behavior,
+ request_deserializer=None,
+ response_serializer=None):
+ """Creates an RpcMethodHandler for a stream-unary RPC method.
Args:
behavior: The implementation of an RPC method as a callable behavior taking
@@ -1027,15 +1047,16 @@ def stream_unary_rpc_method_handler(
An RpcMethodHandler for a stream-unary RPC method constructed from the
given parameters.
"""
- from grpc import _utilities
- return _utilities.RpcMethodHandler(
- True, False, request_deserializer, response_serializer, None, None,
- behavior, None)
+ from grpc import _utilities
+ return _utilities.RpcMethodHandler(True, False, request_deserializer,
+ response_serializer, None, None,
+ behavior, None)
-def stream_stream_rpc_method_handler(
- behavior, request_deserializer=None, response_serializer=None):
- """Creates an RpcMethodHandler for a stream-stream RPC method.
+def stream_stream_rpc_method_handler(behavior,
+ request_deserializer=None,
+ response_serializer=None):
+ """Creates an RpcMethodHandler for a stream-stream RPC method.
Args:
behavior: The implementation of an RPC method as a callable behavior taking
@@ -1048,14 +1069,14 @@ def stream_stream_rpc_method_handler(
An RpcMethodHandler for a stream-stream RPC method constructed from the
given parameters.
"""
- from grpc import _utilities
- return _utilities.RpcMethodHandler(
- True, True, request_deserializer, response_serializer, None, None, None,
- behavior)
+ from grpc import _utilities
+ return _utilities.RpcMethodHandler(True, True, request_deserializer,
+ response_serializer, None, None, None,
+ behavior)
def method_handlers_generic_handler(service, method_handlers):
- """Creates a grpc.GenericRpcHandler from RpcMethodHandlers.
+ """Creates a grpc.GenericRpcHandler from RpcMethodHandlers.
Args:
service: A service name to be used for the given method handlers.
@@ -1065,13 +1086,14 @@ def method_handlers_generic_handler(service, method_handlers):
Returns:
A GenericRpcHandler constructed from the given parameters.
"""
- from grpc import _utilities
- return _utilities.DictionaryGenericHandler(service, method_handlers)
+ from grpc import _utilities
+ return _utilities.DictionaryGenericHandler(service, method_handlers)
-def ssl_channel_credentials(
- root_certificates=None, private_key=None, certificate_chain=None):
- """Creates a ChannelCredentials for use with an SSL-enabled Channel.
+def ssl_channel_credentials(root_certificates=None,
+ private_key=None,
+ certificate_chain=None):
+ """Creates a ChannelCredentials for use with an SSL-enabled Channel.
Args:
root_certificates: The PEM-encoded root certificates or unset to ask for
@@ -1084,16 +1106,16 @@ def ssl_channel_credentials(
Returns:
A ChannelCredentials for use with an SSL-enabled Channel.
"""
- if private_key is not None or certificate_chain is not None:
- pair = _cygrpc.SslPemKeyCertPair(private_key, certificate_chain)
- else:
- pair = None
- return ChannelCredentials(
- _cygrpc.channel_credentials_ssl(root_certificates, pair))
+ if private_key is not None or certificate_chain is not None:
+ pair = _cygrpc.SslPemKeyCertPair(private_key, certificate_chain)
+ else:
+ pair = None
+ return ChannelCredentials(
+ _cygrpc.channel_credentials_ssl(root_certificates, pair))
def metadata_call_credentials(metadata_plugin, name=None):
- """Construct CallCredentials from an AuthMetadataPlugin.
+ """Construct CallCredentials from an AuthMetadataPlugin.
Args:
metadata_plugin: An AuthMetadataPlugin to use as the authentication behavior
@@ -1103,21 +1125,21 @@ def metadata_call_credentials(metadata_plugin, name=None):
Returns:
A CallCredentials.
"""
- from grpc import _plugin_wrapping
- if name is None:
- try:
- effective_name = metadata_plugin.__name__
- except AttributeError:
- effective_name = metadata_plugin.__class__.__name__
- else:
- effective_name = name
- return CallCredentials(
- _plugin_wrapping.call_credentials_metadata_plugin(
- metadata_plugin, effective_name))
+ from grpc import _plugin_wrapping
+ if name is None:
+ try:
+ effective_name = metadata_plugin.__name__
+ except AttributeError:
+ effective_name = metadata_plugin.__class__.__name__
+ else:
+ effective_name = name
+ return CallCredentials(
+ _plugin_wrapping.call_credentials_metadata_plugin(metadata_plugin,
+ effective_name))
def access_token_call_credentials(access_token):
- """Construct CallCredentials from an access token.
+ """Construct CallCredentials from an access token.
Args:
access_token: A string to place directly in the http request
@@ -1126,13 +1148,13 @@ def access_token_call_credentials(access_token):
Returns:
A CallCredentials.
"""
- from grpc import _auth
- return metadata_call_credentials(
- _auth.AccessTokenCallCredentials(access_token))
+ from grpc import _auth
+ return metadata_call_credentials(
+ _auth.AccessTokenCallCredentials(access_token))
def composite_call_credentials(*call_credentials):
- """Compose multiple CallCredentials to make a new CallCredentials.
+ """Compose multiple CallCredentials to make a new CallCredentials.
Args:
*call_credentials: At least two CallCredentials objects.
@@ -1140,16 +1162,16 @@ def composite_call_credentials(*call_credentials):
Returns:
A CallCredentials object composed of the given CallCredentials objects.
"""
- from grpc import _credential_composition
- cygrpc_call_credentials = tuple(
- single_call_credentials._credentials
- for single_call_credentials in call_credentials)
- return CallCredentials(
- _credential_composition.call(cygrpc_call_credentials))
+ from grpc import _credential_composition
+ cygrpc_call_credentials = tuple(
+ single_call_credentials._credentials
+ for single_call_credentials in call_credentials)
+ return CallCredentials(
+ _credential_composition.call(cygrpc_call_credentials))
def composite_channel_credentials(channel_credentials, *call_credentials):
- """Compose a ChannelCredentials and one or more CallCredentials objects.
+ """Compose a ChannelCredentials and one or more CallCredentials objects.
Args:
channel_credentials: A ChannelCredentials.
@@ -1159,19 +1181,19 @@ def composite_channel_credentials(channel_credentials, *call_credentials):
A ChannelCredentials composed of the given ChannelCredentials and
CallCredentials objects.
"""
- from grpc import _credential_composition
- cygrpc_call_credentials = tuple(
- single_call_credentials._credentials
- for single_call_credentials in call_credentials)
- return ChannelCredentials(
- _credential_composition.channel(
- channel_credentials._credentials, cygrpc_call_credentials))
+ from grpc import _credential_composition
+ cygrpc_call_credentials = tuple(
+ single_call_credentials._credentials
+ for single_call_credentials in call_credentials)
+ return ChannelCredentials(
+ _credential_composition.channel(channel_credentials._credentials,
+ cygrpc_call_credentials))
-def ssl_server_credentials(
- private_key_certificate_chain_pairs, root_certificates=None,
- require_client_auth=False):
- """Creates a ServerCredentials for use with an SSL-enabled Server.
+def ssl_server_credentials(private_key_certificate_chain_pairs,
+ root_certificates=None,
+ require_client_auth=False):
+ """Creates a ServerCredentials for use with an SSL-enabled Server.
Args:
private_key_certificate_chain_pairs: A nonempty sequence each element of
@@ -1187,23 +1209,23 @@ def ssl_server_credentials(
Returns:
A ServerCredentials for use with an SSL-enabled Server.
"""
- if len(private_key_certificate_chain_pairs) == 0:
- raise ValueError(
- 'At least one private key-certificate chain pair is required!')
- elif require_client_auth and root_certificates is None:
- raise ValueError(
- 'Illegal to require client auth without providing root certificates!')
- else:
- return ServerCredentials(
- _cygrpc.server_credentials_ssl(
- root_certificates,
- [_cygrpc.SslPemKeyCertPair(key, pem)
- for key, pem in private_key_certificate_chain_pairs],
- require_client_auth))
+ if len(private_key_certificate_chain_pairs) == 0:
+ raise ValueError(
+ 'At least one private key-certificate chain pair is required!')
+ elif require_client_auth and root_certificates is None:
+ raise ValueError(
+ 'Illegal to require client auth without providing root certificates!'
+ )
+ else:
+ return ServerCredentials(
+ _cygrpc.server_credentials_ssl(root_certificates, [
+ _cygrpc.SslPemKeyCertPair(key, pem)
+ for key, pem in private_key_certificate_chain_pairs
+ ], require_client_auth))
def channel_ready_future(channel):
- """Creates a Future tracking when a Channel is ready.
+ """Creates a Future tracking when a Channel is ready.
Cancelling the returned Future does not tell the given Channel to abandon
attempts it may have been making to connect; cancelling merely deactivates the
@@ -1216,12 +1238,12 @@ def channel_ready_future(channel):
A Future that matures when the given Channel has connectivity
ChannelConnectivity.READY.
"""
- from grpc import _utilities
- return _utilities.channel_ready_future(channel)
+ from grpc import _utilities
+ return _utilities.channel_ready_future(channel)
def insecure_channel(target, options=None):
- """Creates an insecure Channel to a server.
+ """Creates an insecure Channel to a server.
Args:
target: The target to which to connect.
@@ -1231,12 +1253,12 @@ def insecure_channel(target, options=None):
Returns:
A Channel to the target through which RPCs may be conducted.
"""
- from grpc import _channel
- return _channel.Channel(target, () if options is None else options, None)
+ from grpc import _channel
+ return _channel.Channel(target, () if options is None else options, None)
def secure_channel(target, credentials, options=None):
- """Creates a secure Channel to a server.
+ """Creates a secure Channel to a server.
Args:
target: The target to which to connect.
@@ -1247,13 +1269,13 @@ def secure_channel(target, credentials, options=None):
Returns:
A Channel to the target through which RPCs may be conducted.
"""
- from grpc import _channel
- return _channel.Channel(target, () if options is None else options,
- credentials._credentials)
+ from grpc import _channel
+ return _channel.Channel(target, () if options is None else options,
+ credentials._credentials)
def server(thread_pool, handlers=None, options=None):
- """Creates a Server with which RPCs can be serviced.
+ """Creates a Server with which RPCs can be serviced.
Args:
thread_pool: A futures.ThreadPoolExecutor to be used by the returned Server
@@ -1269,14 +1291,13 @@ def server(thread_pool, handlers=None, options=None):
Returns:
A Server with which RPCs can be serviced.
"""
- from grpc import _server
- return _server.Server(thread_pool, () if handlers is None else handlers,
- () if options is None else options)
+ from grpc import _server
+ return _server.Server(thread_pool, () if handlers is None else handlers, ()
+ if options is None else options)
################################### __all__ #################################
-
__all__ = (
'FutureTimeoutError',
'FutureCancelledError',
@@ -1317,26 +1338,23 @@ __all__ = (
'channel_ready_future',
'insecure_channel',
'secure_channel',
- 'server',
-)
-
+ 'server',)
############################### Extension Shims ################################
-
# Here to maintain backwards compatibility; avoid using these in new code!
try:
- import grpc_tools
- sys.modules.update({'grpc.tools': grpc_tools})
+ import grpc_tools
+ sys.modules.update({'grpc.tools': grpc_tools})
except ImportError:
- pass
+ pass
try:
- import grpc_health
- sys.modules.update({'grpc.health': grpc_health})
+ import grpc_health
+ sys.modules.update({'grpc.health': grpc_health})
except ImportError:
- pass
+ pass
try:
- import grpc_reflection
- sys.modules.update({'grpc.reflection': grpc_reflection})
+ import grpc_reflection
+ sys.modules.update({'grpc.reflection': grpc_reflection})
except ImportError:
- pass
+ pass
diff --git a/src/python/grpcio/grpc/_auth.py b/src/python/grpcio/grpc/_auth.py
index dea3221c9d..e8a90cf504 100644
--- a/src/python/grpcio/grpc/_auth.py
+++ b/src/python/grpcio/grpc/_auth.py
@@ -26,7 +26,6 @@
# 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.
-
"""GRPCAuthMetadataPlugins for standard authentication."""
import inspect
@@ -36,51 +35,53 @@ import grpc
def _sign_request(callback, token, error):
- metadata = (('authorization', 'Bearer {}'.format(token)),)
- callback(metadata, error)
+ metadata = (('authorization', 'Bearer {}'.format(token)),)
+ callback(metadata, error)
class GoogleCallCredentials(grpc.AuthMetadataPlugin):
- """Metadata wrapper for GoogleCredentials from the oauth2client library."""
-
- def __init__(self, credentials):
- self._credentials = credentials
- self._pool = futures.ThreadPoolExecutor(max_workers=1)
-
- # Hack to determine if these are JWT creds and we need to pass
- # additional_claims when getting a token
- if 'additional_claims' in inspect.getargspec(
- credentials.get_access_token).args:
- self._is_jwt = True
- else:
- self._is_jwt = False
-
- def __call__(self, context, callback):
- # MetadataPlugins cannot block (see grpc.beta.interfaces.py)
- if self._is_jwt:
- future = self._pool.submit(self._credentials.get_access_token,
- additional_claims={'aud': context.service_url})
- else:
- future = self._pool.submit(self._credentials.get_access_token)
- future.add_done_callback(lambda x: self._get_token_callback(callback, x))
-
- def _get_token_callback(self, callback, future):
- try:
- access_token = future.result().access_token
- except Exception as e:
- _sign_request(callback, None, e)
- else:
- _sign_request(callback, access_token, None)
-
- def __del__(self):
- self._pool.shutdown(wait=False)
+ """Metadata wrapper for GoogleCredentials from the oauth2client library."""
+
+ def __init__(self, credentials):
+ self._credentials = credentials
+ self._pool = futures.ThreadPoolExecutor(max_workers=1)
+
+ # Hack to determine if these are JWT creds and we need to pass
+ # additional_claims when getting a token
+ if 'additional_claims' in inspect.getargspec(
+ credentials.get_access_token).args:
+ self._is_jwt = True
+ else:
+ self._is_jwt = False
+
+ def __call__(self, context, callback):
+ # MetadataPlugins cannot block (see grpc.beta.interfaces.py)
+ if self._is_jwt:
+ future = self._pool.submit(
+ self._credentials.get_access_token,
+ additional_claims={'aud': context.service_url})
+ else:
+ future = self._pool.submit(self._credentials.get_access_token)
+ future.add_done_callback(
+ lambda x: self._get_token_callback(callback, x))
+
+ def _get_token_callback(self, callback, future):
+ try:
+ access_token = future.result().access_token
+ except Exception as e:
+ _sign_request(callback, None, e)
+ else:
+ _sign_request(callback, access_token, None)
+
+ def __del__(self):
+ self._pool.shutdown(wait=False)
class AccessTokenCallCredentials(grpc.AuthMetadataPlugin):
- """Metadata wrapper for raw access token credentials."""
+ """Metadata wrapper for raw access token credentials."""
- def __init__(self, access_token):
- self._access_token = access_token
+ def __init__(self, access_token):
+ self._access_token = access_token
- def __call__(self, context, callback):
- _sign_request(callback, self._access_token, None)
+ def __call__(self, context, callback):
+ _sign_request(callback, self._access_token, None)
diff --git a/src/python/grpcio/grpc/_channel.py b/src/python/grpcio/grpc/_channel.py
index e8c6a99cb1..77412236cc 100644
--- a/src/python/grpcio/grpc/_channel.py
+++ b/src/python/grpcio/grpc/_channel.py
@@ -26,7 +26,6 @@
# 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.
-
"""Invocation-side implementation of gRPC Python."""
import sys
@@ -52,692 +51,710 @@ _UNARY_UNARY_INITIAL_DUE = (
cygrpc.OperationType.send_close_from_client,
cygrpc.OperationType.receive_initial_metadata,
cygrpc.OperationType.receive_message,
- cygrpc.OperationType.receive_status_on_client,
-)
+ cygrpc.OperationType.receive_status_on_client,)
_UNARY_STREAM_INITIAL_DUE = (
cygrpc.OperationType.send_initial_metadata,
cygrpc.OperationType.send_message,
cygrpc.OperationType.send_close_from_client,
cygrpc.OperationType.receive_initial_metadata,
- cygrpc.OperationType.receive_status_on_client,
-)
+ cygrpc.OperationType.receive_status_on_client,)
_STREAM_UNARY_INITIAL_DUE = (
cygrpc.OperationType.send_initial_metadata,
cygrpc.OperationType.receive_initial_metadata,
cygrpc.OperationType.receive_message,
- cygrpc.OperationType.receive_status_on_client,
-)
+ cygrpc.OperationType.receive_status_on_client,)
_STREAM_STREAM_INITIAL_DUE = (
cygrpc.OperationType.send_initial_metadata,
cygrpc.OperationType.receive_initial_metadata,
- cygrpc.OperationType.receive_status_on_client,
-)
+ cygrpc.OperationType.receive_status_on_client,)
_CHANNEL_SUBSCRIPTION_CALLBACK_ERROR_LOG_MESSAGE = (
'Exception calling channel subscription callback!')
def _deadline(timeout):
- if timeout is None:
- return None, _INFINITE_FUTURE
- else:
- deadline = time.time() + timeout
- return deadline, cygrpc.Timespec(deadline)
+ if timeout is None:
+ return None, _INFINITE_FUTURE
+ else:
+ deadline = time.time() + timeout
+ return deadline, cygrpc.Timespec(deadline)
def _unknown_code_details(unknown_cygrpc_code, details):
- return 'Server sent unknown code {} and details "{}"'.format(
- unknown_cygrpc_code, details)
+ return 'Server sent unknown code {} and details "{}"'.format(
+ unknown_cygrpc_code, details)
def _wait_once_until(condition, until):
- if until is None:
- condition.wait()
- else:
- remaining = until - time.time()
- if remaining < 0:
- raise grpc.FutureTimeoutError()
+ if until is None:
+ condition.wait()
else:
- condition.wait(timeout=remaining)
+ remaining = until - time.time()
+ if remaining < 0:
+ raise grpc.FutureTimeoutError()
+ else:
+ condition.wait(timeout=remaining)
+
_INTERNAL_CALL_ERROR_MESSAGE_FORMAT = (
'Internal gRPC call error %d. ' +
'Please report to https://github.com/grpc/grpc/issues')
+
def _check_call_error(call_error, metadata):
- if call_error == cygrpc.CallError.invalid_metadata:
- raise ValueError('metadata was invalid: %s' % metadata)
- elif call_error != cygrpc.CallError.ok:
- raise ValueError(_INTERNAL_CALL_ERROR_MESSAGE_FORMAT % call_error)
+ if call_error == cygrpc.CallError.invalid_metadata:
+ raise ValueError('metadata was invalid: %s' % metadata)
+ elif call_error != cygrpc.CallError.ok:
+ raise ValueError(_INTERNAL_CALL_ERROR_MESSAGE_FORMAT % call_error)
+
def _call_error_set_RPCstate(state, call_error, metadata):
- if call_error == cygrpc.CallError.invalid_metadata:
- _abort(state, grpc.StatusCode.INTERNAL, 'metadata was invalid: %s' % metadata)
- else:
- _abort(state, grpc.StatusCode.INTERNAL,
- _INTERNAL_CALL_ERROR_MESSAGE_FORMAT % call_error)
+ if call_error == cygrpc.CallError.invalid_metadata:
+ _abort(state, grpc.StatusCode.INTERNAL,
+ 'metadata was invalid: %s' % metadata)
+ else:
+ _abort(state, grpc.StatusCode.INTERNAL,
+ _INTERNAL_CALL_ERROR_MESSAGE_FORMAT % call_error)
+
class _RPCState(object):
- def __init__(self, due, initial_metadata, trailing_metadata, code, details):
- self.condition = threading.Condition()
- # The cygrpc.OperationType objects representing events due from the RPC's
- # completion queue.
- self.due = set(due)
- self.initial_metadata = initial_metadata
- self.response = None
- self.trailing_metadata = trailing_metadata
- self.code = code
- self.details = details
- # The semantics of grpc.Future.cancel and grpc.Future.cancelled are
- # slightly wonky, so they have to be tracked separately from the rest of the
- # result of the RPC. This field tracks whether cancellation was requested
- # prior to termination of the RPC.
- self.cancelled = False
- self.callbacks = []
+ def __init__(self, due, initial_metadata, trailing_metadata, code, details):
+ self.condition = threading.Condition()
+ # The cygrpc.OperationType objects representing events due from the RPC's
+ # completion queue.
+ self.due = set(due)
+ self.initial_metadata = initial_metadata
+ self.response = None
+ self.trailing_metadata = trailing_metadata
+ self.code = code
+ self.details = details
+ # The semantics of grpc.Future.cancel and grpc.Future.cancelled are
+ # slightly wonky, so they have to be tracked separately from the rest of the
+ # result of the RPC. This field tracks whether cancellation was requested
+ # prior to termination of the RPC.
+ self.cancelled = False
+ self.callbacks = []
def _abort(state, code, details):
- if state.code is None:
- state.code = code
- state.details = details
- if state.initial_metadata is None:
- state.initial_metadata = _EMPTY_METADATA
- state.trailing_metadata = _EMPTY_METADATA
+ if state.code is None:
+ state.code = code
+ state.details = details
+ if state.initial_metadata is None:
+ state.initial_metadata = _EMPTY_METADATA
+ state.trailing_metadata = _EMPTY_METADATA
def _handle_event(event, state, response_deserializer):
- callbacks = []
- for batch_operation in event.batch_operations:
- operation_type = batch_operation.type
- state.due.remove(operation_type)
- if operation_type == cygrpc.OperationType.receive_initial_metadata:
- state.initial_metadata = batch_operation.received_metadata
- elif operation_type == cygrpc.OperationType.receive_message:
- serialized_response = batch_operation.received_message.bytes()
- if serialized_response is not None:
- response = _common.deserialize(
- serialized_response, response_deserializer)
- if response is None:
- details = 'Exception deserializing response!'
- _abort(state, grpc.StatusCode.INTERNAL, details)
- else:
- state.response = response
- elif operation_type == cygrpc.OperationType.receive_status_on_client:
- state.trailing_metadata = batch_operation.received_metadata
- if state.code is None:
- code = _common.CYGRPC_STATUS_CODE_TO_STATUS_CODE.get(
- batch_operation.received_status_code)
- if code is None:
- state.code = grpc.StatusCode.UNKNOWN
- state.details = _unknown_code_details(
- batch_operation.received_status_code,
- batch_operation.received_status_details)
- else:
- state.code = code
- state.details = batch_operation.received_status_details
- callbacks.extend(state.callbacks)
- state.callbacks = None
- return callbacks
+ callbacks = []
+ for batch_operation in event.batch_operations:
+ operation_type = batch_operation.type
+ state.due.remove(operation_type)
+ if operation_type == cygrpc.OperationType.receive_initial_metadata:
+ state.initial_metadata = batch_operation.received_metadata
+ elif operation_type == cygrpc.OperationType.receive_message:
+ serialized_response = batch_operation.received_message.bytes()
+ if serialized_response is not None:
+ response = _common.deserialize(serialized_response,
+ response_deserializer)
+ if response is None:
+ details = 'Exception deserializing response!'
+ _abort(state, grpc.StatusCode.INTERNAL, details)
+ else:
+ state.response = response
+ elif operation_type == cygrpc.OperationType.receive_status_on_client:
+ state.trailing_metadata = batch_operation.received_metadata
+ if state.code is None:
+ code = _common.CYGRPC_STATUS_CODE_TO_STATUS_CODE.get(
+ batch_operation.received_status_code)
+ if code is None:
+ state.code = grpc.StatusCode.UNKNOWN
+ state.details = _unknown_code_details(
+ batch_operation.received_status_code,
+ batch_operation.received_status_details)
+ else:
+ state.code = code
+ state.details = batch_operation.received_status_details
+ callbacks.extend(state.callbacks)
+ state.callbacks = None
+ return callbacks
def _event_handler(state, call, response_deserializer):
- def handle_event(event):
- with state.condition:
- callbacks = _handle_event(event, state, response_deserializer)
- state.condition.notify_all()
- done = not state.due
- for callback in callbacks:
- callback()
- return call if done else None
- return handle_event
-
-
-def _consume_request_iterator(
- request_iterator, state, call, request_serializer):
- event_handler = _event_handler(state, call, None)
-
- def consume_request_iterator():
- while True:
- try:
- request = next(request_iterator)
- except StopIteration:
- break
- except Exception as e:
- logging.exception("Exception iterating requests!")
- call.cancel()
- _abort(state, grpc.StatusCode.UNKNOWN, "Exception iterating requests!")
- return
- serialized_request = _common.serialize(request, request_serializer)
- with state.condition:
- if state.code is None and not state.cancelled:
- if serialized_request is None:
- call.cancel()
- details = 'Exception serializing request!'
- _abort(state, grpc.StatusCode.INTERNAL, details)
- return
- else:
- operations = (
- cygrpc.operation_send_message(
- serialized_request, _EMPTY_FLAGS),
- )
- call.start_client_batch(cygrpc.Operations(operations),
- event_handler)
- state.due.add(cygrpc.OperationType.send_message)
- while True:
- state.condition.wait()
- if state.code is None:
- if cygrpc.OperationType.send_message not in state.due:
- break
- else:
+
+ def handle_event(event):
+ with state.condition:
+ callbacks = _handle_event(event, state, response_deserializer)
+ state.condition.notify_all()
+ done = not state.due
+ for callback in callbacks:
+ callback()
+ return call if done else None
+
+ return handle_event
+
+
+def _consume_request_iterator(request_iterator, state, call,
+ request_serializer):
+ event_handler = _event_handler(state, call, None)
+
+ def consume_request_iterator():
+ while True:
+ try:
+ request = next(request_iterator)
+ except StopIteration:
+ break
+ except Exception as e:
+ logging.exception("Exception iterating requests!")
+ call.cancel()
+ _abort(state, grpc.StatusCode.UNKNOWN,
+ "Exception iterating requests!")
return
- else:
- return
- with state.condition:
- if state.code is None:
- operations = (
- cygrpc.operation_send_close_from_client(_EMPTY_FLAGS),
- )
- call.start_client_batch(cygrpc.Operations(operations), event_handler)
- state.due.add(cygrpc.OperationType.send_close_from_client)
-
- def stop_consumption_thread(timeout):
- with state.condition:
- if state.code is None:
- call.cancel()
- state.cancelled = True
- _abort(state, grpc.StatusCode.CANCELLED, 'Cancelled!')
- state.condition.notify_all()
-
- consumption_thread = _common.CleanupThread(
- stop_consumption_thread, target=consume_request_iterator)
- consumption_thread.start()
+ serialized_request = _common.serialize(request, request_serializer)
+ with state.condition:
+ if state.code is None and not state.cancelled:
+ if serialized_request is None:
+ call.cancel()
+ details = 'Exception serializing request!'
+ _abort(state, grpc.StatusCode.INTERNAL, details)
+ return
+ else:
+ operations = (cygrpc.operation_send_message(
+ serialized_request, _EMPTY_FLAGS),)
+ call.start_client_batch(
+ cygrpc.Operations(operations), event_handler)
+ state.due.add(cygrpc.OperationType.send_message)
+ while True:
+ state.condition.wait()
+ if state.code is None:
+ if cygrpc.OperationType.send_message not in state.due:
+ break
+ else:
+ return
+ else:
+ return
+ with state.condition:
+ if state.code is None:
+ operations = (
+ cygrpc.operation_send_close_from_client(_EMPTY_FLAGS),)
+ call.start_client_batch(
+ cygrpc.Operations(operations), event_handler)
+ state.due.add(cygrpc.OperationType.send_close_from_client)
+
+ def stop_consumption_thread(timeout):
+ with state.condition:
+ if state.code is None:
+ call.cancel()
+ state.cancelled = True
+ _abort(state, grpc.StatusCode.CANCELLED, 'Cancelled!')
+ state.condition.notify_all()
+
+ consumption_thread = _common.CleanupThread(
+ stop_consumption_thread, target=consume_request_iterator)
+ consumption_thread.start()
class _Rendezvous(grpc.RpcError, grpc.Future, grpc.Call):
- def __init__(self, state, call, response_deserializer, deadline):
- super(_Rendezvous, self).__init__()
- self._state = state
- self._call = call
- self._response_deserializer = response_deserializer
- self._deadline = deadline
-
- def cancel(self):
- with self._state.condition:
- if self._state.code is None:
- self._call.cancel()
- self._state.cancelled = True
- _abort(self._state, grpc.StatusCode.CANCELLED, 'Cancelled!')
- self._state.condition.notify_all()
- return False
-
- def cancelled(self):
- with self._state.condition:
- return self._state.cancelled
-
- def running(self):
- with self._state.condition:
- return self._state.code is None
-
- def done(self):
- with self._state.condition:
- return self._state.code is not None
-
- def result(self, timeout=None):
- until = None if timeout is None else time.time() + timeout
- with self._state.condition:
- while True:
- if self._state.code is None:
- _wait_once_until(self._state.condition, until)
- elif self._state.code is grpc.StatusCode.OK:
- return self._state.response
- elif self._state.cancelled:
- raise grpc.FutureCancelledError()
- else:
- raise self
-
- def exception(self, timeout=None):
- until = None if timeout is None else time.time() + timeout
- with self._state.condition:
- while True:
- if self._state.code is None:
- _wait_once_until(self._state.condition, until)
- elif self._state.code is grpc.StatusCode.OK:
- return None
- elif self._state.cancelled:
- raise grpc.FutureCancelledError()
- else:
- return self
-
- def traceback(self, timeout=None):
- until = None if timeout is None else time.time() + timeout
- with self._state.condition:
- while True:
- if self._state.code is None:
- _wait_once_until(self._state.condition, until)
- elif self._state.code is grpc.StatusCode.OK:
- return None
- elif self._state.cancelled:
- raise grpc.FutureCancelledError()
+ def __init__(self, state, call, response_deserializer, deadline):
+ super(_Rendezvous, self).__init__()
+ self._state = state
+ self._call = call
+ self._response_deserializer = response_deserializer
+ self._deadline = deadline
+
+ def cancel(self):
+ with self._state.condition:
+ if self._state.code is None:
+ self._call.cancel()
+ self._state.cancelled = True
+ _abort(self._state, grpc.StatusCode.CANCELLED, 'Cancelled!')
+ self._state.condition.notify_all()
+ return False
+
+ def cancelled(self):
+ with self._state.condition:
+ return self._state.cancelled
+
+ def running(self):
+ with self._state.condition:
+ return self._state.code is None
+
+ def done(self):
+ with self._state.condition:
+ return self._state.code is not None
+
+ def result(self, timeout=None):
+ until = None if timeout is None else time.time() + timeout
+ with self._state.condition:
+ while True:
+ if self._state.code is None:
+ _wait_once_until(self._state.condition, until)
+ elif self._state.code is grpc.StatusCode.OK:
+ return self._state.response
+ elif self._state.cancelled:
+ raise grpc.FutureCancelledError()
+ else:
+ raise self
+
+ def exception(self, timeout=None):
+ until = None if timeout is None else time.time() + timeout
+ with self._state.condition:
+ while True:
+ if self._state.code is None:
+ _wait_once_until(self._state.condition, until)
+ elif self._state.code is grpc.StatusCode.OK:
+ return None
+ elif self._state.cancelled:
+ raise grpc.FutureCancelledError()
+ else:
+ return self
+
+ def traceback(self, timeout=None):
+ until = None if timeout is None else time.time() + timeout
+ with self._state.condition:
+ while True:
+ if self._state.code is None:
+ _wait_once_until(self._state.condition, until)
+ elif self._state.code is grpc.StatusCode.OK:
+ return None
+ elif self._state.cancelled:
+ raise grpc.FutureCancelledError()
+ else:
+ try:
+ raise self
+ except grpc.RpcError:
+ return sys.exc_info()[2]
+
+ def add_done_callback(self, fn):
+ with self._state.condition:
+ if self._state.code is None:
+ self._state.callbacks.append(lambda: fn(self))
+ return
+
+ fn(self)
+
+ def _next(self):
+ with self._state.condition:
+ if self._state.code is None:
+ event_handler = _event_handler(self._state, self._call,
+ self._response_deserializer)
+ self._call.start_client_batch(
+ cygrpc.Operations(
+ (cygrpc.operation_receive_message(_EMPTY_FLAGS),)),
+ event_handler)
+ self._state.due.add(cygrpc.OperationType.receive_message)
+ elif self._state.code is grpc.StatusCode.OK:
+ raise StopIteration()
+ else:
+ raise self
+ while True:
+ self._state.condition.wait()
+ if self._state.response is not None:
+ response = self._state.response
+ self._state.response = None
+ return response
+ elif cygrpc.OperationType.receive_message not in self._state.due:
+ if self._state.code is grpc.StatusCode.OK:
+ raise StopIteration()
+ elif self._state.code is not None:
+ raise self
+
+ def __iter__(self):
+ return self
+
+ def __next__(self):
+ return self._next()
+
+ def next(self):
+ return self._next()
+
+ def is_active(self):
+ with self._state.condition:
+ return self._state.code is None
+
+ def time_remaining(self):
+ if self._deadline is None:
+ return None
else:
- try:
- raise self
- except grpc.RpcError:
- return sys.exc_info()[2]
-
- def add_done_callback(self, fn):
- with self._state.condition:
- if self._state.code is None:
- self._state.callbacks.append(lambda: fn(self))
- return
-
- fn(self)
-
- def _next(self):
- with self._state.condition:
- if self._state.code is None:
- event_handler = _event_handler(
- self._state, self._call, self._response_deserializer)
- self._call.start_client_batch(
- cygrpc.Operations(
- (cygrpc.operation_receive_message(_EMPTY_FLAGS),)),
- event_handler)
- self._state.due.add(cygrpc.OperationType.receive_message)
- elif self._state.code is grpc.StatusCode.OK:
- raise StopIteration()
- else:
- raise self
- while True:
- self._state.condition.wait()
- if self._state.response is not None:
- response = self._state.response
- self._state.response = None
- return response
- elif cygrpc.OperationType.receive_message not in self._state.due:
- if self._state.code is grpc.StatusCode.OK:
- raise StopIteration()
- elif self._state.code is not None:
- raise self
-
- def __iter__(self):
- return self
-
- def __next__(self):
- return self._next()
-
- def next(self):
- return self._next()
-
- def is_active(self):
- with self._state.condition:
- return self._state.code is None
-
- def time_remaining(self):
- if self._deadline is None:
- return None
- else:
- return max(self._deadline - time.time(), 0)
-
- def add_callback(self, callback):
- with self._state.condition:
- if self._state.callbacks is None:
- return False
- else:
- self._state.callbacks.append(callback)
- return True
-
- def initial_metadata(self):
- with self._state.condition:
- while self._state.initial_metadata is None:
- self._state.condition.wait()
- return _common.application_metadata(self._state.initial_metadata)
-
- def trailing_metadata(self):
- with self._state.condition:
- while self._state.trailing_metadata is None:
- self._state.condition.wait()
- return _common.application_metadata(self._state.trailing_metadata)
-
- def code(self):
- with self._state.condition:
- while self._state.code is None:
- self._state.condition.wait()
- return self._state.code
-
- def details(self):
- with self._state.condition:
- while self._state.details is None:
- self._state.condition.wait()
- return _common.decode(self._state.details)
-
- def _repr(self):
- with self._state.condition:
- if self._state.code is None:
- return '<_Rendezvous object of in-flight RPC>'
- else:
- return '<_Rendezvous of RPC that terminated with ({}, {})>'.format(
- self._state.code, _common.decode(self._state.details))
-
- def __repr__(self):
- return self._repr()
-
- def __str__(self):
- return self._repr()
-
- def __del__(self):
- with self._state.condition:
- if self._state.code is None:
- self._call.cancel()
- self._state.cancelled = True
- self._state.code = grpc.StatusCode.CANCELLED
- self._state.condition.notify_all()
+ return max(self._deadline - time.time(), 0)
+
+ def add_callback(self, callback):
+ with self._state.condition:
+ if self._state.callbacks is None:
+ return False
+ else:
+ self._state.callbacks.append(callback)
+ return True
+
+ def initial_metadata(self):
+ with self._state.condition:
+ while self._state.initial_metadata is None:
+ self._state.condition.wait()
+ return _common.application_metadata(self._state.initial_metadata)
+
+ def trailing_metadata(self):
+ with self._state.condition:
+ while self._state.trailing_metadata is None:
+ self._state.condition.wait()
+ return _common.application_metadata(self._state.trailing_metadata)
+
+ def code(self):
+ with self._state.condition:
+ while self._state.code is None:
+ self._state.condition.wait()
+ return self._state.code
+
+ def details(self):
+ with self._state.condition:
+ while self._state.details is None:
+ self._state.condition.wait()
+ return _common.decode(self._state.details)
+
+ def _repr(self):
+ with self._state.condition:
+ if self._state.code is None:
+ return '<_Rendezvous object of in-flight RPC>'
+ else:
+ return '<_Rendezvous of RPC that terminated with ({}, {})>'.format(
+ self._state.code, _common.decode(self._state.details))
+
+ def __repr__(self):
+ return self._repr()
+
+ def __str__(self):
+ return self._repr()
+
+ def __del__(self):
+ with self._state.condition:
+ if self._state.code is None:
+ self._call.cancel()
+ self._state.cancelled = True
+ self._state.code = grpc.StatusCode.CANCELLED
+ self._state.condition.notify_all()
def _start_unary_request(request, timeout, request_serializer):
- deadline, deadline_timespec = _deadline(timeout)
- serialized_request = _common.serialize(request, request_serializer)
- if serialized_request is None:
- state = _RPCState(
- (), _EMPTY_METADATA, _EMPTY_METADATA, grpc.StatusCode.INTERNAL,
- 'Exception serializing request!')
- rendezvous = _Rendezvous(state, None, None, deadline)
- return deadline, deadline_timespec, None, rendezvous
- else:
- return deadline, deadline_timespec, serialized_request, None
+ deadline, deadline_timespec = _deadline(timeout)
+ serialized_request = _common.serialize(request, request_serializer)
+ if serialized_request is None:
+ state = _RPCState((), _EMPTY_METADATA, _EMPTY_METADATA,
+ grpc.StatusCode.INTERNAL,
+ 'Exception serializing request!')
+ rendezvous = _Rendezvous(state, None, None, deadline)
+ return deadline, deadline_timespec, None, rendezvous
+ else:
+ return deadline, deadline_timespec, serialized_request, None
def _end_unary_response_blocking(state, with_call, deadline):
- if state.code is grpc.StatusCode.OK:
- if with_call:
- rendezvous = _Rendezvous(state, None, None, deadline)
- return state.response, rendezvous
+ if state.code is grpc.StatusCode.OK:
+ if with_call:
+ rendezvous = _Rendezvous(state, None, None, deadline)
+ return state.response, rendezvous
+ else:
+ return state.response
else:
- return state.response
- else:
- raise _Rendezvous(state, None, None, deadline)
+ raise _Rendezvous(state, None, None, deadline)
class _UnaryUnaryMultiCallable(grpc.UnaryUnaryMultiCallable):
- def __init__(
- self, channel, managed_call, method, request_serializer,
- response_deserializer):
- self._channel = channel
- self._managed_call = managed_call
- self._method = method
- self._request_serializer = request_serializer
- self._response_deserializer = response_deserializer
-
- def _prepare(self, request, timeout, metadata):
- deadline, deadline_timespec, serialized_request, rendezvous = (
- _start_unary_request(request, timeout, self._request_serializer))
- if serialized_request is None:
- return None, None, None, None, rendezvous
- else:
- state = _RPCState(_UNARY_UNARY_INITIAL_DUE, None, None, None, None)
- operations = (
- cygrpc.operation_send_initial_metadata(
- _common.cygrpc_metadata(metadata), _EMPTY_FLAGS),
- cygrpc.operation_send_message(serialized_request, _EMPTY_FLAGS),
- cygrpc.operation_send_close_from_client(_EMPTY_FLAGS),
- cygrpc.operation_receive_initial_metadata(_EMPTY_FLAGS),
- cygrpc.operation_receive_message(_EMPTY_FLAGS),
- cygrpc.operation_receive_status_on_client(_EMPTY_FLAGS),
- )
- return state, operations, deadline, deadline_timespec, None
-
- def _blocking(self, request, timeout, metadata, credentials):
- state, operations, deadline, deadline_timespec, rendezvous = self._prepare(
- request, timeout, metadata)
- if rendezvous:
- raise rendezvous
- else:
- completion_queue = cygrpc.CompletionQueue()
- call = self._channel.create_call(
- None, 0, completion_queue, self._method, None, deadline_timespec)
- if credentials is not None:
- call.set_credentials(credentials._credentials)
- call_error = call.start_client_batch(cygrpc.Operations(operations), None)
- _check_call_error(call_error, metadata)
- _handle_event(completion_queue.poll(), state, self._response_deserializer)
- return state, deadline
-
- def __call__(self, request, timeout=None, metadata=None, credentials=None):
- state, deadline, = self._blocking(request, timeout, metadata, credentials)
- return _end_unary_response_blocking(state, False, deadline)
-
- def with_call(self, request, timeout=None, metadata=None, credentials=None):
- state, deadline, = self._blocking(request, timeout, metadata, credentials)
- return _end_unary_response_blocking(state, True, deadline)
-
- def future(self, request, timeout=None, metadata=None, credentials=None):
- state, operations, deadline, deadline_timespec, rendezvous = self._prepare(
- request, timeout, metadata)
- if rendezvous:
- return rendezvous
- else:
- call, drive_call = self._managed_call(
- None, 0, self._method, None, deadline_timespec)
- if credentials is not None:
- call.set_credentials(credentials._credentials)
- event_handler = _event_handler(state, call, self._response_deserializer)
- with state.condition:
- call_error = call.start_client_batch(cygrpc.Operations(operations),
- event_handler)
- if call_error != cygrpc.CallError.ok:
- _call_error_set_RPCstate(state, call_error, metadata)
- return _Rendezvous(state, None, None, deadline)
- drive_call()
- return _Rendezvous(state, call, self._response_deserializer, deadline)
+ def __init__(self, channel, managed_call, method, request_serializer,
+ response_deserializer):
+ self._channel = channel
+ self._managed_call = managed_call
+ self._method = method
+ self._request_serializer = request_serializer
+ self._response_deserializer = response_deserializer
+
+ def _prepare(self, request, timeout, metadata):
+ deadline, deadline_timespec, serialized_request, rendezvous = (
+ _start_unary_request(request, timeout, self._request_serializer))
+ if serialized_request is None:
+ return None, None, None, None, rendezvous
+ else:
+ state = _RPCState(_UNARY_UNARY_INITIAL_DUE, None, None, None, None)
+ operations = (
+ cygrpc.operation_send_initial_metadata(
+ _common.cygrpc_metadata(metadata), _EMPTY_FLAGS),
+ cygrpc.operation_send_message(serialized_request, _EMPTY_FLAGS),
+ cygrpc.operation_send_close_from_client(_EMPTY_FLAGS),
+ cygrpc.operation_receive_initial_metadata(_EMPTY_FLAGS),
+ cygrpc.operation_receive_message(_EMPTY_FLAGS),
+ cygrpc.operation_receive_status_on_client(_EMPTY_FLAGS),)
+ return state, operations, deadline, deadline_timespec, None
+
+ def _blocking(self, request, timeout, metadata, credentials):
+ state, operations, deadline, deadline_timespec, rendezvous = self._prepare(
+ request, timeout, metadata)
+ if rendezvous:
+ raise rendezvous
+ else:
+ completion_queue = cygrpc.CompletionQueue()
+ call = self._channel.create_call(None, 0, completion_queue,
+ self._method, None,
+ deadline_timespec)
+ if credentials is not None:
+ call.set_credentials(credentials._credentials)
+ call_error = call.start_client_batch(
+ cygrpc.Operations(operations), None)
+ _check_call_error(call_error, metadata)
+ _handle_event(completion_queue.poll(), state,
+ self._response_deserializer)
+ return state, deadline
+
+ def __call__(self, request, timeout=None, metadata=None, credentials=None):
+ state, deadline, = self._blocking(request, timeout, metadata,
+ credentials)
+ return _end_unary_response_blocking(state, False, deadline)
+
+ def with_call(self, request, timeout=None, metadata=None, credentials=None):
+ state, deadline, = self._blocking(request, timeout, metadata,
+ credentials)
+ return _end_unary_response_blocking(state, True, deadline)
+
+ def future(self, request, timeout=None, metadata=None, credentials=None):
+ state, operations, deadline, deadline_timespec, rendezvous = self._prepare(
+ request, timeout, metadata)
+ if rendezvous:
+ return rendezvous
+ else:
+ call, drive_call = self._managed_call(None, 0, self._method, None,
+ deadline_timespec)
+ if credentials is not None:
+ call.set_credentials(credentials._credentials)
+ event_handler = _event_handler(state, call,
+ self._response_deserializer)
+ with state.condition:
+ call_error = call.start_client_batch(
+ cygrpc.Operations(operations), event_handler)
+ if call_error != cygrpc.CallError.ok:
+ _call_error_set_RPCstate(state, call_error, metadata)
+ return _Rendezvous(state, None, None, deadline)
+ drive_call()
+ return _Rendezvous(state, call, self._response_deserializer,
+ deadline)
class _UnaryStreamMultiCallable(grpc.UnaryStreamMultiCallable):
- def __init__(
- self, channel, managed_call, method, request_serializer,
- response_deserializer):
- self._channel = channel
- self._managed_call = managed_call
- self._method = method
- self._request_serializer = request_serializer
- self._response_deserializer = response_deserializer
-
- def __call__(self, request, timeout=None, metadata=None, credentials=None):
- deadline, deadline_timespec, serialized_request, rendezvous = (
- _start_unary_request(request, timeout, self._request_serializer))
- if serialized_request is None:
- raise rendezvous
- else:
- state = _RPCState(_UNARY_STREAM_INITIAL_DUE, None, None, None, None)
- call, drive_call = self._managed_call(
- None, 0, self._method, None, deadline_timespec)
- if credentials is not None:
- call.set_credentials(credentials._credentials)
- event_handler = _event_handler(state, call, self._response_deserializer)
- with state.condition:
- call.start_client_batch(
- cygrpc.Operations(
- (cygrpc.operation_receive_initial_metadata(_EMPTY_FLAGS),)),
- event_handler)
- operations = (
- cygrpc.operation_send_initial_metadata(
- _common.cygrpc_metadata(metadata), _EMPTY_FLAGS),
- cygrpc.operation_send_message(serialized_request, _EMPTY_FLAGS),
- cygrpc.operation_send_close_from_client(_EMPTY_FLAGS),
- cygrpc.operation_receive_status_on_client(_EMPTY_FLAGS),
- )
- call_error = call.start_client_batch(cygrpc.Operations(operations),
- event_handler)
- if call_error != cygrpc.CallError.ok:
- _call_error_set_RPCstate(state, call_error, metadata)
- return _Rendezvous(state, None, None, deadline)
- drive_call()
- return _Rendezvous(state, call, self._response_deserializer, deadline)
+ def __init__(self, channel, managed_call, method, request_serializer,
+ response_deserializer):
+ self._channel = channel
+ self._managed_call = managed_call
+ self._method = method
+ self._request_serializer = request_serializer
+ self._response_deserializer = response_deserializer
+
+ def __call__(self, request, timeout=None, metadata=None, credentials=None):
+ deadline, deadline_timespec, serialized_request, rendezvous = (
+ _start_unary_request(request, timeout, self._request_serializer))
+ if serialized_request is None:
+ raise rendezvous
+ else:
+ state = _RPCState(_UNARY_STREAM_INITIAL_DUE, None, None, None, None)
+ call, drive_call = self._managed_call(None, 0, self._method, None,
+ deadline_timespec)
+ if credentials is not None:
+ call.set_credentials(credentials._credentials)
+ event_handler = _event_handler(state, call,
+ self._response_deserializer)
+ with state.condition:
+ call.start_client_batch(
+ cygrpc.Operations((
+ cygrpc.operation_receive_initial_metadata(_EMPTY_FLAGS),
+ )), event_handler)
+ operations = (
+ cygrpc.operation_send_initial_metadata(
+ _common.cygrpc_metadata(metadata), _EMPTY_FLAGS),
+ cygrpc.operation_send_message(serialized_request,
+ _EMPTY_FLAGS),
+ cygrpc.operation_send_close_from_client(_EMPTY_FLAGS),
+ cygrpc.operation_receive_status_on_client(_EMPTY_FLAGS),)
+ call_error = call.start_client_batch(
+ cygrpc.Operations(operations), event_handler)
+ if call_error != cygrpc.CallError.ok:
+ _call_error_set_RPCstate(state, call_error, metadata)
+ return _Rendezvous(state, None, None, deadline)
+ drive_call()
+ return _Rendezvous(state, call, self._response_deserializer,
+ deadline)
class _StreamUnaryMultiCallable(grpc.StreamUnaryMultiCallable):
- def __init__(
- self, channel, managed_call, method, request_serializer,
- response_deserializer):
- self._channel = channel
- self._managed_call = managed_call
- self._method = method
- self._request_serializer = request_serializer
- self._response_deserializer = response_deserializer
-
- def _blocking(self, request_iterator, timeout, metadata, credentials):
- deadline, deadline_timespec = _deadline(timeout)
- state = _RPCState(_STREAM_UNARY_INITIAL_DUE, None, None, None, None)
- completion_queue = cygrpc.CompletionQueue()
- call = self._channel.create_call(
- None, 0, completion_queue, self._method, None, deadline_timespec)
- if credentials is not None:
- call.set_credentials(credentials._credentials)
- with state.condition:
- call.start_client_batch(
- cygrpc.Operations(
- (cygrpc.operation_receive_initial_metadata(_EMPTY_FLAGS),)),
- None)
- operations = (
- cygrpc.operation_send_initial_metadata(
- _common.cygrpc_metadata(metadata), _EMPTY_FLAGS),
- cygrpc.operation_receive_message(_EMPTY_FLAGS),
- cygrpc.operation_receive_status_on_client(_EMPTY_FLAGS),
- )
- call_error = call.start_client_batch(cygrpc.Operations(operations), None)
- _check_call_error(call_error, metadata)
- _consume_request_iterator(
- request_iterator, state, call, self._request_serializer)
- while True:
- event = completion_queue.poll()
- with state.condition:
- _handle_event(event, state, self._response_deserializer)
- state.condition.notify_all()
- if not state.due:
- break
- return state, deadline
-
- def __call__(
- self, request_iterator, timeout=None, metadata=None, credentials=None):
- state, deadline, = self._blocking(
- request_iterator, timeout, metadata, credentials)
- return _end_unary_response_blocking(state, False, deadline)
-
- def with_call(
- self, request_iterator, timeout=None, metadata=None, credentials=None):
- state, deadline, = self._blocking(
- request_iterator, timeout, metadata, credentials)
- return _end_unary_response_blocking(state, True, deadline)
-
- def future(
- self, request_iterator, timeout=None, metadata=None, credentials=None):
- deadline, deadline_timespec = _deadline(timeout)
- state = _RPCState(_STREAM_UNARY_INITIAL_DUE, None, None, None, None)
- call, drive_call = self._managed_call(
- None, 0, self._method, None, deadline_timespec)
- if credentials is not None:
- call.set_credentials(credentials._credentials)
- event_handler = _event_handler(state, call, self._response_deserializer)
- with state.condition:
- call.start_client_batch(
- cygrpc.Operations(
- (cygrpc.operation_receive_initial_metadata(_EMPTY_FLAGS),)),
- event_handler)
- operations = (
- cygrpc.operation_send_initial_metadata(
- _common.cygrpc_metadata(metadata), _EMPTY_FLAGS),
- cygrpc.operation_receive_message(_EMPTY_FLAGS),
- cygrpc.operation_receive_status_on_client(_EMPTY_FLAGS),
- )
- call_error = call.start_client_batch(cygrpc.Operations(operations),
- event_handler)
- if call_error != cygrpc.CallError.ok:
- _call_error_set_RPCstate(state, call_error, metadata)
- return _Rendezvous(state, None, None, deadline)
- drive_call()
- _consume_request_iterator(
- request_iterator, state, call, self._request_serializer)
- return _Rendezvous(state, call, self._response_deserializer, deadline)
+ def __init__(self, channel, managed_call, method, request_serializer,
+ response_deserializer):
+ self._channel = channel
+ self._managed_call = managed_call
+ self._method = method
+ self._request_serializer = request_serializer
+ self._response_deserializer = response_deserializer
+
+ def _blocking(self, request_iterator, timeout, metadata, credentials):
+ deadline, deadline_timespec = _deadline(timeout)
+ state = _RPCState(_STREAM_UNARY_INITIAL_DUE, None, None, None, None)
+ completion_queue = cygrpc.CompletionQueue()
+ call = self._channel.create_call(None, 0, completion_queue,
+ self._method, None, deadline_timespec)
+ if credentials is not None:
+ call.set_credentials(credentials._credentials)
+ with state.condition:
+ call.start_client_batch(
+ cygrpc.Operations(
+ (cygrpc.operation_receive_initial_metadata(_EMPTY_FLAGS),)),
+ None)
+ operations = (
+ cygrpc.operation_send_initial_metadata(
+ _common.cygrpc_metadata(metadata), _EMPTY_FLAGS),
+ cygrpc.operation_receive_message(_EMPTY_FLAGS),
+ cygrpc.operation_receive_status_on_client(_EMPTY_FLAGS),)
+ call_error = call.start_client_batch(
+ cygrpc.Operations(operations), None)
+ _check_call_error(call_error, metadata)
+ _consume_request_iterator(request_iterator, state, call,
+ self._request_serializer)
+ while True:
+ event = completion_queue.poll()
+ with state.condition:
+ _handle_event(event, state, self._response_deserializer)
+ state.condition.notify_all()
+ if not state.due:
+ break
+ return state, deadline
+
+ def __call__(self,
+ request_iterator,
+ timeout=None,
+ metadata=None,
+ credentials=None):
+ state, deadline, = self._blocking(request_iterator, timeout, metadata,
+ credentials)
+ return _end_unary_response_blocking(state, False, deadline)
+
+ def with_call(self,
+ request_iterator,
+ timeout=None,
+ metadata=None,
+ credentials=None):
+ state, deadline, = self._blocking(request_iterator, timeout, metadata,
+ credentials)
+ return _end_unary_response_blocking(state, True, deadline)
+
+ def future(self,
+ request_iterator,
+ timeout=None,
+ metadata=None,
+ credentials=None):
+ deadline, deadline_timespec = _deadline(timeout)
+ state = _RPCState(_STREAM_UNARY_INITIAL_DUE, None, None, None, None)
+ call, drive_call = self._managed_call(None, 0, self._method, None,
+ deadline_timespec)
+ if credentials is not None:
+ call.set_credentials(credentials._credentials)
+ event_handler = _event_handler(state, call, self._response_deserializer)
+ with state.condition:
+ call.start_client_batch(
+ cygrpc.Operations(
+ (cygrpc.operation_receive_initial_metadata(_EMPTY_FLAGS),)),
+ event_handler)
+ operations = (
+ cygrpc.operation_send_initial_metadata(
+ _common.cygrpc_metadata(metadata), _EMPTY_FLAGS),
+ cygrpc.operation_receive_message(_EMPTY_FLAGS),
+ cygrpc.operation_receive_status_on_client(_EMPTY_FLAGS),)
+ call_error = call.start_client_batch(
+ cygrpc.Operations(operations), event_handler)
+ if call_error != cygrpc.CallError.ok:
+ _call_error_set_RPCstate(state, call_error, metadata)
+ return _Rendezvous(state, None, None, deadline)
+ drive_call()
+ _consume_request_iterator(request_iterator, state, call,
+ self._request_serializer)
+ return _Rendezvous(state, call, self._response_deserializer, deadline)
class _StreamStreamMultiCallable(grpc.StreamStreamMultiCallable):
- def __init__(
- self, channel, managed_call, method, request_serializer,
- response_deserializer):
- self._channel = channel
- self._managed_call = managed_call
- self._method = method
- self._request_serializer = request_serializer
- self._response_deserializer = response_deserializer
-
- def __call__(
- self, request_iterator, timeout=None, metadata=None, credentials=None):
- deadline, deadline_timespec = _deadline(timeout)
- state = _RPCState(_STREAM_STREAM_INITIAL_DUE, None, None, None, None)
- call, drive_call = self._managed_call(
- None, 0, self._method, None, deadline_timespec)
- if credentials is not None:
- call.set_credentials(credentials._credentials)
- event_handler = _event_handler(state, call, self._response_deserializer)
- with state.condition:
- call.start_client_batch(
- cygrpc.Operations(
- (cygrpc.operation_receive_initial_metadata(_EMPTY_FLAGS),)),
- event_handler)
- operations = (
- cygrpc.operation_send_initial_metadata(
- _common.cygrpc_metadata(metadata), _EMPTY_FLAGS),
- cygrpc.operation_receive_status_on_client(_EMPTY_FLAGS),
- )
- call_error = call.start_client_batch(cygrpc.Operations(operations),
- event_handler)
- if call_error != cygrpc.CallError.ok:
- _call_error_set_RPCstate(state, call_error, metadata)
- return _Rendezvous(state, None, None, deadline)
- drive_call()
- _consume_request_iterator(
- request_iterator, state, call, self._request_serializer)
- return _Rendezvous(state, call, self._response_deserializer, deadline)
+ def __init__(self, channel, managed_call, method, request_serializer,
+ response_deserializer):
+ self._channel = channel
+ self._managed_call = managed_call
+ self._method = method
+ self._request_serializer = request_serializer
+ self._response_deserializer = response_deserializer
+
+ def __call__(self,
+ request_iterator,
+ timeout=None,
+ metadata=None,
+ credentials=None):
+ deadline, deadline_timespec = _deadline(timeout)
+ state = _RPCState(_STREAM_STREAM_INITIAL_DUE, None, None, None, None)
+ call, drive_call = self._managed_call(None, 0, self._method, None,
+ deadline_timespec)
+ if credentials is not None:
+ call.set_credentials(credentials._credentials)
+ event_handler = _event_handler(state, call, self._response_deserializer)
+ with state.condition:
+ call.start_client_batch(
+ cygrpc.Operations(
+ (cygrpc.operation_receive_initial_metadata(_EMPTY_FLAGS),)),
+ event_handler)
+ operations = (
+ cygrpc.operation_send_initial_metadata(
+ _common.cygrpc_metadata(metadata), _EMPTY_FLAGS),
+ cygrpc.operation_receive_status_on_client(_EMPTY_FLAGS),)
+ call_error = call.start_client_batch(
+ cygrpc.Operations(operations), event_handler)
+ if call_error != cygrpc.CallError.ok:
+ _call_error_set_RPCstate(state, call_error, metadata)
+ return _Rendezvous(state, None, None, deadline)
+ drive_call()
+ _consume_request_iterator(request_iterator, state, call,
+ self._request_serializer)
+ return _Rendezvous(state, call, self._response_deserializer, deadline)
class _ChannelCallState(object):
- def __init__(self, channel):
- self.lock = threading.Lock()
- self.channel = channel
- self.completion_queue = cygrpc.CompletionQueue()
- self.managed_calls = None
+ def __init__(self, channel):
+ self.lock = threading.Lock()
+ self.channel = channel
+ self.completion_queue = cygrpc.CompletionQueue()
+ self.managed_calls = None
def _run_channel_spin_thread(state):
- def channel_spin():
- while True:
- event = state.completion_queue.poll()
- completed_call = event.tag(event)
- if completed_call is not None:
- with state.lock:
- state.managed_calls.remove(completed_call)
- if not state.managed_calls:
- state.managed_calls = None
- return
- def stop_channel_spin(timeout):
- with state.lock:
- if state.managed_calls is not None:
- for call in state.managed_calls:
- call.cancel()
+ def channel_spin():
+ while True:
+ event = state.completion_queue.poll()
+ completed_call = event.tag(event)
+ if completed_call is not None:
+ with state.lock:
+ state.managed_calls.remove(completed_call)
+ if not state.managed_calls:
+ state.managed_calls = None
+ return
+
+ def stop_channel_spin(timeout):
+ with state.lock:
+ if state.managed_calls is not None:
+ for call in state.managed_calls:
+ call.cancel()
- channel_spin_thread = _common.CleanupThread(
- stop_channel_spin, target=channel_spin)
- channel_spin_thread.start()
+ channel_spin_thread = _common.CleanupThread(
+ stop_channel_spin, target=channel_spin)
+ channel_spin_thread.start()
def _channel_managed_call_management(state):
- def create(parent, flags, method, host, deadline):
- """Creates a managed cygrpc.Call and a function to call to drive it.
+
+ def create(parent, flags, method, host, deadline):
+ """Creates a managed cygrpc.Call and a function to call to drive it.
If operations are successfully added to the returned cygrpc.Call, the
returned function must be called. If operations are not successfully added
@@ -754,193 +771,213 @@ def _channel_managed_call_management(state):
A cygrpc.Call with which to conduct an RPC and a function to call if
operations are successfully started on the call.
"""
- call = state.channel.create_call(
- parent, flags, state.completion_queue, method, host, deadline)
-
- def drive():
- with state.lock:
- if state.managed_calls is None:
- state.managed_calls = set((call,))
- _run_channel_spin_thread(state)
- else:
- state.managed_calls.add(call)
+ call = state.channel.create_call(parent, flags, state.completion_queue,
+ method, host, deadline)
+
+ def drive():
+ with state.lock:
+ if state.managed_calls is None:
+ state.managed_calls = set((call,))
+ _run_channel_spin_thread(state)
+ else:
+ state.managed_calls.add(call)
+
+ return call, drive
- return call, drive
- return create
+ return create
class _ChannelConnectivityState(object):
- def __init__(self, channel):
- self.lock = threading.Lock()
- self.channel = channel
- self.polling = False
- self.connectivity = None
- self.try_to_connect = False
- self.callbacks_and_connectivities = []
- self.delivering = False
+ def __init__(self, channel):
+ self.lock = threading.Lock()
+ self.channel = channel
+ self.polling = False
+ self.connectivity = None
+ self.try_to_connect = False
+ self.callbacks_and_connectivities = []
+ self.delivering = False
def _deliveries(state):
- callbacks_needing_update = []
- for callback_and_connectivity in state.callbacks_and_connectivities:
- callback, callback_connectivity, = callback_and_connectivity
- if callback_connectivity is not state.connectivity:
- callbacks_needing_update.append(callback)
- callback_and_connectivity[1] = state.connectivity
- return callbacks_needing_update
+ callbacks_needing_update = []
+ for callback_and_connectivity in state.callbacks_and_connectivities:
+ callback, callback_connectivity, = callback_and_connectivity
+ if callback_connectivity is not state.connectivity:
+ callbacks_needing_update.append(callback)
+ callback_and_connectivity[1] = state.connectivity
+ return callbacks_needing_update
def _deliver(state, initial_connectivity, initial_callbacks):
- connectivity = initial_connectivity
- callbacks = initial_callbacks
- while True:
- for callback in callbacks:
- callable_util.call_logging_exceptions(
- callback, _CHANNEL_SUBSCRIPTION_CALLBACK_ERROR_LOG_MESSAGE,
- connectivity)
- with state.lock:
- callbacks = _deliveries(state)
- if callbacks:
- connectivity = state.connectivity
- else:
- state.delivering = False
- return
+ connectivity = initial_connectivity
+ callbacks = initial_callbacks
+ while True:
+ for callback in callbacks:
+ callable_util.call_logging_exceptions(
+ callback, _CHANNEL_SUBSCRIPTION_CALLBACK_ERROR_LOG_MESSAGE,
+ connectivity)
+ with state.lock:
+ callbacks = _deliveries(state)
+ if callbacks:
+ connectivity = state.connectivity
+ else:
+ state.delivering = False
+ return
def _spawn_delivery(state, callbacks):
- delivering_thread = threading.Thread(
- target=_deliver, args=(state, state.connectivity, callbacks,))
- delivering_thread.start()
- state.delivering = True
+ delivering_thread = threading.Thread(
+ target=_deliver, args=(
+ state,
+ state.connectivity,
+ callbacks,))
+ delivering_thread.start()
+ state.delivering = True
# NOTE(https://github.com/grpc/grpc/issues/3064): We'd rather not poll.
def _poll_connectivity(state, channel, initial_try_to_connect):
- try_to_connect = initial_try_to_connect
- connectivity = channel.check_connectivity_state(try_to_connect)
- with state.lock:
- state.connectivity = (
- _common.CYGRPC_CONNECTIVITY_STATE_TO_CHANNEL_CONNECTIVITY[
- connectivity])
- callbacks = tuple(
- callback for callback, unused_but_known_to_be_none_connectivity
- in state.callbacks_and_connectivities)
- for callback_and_connectivity in state.callbacks_and_connectivities:
- callback_and_connectivity[1] = state.connectivity
- if callbacks:
- _spawn_delivery(state, callbacks)
- completion_queue = cygrpc.CompletionQueue()
- while True:
- channel.watch_connectivity_state(
- connectivity, cygrpc.Timespec(time.time() + 0.2),
- completion_queue, None)
- event = completion_queue.poll()
+ try_to_connect = initial_try_to_connect
+ connectivity = channel.check_connectivity_state(try_to_connect)
with state.lock:
- if not state.callbacks_and_connectivities and not state.try_to_connect:
- state.polling = False
- state.connectivity = None
- break
- try_to_connect = state.try_to_connect
- state.try_to_connect = False
- if event.success or try_to_connect:
- connectivity = channel.check_connectivity_state(try_to_connect)
- with state.lock:
state.connectivity = (
_common.CYGRPC_CONNECTIVITY_STATE_TO_CHANNEL_CONNECTIVITY[
connectivity])
- if not state.delivering:
- callbacks = _deliveries(state)
- if callbacks:
+ callbacks = tuple(callback
+ for callback, unused_but_known_to_be_none_connectivity
+ in state.callbacks_and_connectivities)
+ for callback_and_connectivity in state.callbacks_and_connectivities:
+ callback_and_connectivity[1] = state.connectivity
+ if callbacks:
_spawn_delivery(state, callbacks)
+ completion_queue = cygrpc.CompletionQueue()
+ while True:
+ channel.watch_connectivity_state(connectivity,
+ cygrpc.Timespec(time.time() + 0.2),
+ completion_queue, None)
+ event = completion_queue.poll()
+ with state.lock:
+ if not state.callbacks_and_connectivities and not state.try_to_connect:
+ state.polling = False
+ state.connectivity = None
+ break
+ try_to_connect = state.try_to_connect
+ state.try_to_connect = False
+ if event.success or try_to_connect:
+ connectivity = channel.check_connectivity_state(try_to_connect)
+ with state.lock:
+ state.connectivity = (
+ _common.CYGRPC_CONNECTIVITY_STATE_TO_CHANNEL_CONNECTIVITY[
+ connectivity])
+ if not state.delivering:
+ callbacks = _deliveries(state)
+ if callbacks:
+ _spawn_delivery(state, callbacks)
def _moot(state):
- with state.lock:
- del state.callbacks_and_connectivities[:]
+ with state.lock:
+ del state.callbacks_and_connectivities[:]
def _subscribe(state, callback, try_to_connect):
- with state.lock:
- if not state.callbacks_and_connectivities and not state.polling:
- def cancel_all_subscriptions(timeout):
- _moot(state)
- polling_thread = _common.CleanupThread(
- cancel_all_subscriptions, target=_poll_connectivity,
- args=(state, state.channel, bool(try_to_connect)))
- polling_thread.start()
- state.polling = True
- state.callbacks_and_connectivities.append([callback, None])
- elif not state.delivering and state.connectivity is not None:
- _spawn_delivery(state, (callback,))
- state.try_to_connect |= bool(try_to_connect)
- state.callbacks_and_connectivities.append(
- [callback, state.connectivity])
- else:
- state.try_to_connect |= bool(try_to_connect)
- state.callbacks_and_connectivities.append([callback, None])
+ with state.lock:
+ if not state.callbacks_and_connectivities and not state.polling:
+
+ def cancel_all_subscriptions(timeout):
+ _moot(state)
+
+ polling_thread = _common.CleanupThread(
+ cancel_all_subscriptions,
+ target=_poll_connectivity,
+ args=(state, state.channel, bool(try_to_connect)))
+ polling_thread.start()
+ state.polling = True
+ state.callbacks_and_connectivities.append([callback, None])
+ elif not state.delivering and state.connectivity is not None:
+ _spawn_delivery(state, (callback,))
+ state.try_to_connect |= bool(try_to_connect)
+ state.callbacks_and_connectivities.append(
+ [callback, state.connectivity])
+ else:
+ state.try_to_connect |= bool(try_to_connect)
+ state.callbacks_and_connectivities.append([callback, None])
def _unsubscribe(state, callback):
- with state.lock:
- for index, (subscribed_callback, unused_connectivity) in enumerate(
- state.callbacks_and_connectivities):
- if callback == subscribed_callback:
- state.callbacks_and_connectivities.pop(index)
- break
+ with state.lock:
+ for index, (subscribed_callback, unused_connectivity
+ ) in enumerate(state.callbacks_and_connectivities):
+ if callback == subscribed_callback:
+ state.callbacks_and_connectivities.pop(index)
+ break
def _options(options):
- return list(options) + [
- (cygrpc.ChannelArgKey.primary_user_agent_string, _USER_AGENT)]
+ return list(options) + [
+ (cygrpc.ChannelArgKey.primary_user_agent_string, _USER_AGENT)
+ ]
class Channel(grpc.Channel):
- """A cygrpc.Channel-backed implementation of grpc.Channel."""
+ """A cygrpc.Channel-backed implementation of grpc.Channel."""
- def __init__(self, target, options, credentials):
- """Constructor.
+ def __init__(self, target, options, credentials):
+ """Constructor.
Args:
target: The target to which to connect.
options: Configuration options for the channel.
credentials: A cygrpc.ChannelCredentials or None.
"""
- self._channel = cygrpc.Channel(
- _common.encode(target), _common.channel_args(_options(options)),
- credentials)
- self._call_state = _ChannelCallState(self._channel)
- self._connectivity_state = _ChannelConnectivityState(self._channel)
-
- def subscribe(self, callback, try_to_connect=None):
- _subscribe(self._connectivity_state, callback, try_to_connect)
-
- def unsubscribe(self, callback):
- _unsubscribe(self._connectivity_state, callback)
-
- def unary_unary(
- self, method, request_serializer=None, response_deserializer=None):
- return _UnaryUnaryMultiCallable(
- self._channel, _channel_managed_call_management(self._call_state),
- _common.encode(method), request_serializer, response_deserializer)
-
- def unary_stream(
- self, method, request_serializer=None, response_deserializer=None):
- return _UnaryStreamMultiCallable(
- self._channel, _channel_managed_call_management(self._call_state),
- _common.encode(method), request_serializer, response_deserializer)
-
- def stream_unary(
- self, method, request_serializer=None, response_deserializer=None):
- return _StreamUnaryMultiCallable(
- self._channel, _channel_managed_call_management(self._call_state),
- _common.encode(method), request_serializer, response_deserializer)
-
- def stream_stream(
- self, method, request_serializer=None, response_deserializer=None):
- return _StreamStreamMultiCallable(
- self._channel, _channel_managed_call_management(self._call_state),
- _common.encode(method), request_serializer, response_deserializer)
-
- def __del__(self):
- _moot(self._connectivity_state)
+ self._channel = cygrpc.Channel(
+ _common.encode(target),
+ _common.channel_args(_options(options)), credentials)
+ self._call_state = _ChannelCallState(self._channel)
+ self._connectivity_state = _ChannelConnectivityState(self._channel)
+
+ def subscribe(self, callback, try_to_connect=None):
+ _subscribe(self._connectivity_state, callback, try_to_connect)
+
+ def unsubscribe(self, callback):
+ _unsubscribe(self._connectivity_state, callback)
+
+ def unary_unary(self,
+ method,
+ request_serializer=None,
+ response_deserializer=None):
+ return _UnaryUnaryMultiCallable(
+ self._channel,
+ _channel_managed_call_management(self._call_state),
+ _common.encode(method), request_serializer, response_deserializer)
+
+ def unary_stream(self,
+ method,
+ request_serializer=None,
+ response_deserializer=None):
+ return _UnaryStreamMultiCallable(
+ self._channel,
+ _channel_managed_call_management(self._call_state),
+ _common.encode(method), request_serializer, response_deserializer)
+
+ def stream_unary(self,
+ method,
+ request_serializer=None,
+ response_deserializer=None):
+ return _StreamUnaryMultiCallable(
+ self._channel,
+ _channel_managed_call_management(self._call_state),
+ _common.encode(method), request_serializer, response_deserializer)
+
+ def stream_stream(self,
+ method,
+ request_serializer=None,
+ response_deserializer=None):
+ return _StreamStreamMultiCallable(
+ self._channel,
+ _channel_managed_call_management(self._call_state),
+ _common.encode(method), request_serializer, response_deserializer)
+
+ def __del__(self):
+ _moot(self._connectivity_state)
diff --git a/src/python/grpcio/grpc/_common.py b/src/python/grpcio/grpc/_common.py
index cc0984c8c6..7ef2571379 100644
--- a/src/python/grpcio/grpc/_common.py
+++ b/src/python/grpcio/grpc/_common.py
@@ -26,7 +26,6 @@
# 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.
-
"""Shared implementation."""
import logging
@@ -45,9 +44,8 @@ CYGRPC_CONNECTIVITY_STATE_TO_CHANNEL_CONNECTIVITY = {
cygrpc.ConnectivityState.connecting: grpc.ChannelConnectivity.CONNECTING,
cygrpc.ConnectivityState.ready: grpc.ChannelConnectivity.READY,
cygrpc.ConnectivityState.transient_failure:
- grpc.ChannelConnectivity.TRANSIENT_FAILURE,
- cygrpc.ConnectivityState.shutdown:
- grpc.ChannelConnectivity.SHUTDOWN,
+ grpc.ChannelConnectivity.TRANSIENT_FAILURE,
+ cygrpc.ConnectivityState.shutdown: grpc.ChannelConnectivity.SHUTDOWN,
}
CYGRPC_STATUS_CODE_TO_STATUS_CODE = {
@@ -77,83 +75,88 @@ STATUS_CODE_TO_CYGRPC_STATUS_CODE = {
def encode(s):
- if isinstance(s, bytes):
- return s
- else:
- return s.encode('ascii')
+ if isinstance(s, bytes):
+ return s
+ else:
+ return s.encode('ascii')
def decode(b):
- if isinstance(b, str):
- return b
- else:
- try:
- return b.decode('utf8')
- except UnicodeDecodeError:
- logging.exception('Invalid encoding on {}'.format(b))
- return b.decode('latin1')
+ if isinstance(b, str):
+ return b
+ else:
+ try:
+ return b.decode('utf8')
+ except UnicodeDecodeError:
+ logging.exception('Invalid encoding on {}'.format(b))
+ return b.decode('latin1')
def channel_args(options):
- channel_args = []
- for key, value in options:
- if isinstance(value, six.string_types):
- channel_args.append(cygrpc.ChannelArg(encode(key), encode(value)))
- else:
- channel_args.append(cygrpc.ChannelArg(encode(key), value))
- return cygrpc.ChannelArgs(channel_args)
+ channel_args = []
+ for key, value in options:
+ if isinstance(value, six.string_types):
+ channel_args.append(cygrpc.ChannelArg(encode(key), encode(value)))
+ else:
+ channel_args.append(cygrpc.ChannelArg(encode(key), value))
+ return cygrpc.ChannelArgs(channel_args)
def cygrpc_metadata(application_metadata):
- return _EMPTY_METADATA if application_metadata is None else cygrpc.Metadata(
- cygrpc.Metadatum(encode(key), encode(value))
- for key, value in application_metadata)
+ return _EMPTY_METADATA if application_metadata is None else cygrpc.Metadata(
+ cygrpc.Metadatum(encode(key), encode(value))
+ for key, value in application_metadata)
def application_metadata(cygrpc_metadata):
- if cygrpc_metadata is None:
- return ()
- else:
- return tuple(
- (decode(key), value if key[-4:] == b'-bin' else decode(value))
- for key, value in cygrpc_metadata)
+ if cygrpc_metadata is None:
+ return ()
+ else:
+ return tuple((decode(key), value
+ if key[-4:] == b'-bin' else decode(value))
+ for key, value in cygrpc_metadata)
def _transform(message, transformer, exception_message):
- if transformer is None:
- return message
- else:
- try:
- return transformer(message)
- except Exception: # pylint: disable=broad-except
- logging.exception(exception_message)
- return None
+ if transformer is None:
+ return message
+ else:
+ try:
+ return transformer(message)
+ except Exception: # pylint: disable=broad-except
+ logging.exception(exception_message)
+ return None
def serialize(message, serializer):
- return _transform(message, serializer, 'Exception serializing message!')
+ return _transform(message, serializer, 'Exception serializing message!')
def deserialize(serialized_message, deserializer):
- return _transform(serialized_message, deserializer,
- 'Exception deserializing message!')
+ return _transform(serialized_message, deserializer,
+ 'Exception deserializing message!')
def fully_qualified_method(group, method):
- return '/{}/{}'.format(group, method)
+ return '/{}/{}'.format(group, method)
class CleanupThread(threading.Thread):
- """A threading.Thread subclass supporting custom behavior on join().
+ """A threading.Thread subclass supporting custom behavior on join().
On Python Interpreter exit, Python will attempt to join outstanding threads
prior to garbage collection. We may need to do additional cleanup, and
we accomplish this by overriding the join() method.
"""
- def __init__(self, behavior, group=None, target=None, name=None,
- args=(), kwargs={}):
- """Constructor.
+ def __init__(self,
+ behavior,
+ group=None,
+ target=None,
+ name=None,
+ args=(),
+ kwargs={}):
+ """Constructor.
Args:
behavior (function): Function called on join() with a single
@@ -169,15 +172,15 @@ class CleanupThread(threading.Thread):
kwargs (dict[str,object]): A dictionary of keyword arguments to
pass to `target`.
"""
- super(CleanupThread, self).__init__(group=group, target=target,
- name=name, args=args, kwargs=kwargs)
- self._behavior = behavior
-
- def join(self, timeout=None):
- start_time = time.time()
- self._behavior(timeout)
- end_time = time.time()
- if timeout is not None:
- timeout -= end_time - start_time
- timeout = max(timeout, 0)
- super(CleanupThread, self).join(timeout)
+ super(CleanupThread, self).__init__(
+ group=group, target=target, name=name, args=args, kwargs=kwargs)
+ self._behavior = behavior
+
+ def join(self, timeout=None):
+ start_time = time.time()
+ self._behavior(timeout)
+ end_time = time.time()
+ if timeout is not None:
+ timeout -= end_time - start_time
+ timeout = max(timeout, 0)
+ super(CleanupThread, self).join(timeout)
diff --git a/src/python/grpcio/grpc/_credential_composition.py b/src/python/grpcio/grpc/_credential_composition.py
index 9cb5508e27..bdf017baa5 100644
--- a/src/python/grpcio/grpc/_credential_composition.py
+++ b/src/python/grpcio/grpc/_credential_composition.py
@@ -31,18 +31,18 @@ from grpc._cython import cygrpc
def _call(call_credentialses):
- call_credentials_iterator = iter(call_credentialses)
- composition = next(call_credentials_iterator)
- for additional_call_credentials in call_credentials_iterator:
- composition = cygrpc.call_credentials_composite(
- composition, additional_call_credentials)
- return composition
+ call_credentials_iterator = iter(call_credentialses)
+ composition = next(call_credentials_iterator)
+ for additional_call_credentials in call_credentials_iterator:
+ composition = cygrpc.call_credentials_composite(
+ composition, additional_call_credentials)
+ return composition
def call(call_credentialses):
- return _call(call_credentialses)
+ return _call(call_credentialses)
def channel(channel_credentials, call_credentialses):
- return cygrpc.channel_credentials_composite(
- channel_credentials, _call(call_credentialses))
+ return cygrpc.channel_credentials_composite(channel_credentials,
+ _call(call_credentialses))
diff --git a/src/python/grpcio/grpc/_plugin_wrapping.py b/src/python/grpcio/grpc/_plugin_wrapping.py
index 7cb5218c22..bb9a42f3ff 100644
--- a/src/python/grpcio/grpc/_plugin_wrapping.py
+++ b/src/python/grpcio/grpc/_plugin_wrapping.py
@@ -36,82 +36,82 @@ from grpc._cython import cygrpc
class AuthMetadataContext(
- collections.namedtuple(
- 'AuthMetadataContext', ('service_url', 'method_name',)),
- grpc.AuthMetadataContext):
- pass
+ collections.namedtuple('AuthMetadataContext', (
+ 'service_url',
+ 'method_name',)), grpc.AuthMetadataContext):
+ pass
class AuthMetadataPluginCallback(grpc.AuthMetadataContext):
- def __init__(self, callback):
- self._callback = callback
+ def __init__(self, callback):
+ self._callback = callback
- def __call__(self, metadata, error):
- self._callback(metadata, error)
+ def __call__(self, metadata, error):
+ self._callback(metadata, error)
class _WrappedCygrpcCallback(object):
- def __init__(self, cygrpc_callback):
- self.is_called = False
- self.error = None
- self.is_called_lock = threading.Lock()
- self.cygrpc_callback = cygrpc_callback
-
- def _invoke_failure(self, error):
- # TODO(atash) translate different Exception superclasses into different
- # status codes.
- self.cygrpc_callback(
- _common.EMPTY_METADATA, cygrpc.StatusCode.internal,
- _common.encode(str(error)))
-
- def _invoke_success(self, metadata):
- try:
- cygrpc_metadata = _common.cygrpc_metadata(metadata)
- except Exception as error:
- self._invoke_failure(error)
- return
- self.cygrpc_callback(cygrpc_metadata, cygrpc.StatusCode.ok, b'')
-
- def __call__(self, metadata, error):
- with self.is_called_lock:
- if self.is_called:
- raise RuntimeError('callback should only ever be invoked once')
- if self.error:
- self._invoke_failure(self.error)
- return
- self.is_called = True
- if error is None:
- self._invoke_success(metadata)
- else:
- self._invoke_failure(error)
-
- def notify_failure(self, error):
- with self.is_called_lock:
- if not self.is_called:
- self.error = error
+ def __init__(self, cygrpc_callback):
+ self.is_called = False
+ self.error = None
+ self.is_called_lock = threading.Lock()
+ self.cygrpc_callback = cygrpc_callback
+
+ def _invoke_failure(self, error):
+ # TODO(atash) translate different Exception superclasses into different
+ # status codes.
+ self.cygrpc_callback(_common.EMPTY_METADATA, cygrpc.StatusCode.internal,
+ _common.encode(str(error)))
+
+ def _invoke_success(self, metadata):
+ try:
+ cygrpc_metadata = _common.cygrpc_metadata(metadata)
+ except Exception as error:
+ self._invoke_failure(error)
+ return
+ self.cygrpc_callback(cygrpc_metadata, cygrpc.StatusCode.ok, b'')
+
+ def __call__(self, metadata, error):
+ with self.is_called_lock:
+ if self.is_called:
+ raise RuntimeError('callback should only ever be invoked once')
+ if self.error:
+ self._invoke_failure(self.error)
+ return
+ self.is_called = True
+ if error is None:
+ self._invoke_success(metadata)
+ else:
+ self._invoke_failure(error)
+
+ def notify_failure(self, error):
+ with self.is_called_lock:
+ if not self.is_called:
+ self.error = error
class _WrappedPlugin(object):
- def __init__(self, plugin):
- self.plugin = plugin
+ def __init__(self, plugin):
+ self.plugin = plugin
- def __call__(self, context, cygrpc_callback):
- wrapped_cygrpc_callback = _WrappedCygrpcCallback(cygrpc_callback)
- wrapped_context = AuthMetadataContext(
- _common.decode(context.service_url), _common.decode(context.method_name))
- try:
- self.plugin(
- wrapped_context, AuthMetadataPluginCallback(wrapped_cygrpc_callback))
- except Exception as error:
- wrapped_cygrpc_callback.notify_failure(error)
- raise
+ def __call__(self, context, cygrpc_callback):
+ wrapped_cygrpc_callback = _WrappedCygrpcCallback(cygrpc_callback)
+ wrapped_context = AuthMetadataContext(
+ _common.decode(context.service_url),
+ _common.decode(context.method_name))
+ try:
+ self.plugin(wrapped_context,
+ AuthMetadataPluginCallback(wrapped_cygrpc_callback))
+ except Exception as error:
+ wrapped_cygrpc_callback.notify_failure(error)
+ raise
def call_credentials_metadata_plugin(plugin, name):
- """
+ """
Args:
plugin: A callable accepting a grpc.AuthMetadataContext
object and a callback (itself accepting a list of metadata key/value
@@ -119,5 +119,6 @@ def call_credentials_metadata_plugin(plugin, name):
called, but need not be called in plugin's invocation.
plugin's invocation must be non-blocking.
"""
- return cygrpc.call_credentials_metadata_plugin(
- cygrpc.CredentialsMetadataPlugin(_WrappedPlugin(plugin), _common.encode(name)))
+ return cygrpc.call_credentials_metadata_plugin(
+ cygrpc.CredentialsMetadataPlugin(
+ _WrappedPlugin(plugin), _common.encode(name)))
diff --git a/src/python/grpcio/grpc/_server.py b/src/python/grpcio/grpc/_server.py
index 5223712dfa..158cdf8b0e 100644
--- a/src/python/grpcio/grpc/_server.py
+++ b/src/python/grpcio/grpc/_server.py
@@ -26,7 +26,6 @@
# 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.
-
"""Service-side implementation of gRPC Python."""
import collections
@@ -64,692 +63,715 @@ _UNEXPECTED_EXIT_SERVER_GRACE = 1.0
def _serialized_request(request_event):
- return request_event.batch_operations[0].received_message.bytes()
+ return request_event.batch_operations[0].received_message.bytes()
def _application_code(code):
- cygrpc_code = _common.STATUS_CODE_TO_CYGRPC_STATUS_CODE.get(code)
- return cygrpc.StatusCode.unknown if cygrpc_code is None else cygrpc_code
+ cygrpc_code = _common.STATUS_CODE_TO_CYGRPC_STATUS_CODE.get(code)
+ return cygrpc.StatusCode.unknown if cygrpc_code is None else cygrpc_code
def _completion_code(state):
- if state.code is None:
- return cygrpc.StatusCode.ok
- else:
- return _application_code(state.code)
+ if state.code is None:
+ return cygrpc.StatusCode.ok
+ else:
+ return _application_code(state.code)
def _abortion_code(state, code):
- if state.code is None:
- return code
- else:
- return _application_code(state.code)
+ if state.code is None:
+ return code
+ else:
+ return _application_code(state.code)
def _details(state):
- return b'' if state.details is None else state.details
+ return b'' if state.details is None else state.details
class _HandlerCallDetails(
- collections.namedtuple(
- '_HandlerCallDetails', ('method', 'invocation_metadata',)),
- grpc.HandlerCallDetails):
- pass
+ collections.namedtuple('_HandlerCallDetails', (
+ 'method',
+ 'invocation_metadata',)), grpc.HandlerCallDetails):
+ pass
class _RPCState(object):
- def __init__(self):
- self.condition = threading.Condition()
- self.due = set()
- self.request = None
- self.client = _OPEN
- self.initial_metadata_allowed = True
- self.disable_next_compression = False
- self.trailing_metadata = None
- self.code = None
- self.details = None
- self.statused = False
- self.rpc_errors = []
- self.callbacks = []
+ def __init__(self):
+ self.condition = threading.Condition()
+ self.due = set()
+ self.request = None
+ self.client = _OPEN
+ self.initial_metadata_allowed = True
+ self.disable_next_compression = False
+ self.trailing_metadata = None
+ self.code = None
+ self.details = None
+ self.statused = False
+ self.rpc_errors = []
+ self.callbacks = []
def _raise_rpc_error(state):
- rpc_error = grpc.RpcError()
- state.rpc_errors.append(rpc_error)
- raise rpc_error
+ rpc_error = grpc.RpcError()
+ state.rpc_errors.append(rpc_error)
+ raise rpc_error
def _possibly_finish_call(state, token):
- state.due.remove(token)
- if (state.client is _CANCELLED or state.statused) and not state.due:
- callbacks = state.callbacks
- state.callbacks = None
- return state, callbacks
- else:
- return None, ()
+ state.due.remove(token)
+ if (state.client is _CANCELLED or state.statused) and not state.due:
+ callbacks = state.callbacks
+ state.callbacks = None
+ return state, callbacks
+ else:
+ return None, ()
def _send_status_from_server(state, token):
- def send_status_from_server(unused_send_status_from_server_event):
- with state.condition:
- return _possibly_finish_call(state, token)
- return send_status_from_server
+
+ def send_status_from_server(unused_send_status_from_server_event):
+ with state.condition:
+ return _possibly_finish_call(state, token)
+
+ return send_status_from_server
def _abort(state, call, code, details):
- if state.client is not _CANCELLED:
- effective_code = _abortion_code(state, code)
- effective_details = details if state.details is None else state.details
- if state.initial_metadata_allowed:
- operations = (
- cygrpc.operation_send_initial_metadata(
- _EMPTY_METADATA, _EMPTY_FLAGS),
- cygrpc.operation_send_status_from_server(
- _common.cygrpc_metadata(state.trailing_metadata), effective_code,
- effective_details, _EMPTY_FLAGS),
- )
- token = _SEND_INITIAL_METADATA_AND_SEND_STATUS_FROM_SERVER_TOKEN
- else:
- operations = (
- cygrpc.operation_send_status_from_server(
- _common.cygrpc_metadata(state.trailing_metadata), effective_code,
- effective_details, _EMPTY_FLAGS),
- )
- token = _SEND_STATUS_FROM_SERVER_TOKEN
- call.start_server_batch(
- cygrpc.Operations(operations),
- _send_status_from_server(state, token))
- state.statused = True
- state.due.add(token)
+ if state.client is not _CANCELLED:
+ effective_code = _abortion_code(state, code)
+ effective_details = details if state.details is None else state.details
+ if state.initial_metadata_allowed:
+ operations = (
+ cygrpc.operation_send_initial_metadata(_EMPTY_METADATA,
+ _EMPTY_FLAGS),
+ cygrpc.operation_send_status_from_server(
+ _common.cygrpc_metadata(state.trailing_metadata),
+ effective_code, effective_details, _EMPTY_FLAGS),)
+ token = _SEND_INITIAL_METADATA_AND_SEND_STATUS_FROM_SERVER_TOKEN
+ else:
+ operations = (cygrpc.operation_send_status_from_server(
+ _common.cygrpc_metadata(state.trailing_metadata),
+ effective_code, effective_details, _EMPTY_FLAGS),)
+ token = _SEND_STATUS_FROM_SERVER_TOKEN
+ call.start_server_batch(
+ cygrpc.Operations(operations),
+ _send_status_from_server(state, token))
+ state.statused = True
+ state.due.add(token)
def _receive_close_on_server(state):
- def receive_close_on_server(receive_close_on_server_event):
- with state.condition:
- if receive_close_on_server_event.batch_operations[0].received_cancelled:
- state.client = _CANCELLED
- elif state.client is _OPEN:
- state.client = _CLOSED
- state.condition.notify_all()
- return _possibly_finish_call(state, _RECEIVE_CLOSE_ON_SERVER_TOKEN)
- return receive_close_on_server
+
+ def receive_close_on_server(receive_close_on_server_event):
+ with state.condition:
+ if receive_close_on_server_event.batch_operations[
+ 0].received_cancelled:
+ state.client = _CANCELLED
+ elif state.client is _OPEN:
+ state.client = _CLOSED
+ state.condition.notify_all()
+ return _possibly_finish_call(state, _RECEIVE_CLOSE_ON_SERVER_TOKEN)
+
+ return receive_close_on_server
def _receive_message(state, call, request_deserializer):
- def receive_message(receive_message_event):
- serialized_request = _serialized_request(receive_message_event)
- if serialized_request is None:
- with state.condition:
- if state.client is _OPEN:
- state.client = _CLOSED
- state.condition.notify_all()
- return _possibly_finish_call(state, _RECEIVE_MESSAGE_TOKEN)
- else:
- request = _common.deserialize(serialized_request, request_deserializer)
- with state.condition:
- if request is None:
- _abort(
- state, call, cygrpc.StatusCode.internal,
- b'Exception deserializing request!')
+
+ def receive_message(receive_message_event):
+ serialized_request = _serialized_request(receive_message_event)
+ if serialized_request is None:
+ with state.condition:
+ if state.client is _OPEN:
+ state.client = _CLOSED
+ state.condition.notify_all()
+ return _possibly_finish_call(state, _RECEIVE_MESSAGE_TOKEN)
else:
- state.request = request
- state.condition.notify_all()
- return _possibly_finish_call(state, _RECEIVE_MESSAGE_TOKEN)
- return receive_message
+ request = _common.deserialize(serialized_request,
+ request_deserializer)
+ with state.condition:
+ if request is None:
+ _abort(state, call, cygrpc.StatusCode.internal,
+ b'Exception deserializing request!')
+ else:
+ state.request = request
+ state.condition.notify_all()
+ return _possibly_finish_call(state, _RECEIVE_MESSAGE_TOKEN)
+
+ return receive_message
def _send_initial_metadata(state):
- def send_initial_metadata(unused_send_initial_metadata_event):
- with state.condition:
- return _possibly_finish_call(state, _SEND_INITIAL_METADATA_TOKEN)
- return send_initial_metadata
+
+ def send_initial_metadata(unused_send_initial_metadata_event):
+ with state.condition:
+ return _possibly_finish_call(state, _SEND_INITIAL_METADATA_TOKEN)
+
+ return send_initial_metadata
def _send_message(state, token):
- def send_message(unused_send_message_event):
- with state.condition:
- state.condition.notify_all()
- return _possibly_finish_call(state, token)
- return send_message
+
+ def send_message(unused_send_message_event):
+ with state.condition:
+ state.condition.notify_all()
+ return _possibly_finish_call(state, token)
+
+ return send_message
class _Context(grpc.ServicerContext):
- def __init__(self, rpc_event, state, request_deserializer):
- self._rpc_event = rpc_event
- self._state = state
- self._request_deserializer = request_deserializer
+ def __init__(self, rpc_event, state, request_deserializer):
+ self._rpc_event = rpc_event
+ self._state = state
+ self._request_deserializer = request_deserializer
- def is_active(self):
- with self._state.condition:
- return self._state.client is not _CANCELLED and not self._state.statused
+ def is_active(self):
+ with self._state.condition:
+ return self._state.client is not _CANCELLED and not self._state.statused
- def time_remaining(self):
- return max(self._rpc_event.request_call_details.deadline - time.time(), 0)
+ def time_remaining(self):
+ return max(self._rpc_event.request_call_details.deadline - time.time(),
+ 0)
- def cancel(self):
- self._rpc_event.operation_call.cancel()
+ def cancel(self):
+ self._rpc_event.operation_call.cancel()
- def add_callback(self, callback):
- with self._state.condition:
- if self._state.callbacks is None:
- return False
- else:
- self._state.callbacks.append(callback)
- return True
+ def add_callback(self, callback):
+ with self._state.condition:
+ if self._state.callbacks is None:
+ return False
+ else:
+ self._state.callbacks.append(callback)
+ return True
- def disable_next_message_compression(self):
- with self._state.condition:
- self._state.disable_next_compression = True
-
- def invocation_metadata(self):
- return _common.application_metadata(self._rpc_event.request_metadata)
-
- def peer(self):
- return _common.decode(self._rpc_event.operation_call.peer())
-
- def send_initial_metadata(self, initial_metadata):
- with self._state.condition:
- if self._state.client is _CANCELLED:
- _raise_rpc_error(self._state)
- else:
- if self._state.initial_metadata_allowed:
- operation = cygrpc.operation_send_initial_metadata(
- _common.cygrpc_metadata(initial_metadata), _EMPTY_FLAGS)
- self._rpc_event.operation_call.start_server_batch(
- cygrpc.Operations((operation,)),
- _send_initial_metadata(self._state))
- self._state.initial_metadata_allowed = False
- self._state.due.add(_SEND_INITIAL_METADATA_TOKEN)
- else:
- raise ValueError('Initial metadata no longer allowed!')
+ def disable_next_message_compression(self):
+ with self._state.condition:
+ self._state.disable_next_compression = True
- def set_trailing_metadata(self, trailing_metadata):
- with self._state.condition:
- self._state.trailing_metadata = _common.cygrpc_metadata(
- trailing_metadata)
+ def invocation_metadata(self):
+ return _common.application_metadata(self._rpc_event.request_metadata)
- def set_code(self, code):
- with self._state.condition:
- self._state.code = code
+ def peer(self):
+ return _common.decode(self._rpc_event.operation_call.peer())
- def set_details(self, details):
- with self._state.condition:
- self._state.details = _common.encode(details)
+ def send_initial_metadata(self, initial_metadata):
+ with self._state.condition:
+ if self._state.client is _CANCELLED:
+ _raise_rpc_error(self._state)
+ else:
+ if self._state.initial_metadata_allowed:
+ operation = cygrpc.operation_send_initial_metadata(
+ _common.cygrpc_metadata(initial_metadata), _EMPTY_FLAGS)
+ self._rpc_event.operation_call.start_server_batch(
+ cygrpc.Operations((operation,)),
+ _send_initial_metadata(self._state))
+ self._state.initial_metadata_allowed = False
+ self._state.due.add(_SEND_INITIAL_METADATA_TOKEN)
+ else:
+ raise ValueError('Initial metadata no longer allowed!')
+
+ def set_trailing_metadata(self, trailing_metadata):
+ with self._state.condition:
+ self._state.trailing_metadata = _common.cygrpc_metadata(
+ trailing_metadata)
+
+ def set_code(self, code):
+ with self._state.condition:
+ self._state.code = code
+
+ def set_details(self, details):
+ with self._state.condition:
+ self._state.details = _common.encode(details)
class _RequestIterator(object):
- def __init__(self, state, call, request_deserializer):
- self._state = state
- self._call = call
- self._request_deserializer = request_deserializer
+ def __init__(self, state, call, request_deserializer):
+ self._state = state
+ self._call = call
+ self._request_deserializer = request_deserializer
- def _raise_or_start_receive_message(self):
- if self._state.client is _CANCELLED:
- _raise_rpc_error(self._state)
- elif self._state.client is _CLOSED or self._state.statused:
- raise StopIteration()
- else:
- self._call.start_server_batch(
- cygrpc.Operations((cygrpc.operation_receive_message(_EMPTY_FLAGS),)),
- _receive_message(self._state, self._call, self._request_deserializer))
- self._state.due.add(_RECEIVE_MESSAGE_TOKEN)
-
- def _look_for_request(self):
- if self._state.client is _CANCELLED:
- _raise_rpc_error(self._state)
- elif (self._state.request is None and
- _RECEIVE_MESSAGE_TOKEN not in self._state.due):
- raise StopIteration()
- else:
- request = self._state.request
- self._state.request = None
- return request
+ def _raise_or_start_receive_message(self):
+ if self._state.client is _CANCELLED:
+ _raise_rpc_error(self._state)
+ elif self._state.client is _CLOSED or self._state.statused:
+ raise StopIteration()
+ else:
+ self._call.start_server_batch(
+ cygrpc.Operations(
+ (cygrpc.operation_receive_message(_EMPTY_FLAGS),)),
+ _receive_message(self._state, self._call,
+ self._request_deserializer))
+ self._state.due.add(_RECEIVE_MESSAGE_TOKEN)
+
+ def _look_for_request(self):
+ if self._state.client is _CANCELLED:
+ _raise_rpc_error(self._state)
+ elif (self._state.request is None and
+ _RECEIVE_MESSAGE_TOKEN not in self._state.due):
+ raise StopIteration()
+ else:
+ request = self._state.request
+ self._state.request = None
+ return request
- def _next(self):
- with self._state.condition:
- self._raise_or_start_receive_message()
- while True:
- self._state.condition.wait()
- request = self._look_for_request()
- if request is not None:
- return request
+ def _next(self):
+ with self._state.condition:
+ self._raise_or_start_receive_message()
+ while True:
+ self._state.condition.wait()
+ request = self._look_for_request()
+ if request is not None:
+ return request
- def __iter__(self):
- return self
+ def __iter__(self):
+ return self
- def __next__(self):
- return self._next()
+ def __next__(self):
+ return self._next()
- def next(self):
- return self._next()
+ def next(self):
+ return self._next()
def _unary_request(rpc_event, state, request_deserializer):
- def unary_request():
- with state.condition:
- if state.client is _CANCELLED or state.statused:
- return None
- else:
- start_server_batch_result = rpc_event.operation_call.start_server_batch(
- cygrpc.Operations(
- (cygrpc.operation_receive_message(_EMPTY_FLAGS),)),
- _receive_message(
- state, rpc_event.operation_call, request_deserializer))
- state.due.add(_RECEIVE_MESSAGE_TOKEN)
- while True:
- state.condition.wait()
- if state.request is None:
- if state.client is _CLOSED:
- details = '"{}" requires exactly one request message.'.format(
- rpc_event.request_call_details.method)
- _abort(
- state, rpc_event.operation_call,
- cygrpc.StatusCode.unimplemented, _common.encode(details))
- return None
- elif state.client is _CANCELLED:
- return None
- else:
- request = state.request
- state.request = None
- return request
- return unary_request
+
+ def unary_request():
+ with state.condition:
+ if state.client is _CANCELLED or state.statused:
+ return None
+ else:
+ start_server_batch_result = rpc_event.operation_call.start_server_batch(
+ cygrpc.Operations(
+ (cygrpc.operation_receive_message(_EMPTY_FLAGS),)),
+ _receive_message(state, rpc_event.operation_call,
+ request_deserializer))
+ state.due.add(_RECEIVE_MESSAGE_TOKEN)
+ while True:
+ state.condition.wait()
+ if state.request is None:
+ if state.client is _CLOSED:
+ details = '"{}" requires exactly one request message.'.format(
+ rpc_event.request_call_details.method)
+ _abort(state, rpc_event.operation_call,
+ cygrpc.StatusCode.unimplemented,
+ _common.encode(details))
+ return None
+ elif state.client is _CANCELLED:
+ return None
+ else:
+ request = state.request
+ state.request = None
+ return request
+
+ return unary_request
def _call_behavior(rpc_event, state, behavior, argument, request_deserializer):
- context = _Context(rpc_event, state, request_deserializer)
- try:
- return behavior(argument, context), True
- except Exception as e: # pylint: disable=broad-except
- with state.condition:
- if e not in state.rpc_errors:
- details = 'Exception calling application: {}'.format(e)
- logging.exception(details)
- _abort(state, rpc_event.operation_call,
- cygrpc.StatusCode.unknown, _common.encode(details))
- return None, False
+ context = _Context(rpc_event, state, request_deserializer)
+ try:
+ return behavior(argument, context), True
+ except Exception as e: # pylint: disable=broad-except
+ with state.condition:
+ if e not in state.rpc_errors:
+ details = 'Exception calling application: {}'.format(e)
+ logging.exception(details)
+ _abort(state, rpc_event.operation_call,
+ cygrpc.StatusCode.unknown, _common.encode(details))
+ return None, False
def _take_response_from_response_iterator(rpc_event, state, response_iterator):
- try:
- return next(response_iterator), True
- except StopIteration:
- return None, True
- except Exception as e: # pylint: disable=broad-except
- with state.condition:
- if e not in state.rpc_errors:
- details = 'Exception iterating responses: {}'.format(e)
- logging.exception(details)
- _abort(state, rpc_event.operation_call,
- cygrpc.StatusCode.unknown, _common.encode(details))
- return None, False
+ try:
+ return next(response_iterator), True
+ except StopIteration:
+ return None, True
+ except Exception as e: # pylint: disable=broad-except
+ with state.condition:
+ if e not in state.rpc_errors:
+ details = 'Exception iterating responses: {}'.format(e)
+ logging.exception(details)
+ _abort(state, rpc_event.operation_call,
+ cygrpc.StatusCode.unknown, _common.encode(details))
+ return None, False
def _serialize_response(rpc_event, state, response, response_serializer):
- serialized_response = _common.serialize(response, response_serializer)
- if serialized_response is None:
- with state.condition:
- _abort(
- state, rpc_event.operation_call, cygrpc.StatusCode.internal,
- b'Failed to serialize response!')
- return None
- else:
- return serialized_response
+ serialized_response = _common.serialize(response, response_serializer)
+ if serialized_response is None:
+ with state.condition:
+ _abort(state, rpc_event.operation_call, cygrpc.StatusCode.internal,
+ b'Failed to serialize response!')
+ return None
+ else:
+ return serialized_response
def _send_response(rpc_event, state, serialized_response):
- with state.condition:
- if state.client is _CANCELLED or state.statused:
- return False
- else:
- if state.initial_metadata_allowed:
- operations = (
- cygrpc.operation_send_initial_metadata(
- _EMPTY_METADATA, _EMPTY_FLAGS),
- cygrpc.operation_send_message(serialized_response, _EMPTY_FLAGS),
- )
- state.initial_metadata_allowed = False
- token = _SEND_INITIAL_METADATA_AND_SEND_MESSAGE_TOKEN
- else:
- operations = (
- cygrpc.operation_send_message(serialized_response, _EMPTY_FLAGS),
- )
- token = _SEND_MESSAGE_TOKEN
- rpc_event.operation_call.start_server_batch(
- cygrpc.Operations(operations), _send_message(state, token))
- state.due.add(token)
- while True:
- state.condition.wait()
- if token not in state.due:
- return state.client is not _CANCELLED and not state.statused
+ with state.condition:
+ if state.client is _CANCELLED or state.statused:
+ return False
+ else:
+ if state.initial_metadata_allowed:
+ operations = (
+ cygrpc.operation_send_initial_metadata(_EMPTY_METADATA,
+ _EMPTY_FLAGS),
+ cygrpc.operation_send_message(serialized_response,
+ _EMPTY_FLAGS),)
+ state.initial_metadata_allowed = False
+ token = _SEND_INITIAL_METADATA_AND_SEND_MESSAGE_TOKEN
+ else:
+ operations = (cygrpc.operation_send_message(serialized_response,
+ _EMPTY_FLAGS),)
+ token = _SEND_MESSAGE_TOKEN
+ rpc_event.operation_call.start_server_batch(
+ cygrpc.Operations(operations), _send_message(state, token))
+ state.due.add(token)
+ while True:
+ state.condition.wait()
+ if token not in state.due:
+ return state.client is not _CANCELLED and not state.statused
def _status(rpc_event, state, serialized_response):
- with state.condition:
- if state.client is not _CANCELLED:
- trailing_metadata = _common.cygrpc_metadata(state.trailing_metadata)
- code = _completion_code(state)
- details = _details(state)
- operations = [
- cygrpc.operation_send_status_from_server(
- trailing_metadata, code, details, _EMPTY_FLAGS),
- ]
- if state.initial_metadata_allowed:
- operations.append(
- cygrpc.operation_send_initial_metadata(
- _EMPTY_METADATA, _EMPTY_FLAGS))
- if serialized_response is not None:
- operations.append(cygrpc.operation_send_message(
- serialized_response, _EMPTY_FLAGS))
- rpc_event.operation_call.start_server_batch(
- cygrpc.Operations(operations),
- _send_status_from_server(state, _SEND_STATUS_FROM_SERVER_TOKEN))
- state.statused = True
- state.due.add(_SEND_STATUS_FROM_SERVER_TOKEN)
-
-
-def _unary_response_in_pool(
- rpc_event, state, behavior, argument_thunk, request_deserializer,
- response_serializer):
- argument = argument_thunk()
- if argument is not None:
- response, proceed = _call_behavior(
- rpc_event, state, behavior, argument, request_deserializer)
- if proceed:
- serialized_response = _serialize_response(
- rpc_event, state, response, response_serializer)
- if serialized_response is not None:
- _status(rpc_event, state, serialized_response)
-
-
-def _stream_response_in_pool(
- rpc_event, state, behavior, argument_thunk, request_deserializer,
- response_serializer):
- argument = argument_thunk()
- if argument is not None:
- response_iterator, proceed = _call_behavior(
- rpc_event, state, behavior, argument, request_deserializer)
- if proceed:
- while True:
- response, proceed = _take_response_from_response_iterator(
- rpc_event, state, response_iterator)
+ with state.condition:
+ if state.client is not _CANCELLED:
+ trailing_metadata = _common.cygrpc_metadata(state.trailing_metadata)
+ code = _completion_code(state)
+ details = _details(state)
+ operations = [
+ cygrpc.operation_send_status_from_server(
+ trailing_metadata, code, details, _EMPTY_FLAGS),
+ ]
+ if state.initial_metadata_allowed:
+ operations.append(
+ cygrpc.operation_send_initial_metadata(_EMPTY_METADATA,
+ _EMPTY_FLAGS))
+ if serialized_response is not None:
+ operations.append(
+ cygrpc.operation_send_message(serialized_response,
+ _EMPTY_FLAGS))
+ rpc_event.operation_call.start_server_batch(
+ cygrpc.Operations(operations),
+ _send_status_from_server(state, _SEND_STATUS_FROM_SERVER_TOKEN))
+ state.statused = True
+ state.due.add(_SEND_STATUS_FROM_SERVER_TOKEN)
+
+
+def _unary_response_in_pool(rpc_event, state, behavior, argument_thunk,
+ request_deserializer, response_serializer):
+ argument = argument_thunk()
+ if argument is not None:
+ response, proceed = _call_behavior(rpc_event, state, behavior, argument,
+ request_deserializer)
if proceed:
- if response is None:
- _status(rpc_event, state, None)
- break
- else:
serialized_response = _serialize_response(
rpc_event, state, response, response_serializer)
if serialized_response is not None:
- proceed = _send_response(rpc_event, state, serialized_response)
- if not proceed:
- break
- else:
- break
- else:
- break
+ _status(rpc_event, state, serialized_response)
+
+
+def _stream_response_in_pool(rpc_event, state, behavior, argument_thunk,
+ request_deserializer, response_serializer):
+ argument = argument_thunk()
+ if argument is not None:
+ response_iterator, proceed = _call_behavior(
+ rpc_event, state, behavior, argument, request_deserializer)
+ if proceed:
+ while True:
+ response, proceed = _take_response_from_response_iterator(
+ rpc_event, state, response_iterator)
+ if proceed:
+ if response is None:
+ _status(rpc_event, state, None)
+ break
+ else:
+ serialized_response = _serialize_response(
+ rpc_event, state, response, response_serializer)
+ if serialized_response is not None:
+ proceed = _send_response(rpc_event, state,
+ serialized_response)
+ if not proceed:
+ break
+ else:
+ break
+ else:
+ break
def _handle_unary_unary(rpc_event, state, method_handler, thread_pool):
- unary_request = _unary_request(
- rpc_event, state, method_handler.request_deserializer)
- thread_pool.submit(
- _unary_response_in_pool, rpc_event, state, method_handler.unary_unary,
- unary_request, method_handler.request_deserializer,
- method_handler.response_serializer)
+ unary_request = _unary_request(rpc_event, state,
+ method_handler.request_deserializer)
+ thread_pool.submit(_unary_response_in_pool, rpc_event, state,
+ method_handler.unary_unary, unary_request,
+ method_handler.request_deserializer,
+ method_handler.response_serializer)
def _handle_unary_stream(rpc_event, state, method_handler, thread_pool):
- unary_request = _unary_request(
- rpc_event, state, method_handler.request_deserializer)
- thread_pool.submit(
- _stream_response_in_pool, rpc_event, state, method_handler.unary_stream,
- unary_request, method_handler.request_deserializer,
- method_handler.response_serializer)
+ unary_request = _unary_request(rpc_event, state,
+ method_handler.request_deserializer)
+ thread_pool.submit(_stream_response_in_pool, rpc_event, state,
+ method_handler.unary_stream, unary_request,
+ method_handler.request_deserializer,
+ method_handler.response_serializer)
def _handle_stream_unary(rpc_event, state, method_handler, thread_pool):
- request_iterator = _RequestIterator(
- state, rpc_event.operation_call, method_handler.request_deserializer)
- thread_pool.submit(
- _unary_response_in_pool, rpc_event, state, method_handler.stream_unary,
- lambda: request_iterator, method_handler.request_deserializer,
- method_handler.response_serializer)
+ request_iterator = _RequestIterator(state, rpc_event.operation_call,
+ method_handler.request_deserializer)
+ thread_pool.submit(_unary_response_in_pool, rpc_event, state,
+ method_handler.stream_unary, lambda: request_iterator,
+ method_handler.request_deserializer,
+ method_handler.response_serializer)
def _handle_stream_stream(rpc_event, state, method_handler, thread_pool):
- request_iterator = _RequestIterator(
- state, rpc_event.operation_call, method_handler.request_deserializer)
- thread_pool.submit(
- _stream_response_in_pool, rpc_event, state, method_handler.stream_stream,
- lambda: request_iterator, method_handler.request_deserializer,
- method_handler.response_serializer)
+ request_iterator = _RequestIterator(state, rpc_event.operation_call,
+ method_handler.request_deserializer)
+ thread_pool.submit(_stream_response_in_pool, rpc_event, state,
+ method_handler.stream_stream, lambda: request_iterator,
+ method_handler.request_deserializer,
+ method_handler.response_serializer)
def _find_method_handler(rpc_event, generic_handlers):
- for generic_handler in generic_handlers:
- method_handler = generic_handler.service(
- _HandlerCallDetails(
- _common.decode(rpc_event.request_call_details.method),
- rpc_event.request_metadata))
- if method_handler is not None:
- return method_handler
- else:
- return None
+ for generic_handler in generic_handlers:
+ method_handler = generic_handler.service(
+ _HandlerCallDetails(
+ _common.decode(rpc_event.request_call_details.method),
+ rpc_event.request_metadata))
+ if method_handler is not None:
+ return method_handler
+ else:
+ return None
def _handle_unrecognized_method(rpc_event):
- operations = (
- cygrpc.operation_send_initial_metadata(_EMPTY_METADATA, _EMPTY_FLAGS),
- cygrpc.operation_receive_close_on_server(_EMPTY_FLAGS),
- cygrpc.operation_send_status_from_server(
- _EMPTY_METADATA, cygrpc.StatusCode.unimplemented,
- b'Method not found!', _EMPTY_FLAGS),
- )
- rpc_state = _RPCState()
- rpc_event.operation_call.start_server_batch(
- operations, lambda ignored_event: (rpc_state, (),))
- return rpc_state
+ operations = (
+ cygrpc.operation_send_initial_metadata(_EMPTY_METADATA, _EMPTY_FLAGS),
+ cygrpc.operation_receive_close_on_server(_EMPTY_FLAGS),
+ cygrpc.operation_send_status_from_server(
+ _EMPTY_METADATA, cygrpc.StatusCode.unimplemented,
+ b'Method not found!', _EMPTY_FLAGS),)
+ rpc_state = _RPCState()
+ rpc_event.operation_call.start_server_batch(operations,
+ lambda ignored_event: (
+ rpc_state,
+ (),))
+ return rpc_state
def _handle_with_method_handler(rpc_event, method_handler, thread_pool):
- state = _RPCState()
- with state.condition:
- rpc_event.operation_call.start_server_batch(
- cygrpc.Operations(
- (cygrpc.operation_receive_close_on_server(_EMPTY_FLAGS),)),
- _receive_close_on_server(state))
- state.due.add(_RECEIVE_CLOSE_ON_SERVER_TOKEN)
- if method_handler.request_streaming:
- if method_handler.response_streaming:
- _handle_stream_stream(rpc_event, state, method_handler, thread_pool)
- else:
- _handle_stream_unary(rpc_event, state, method_handler, thread_pool)
- else:
- if method_handler.response_streaming:
- _handle_unary_stream(rpc_event, state, method_handler, thread_pool)
- else:
- _handle_unary_unary(rpc_event, state, method_handler, thread_pool)
- return state
+ state = _RPCState()
+ with state.condition:
+ rpc_event.operation_call.start_server_batch(
+ cygrpc.Operations(
+ (cygrpc.operation_receive_close_on_server(_EMPTY_FLAGS),)),
+ _receive_close_on_server(state))
+ state.due.add(_RECEIVE_CLOSE_ON_SERVER_TOKEN)
+ if method_handler.request_streaming:
+ if method_handler.response_streaming:
+ _handle_stream_stream(rpc_event, state, method_handler,
+ thread_pool)
+ else:
+ _handle_stream_unary(rpc_event, state, method_handler,
+ thread_pool)
+ else:
+ if method_handler.response_streaming:
+ _handle_unary_stream(rpc_event, state, method_handler,
+ thread_pool)
+ else:
+ _handle_unary_unary(rpc_event, state, method_handler,
+ thread_pool)
+ return state
def _handle_call(rpc_event, generic_handlers, thread_pool):
- if rpc_event.request_call_details.method is not None:
- method_handler = _find_method_handler(rpc_event, generic_handlers)
- if method_handler is None:
- return _handle_unrecognized_method(rpc_event)
+ if rpc_event.request_call_details.method is not None:
+ method_handler = _find_method_handler(rpc_event, generic_handlers)
+ if method_handler is None:
+ return _handle_unrecognized_method(rpc_event)
+ else:
+ return _handle_with_method_handler(rpc_event, method_handler,
+ thread_pool)
else:
- return _handle_with_method_handler(rpc_event, method_handler, thread_pool)
- else:
- return None
+ return None
@enum.unique
class _ServerStage(enum.Enum):
- STOPPED = 'stopped'
- STARTED = 'started'
- GRACE = 'grace'
+ STOPPED = 'stopped'
+ STARTED = 'started'
+ GRACE = 'grace'
class _ServerState(object):
- def __init__(self, completion_queue, server, generic_handlers, thread_pool):
- self.lock = threading.Lock()
- self.completion_queue = completion_queue
- self.server = server
- self.generic_handlers = list(generic_handlers)
- self.thread_pool = thread_pool
- self.stage = _ServerStage.STOPPED
- self.shutdown_events = None
+ def __init__(self, completion_queue, server, generic_handlers, thread_pool):
+ self.lock = threading.Lock()
+ self.completion_queue = completion_queue
+ self.server = server
+ self.generic_handlers = list(generic_handlers)
+ self.thread_pool = thread_pool
+ self.stage = _ServerStage.STOPPED
+ self.shutdown_events = None
- # TODO(https://github.com/grpc/grpc/issues/6597): eliminate these fields.
- self.rpc_states = set()
- self.due = set()
+ # TODO(https://github.com/grpc/grpc/issues/6597): eliminate these fields.
+ self.rpc_states = set()
+ self.due = set()
def _add_generic_handlers(state, generic_handlers):
- with state.lock:
- state.generic_handlers.extend(generic_handlers)
+ with state.lock:
+ state.generic_handlers.extend(generic_handlers)
def _add_insecure_port(state, address):
- with state.lock:
- return state.server.add_http2_port(address)
+ with state.lock:
+ return state.server.add_http2_port(address)
def _add_secure_port(state, address, server_credentials):
- with state.lock:
- return state.server.add_http2_port(address, server_credentials._credentials)
+ with state.lock:
+ return state.server.add_http2_port(address,
+ server_credentials._credentials)
def _request_call(state):
- state.server.request_call(
- state.completion_queue, state.completion_queue, _REQUEST_CALL_TAG)
- state.due.add(_REQUEST_CALL_TAG)
+ state.server.request_call(state.completion_queue, state.completion_queue,
+ _REQUEST_CALL_TAG)
+ state.due.add(_REQUEST_CALL_TAG)
# TODO(https://github.com/grpc/grpc/issues/6597): delete this function.
def _stop_serving(state):
- if not state.rpc_states and not state.due:
- for shutdown_event in state.shutdown_events:
- shutdown_event.set()
- state.stage = _ServerStage.STOPPED
- return True
- else:
- return False
+ if not state.rpc_states and not state.due:
+ for shutdown_event in state.shutdown_events:
+ shutdown_event.set()
+ state.stage = _ServerStage.STOPPED
+ return True
+ else:
+ return False
def _serve(state):
- while True:
- event = state.completion_queue.poll()
- if event.tag is _SHUTDOWN_TAG:
- with state.lock:
- state.due.remove(_SHUTDOWN_TAG)
- if _stop_serving(state):
- return
- elif event.tag is _REQUEST_CALL_TAG:
- with state.lock:
- state.due.remove(_REQUEST_CALL_TAG)
- rpc_state = _handle_call(
- event, state.generic_handlers, state.thread_pool)
- if rpc_state is not None:
- state.rpc_states.add(rpc_state)
- if state.stage is _ServerStage.STARTED:
- _request_call(state)
- elif _stop_serving(state):
- return
- else:
- rpc_state, callbacks = event.tag(event)
- for callback in callbacks:
- callable_util.call_logging_exceptions(
- callback, 'Exception calling callback!')
- if rpc_state is not None:
- with state.lock:
- state.rpc_states.remove(rpc_state)
- if _stop_serving(state):
- return
+ while True:
+ event = state.completion_queue.poll()
+ if event.tag is _SHUTDOWN_TAG:
+ with state.lock:
+ state.due.remove(_SHUTDOWN_TAG)
+ if _stop_serving(state):
+ return
+ elif event.tag is _REQUEST_CALL_TAG:
+ with state.lock:
+ state.due.remove(_REQUEST_CALL_TAG)
+ rpc_state = _handle_call(event, state.generic_handlers,
+ state.thread_pool)
+ if rpc_state is not None:
+ state.rpc_states.add(rpc_state)
+ if state.stage is _ServerStage.STARTED:
+ _request_call(state)
+ elif _stop_serving(state):
+ return
+ else:
+ rpc_state, callbacks = event.tag(event)
+ for callback in callbacks:
+ callable_util.call_logging_exceptions(
+ callback, 'Exception calling callback!')
+ if rpc_state is not None:
+ with state.lock:
+ state.rpc_states.remove(rpc_state)
+ if _stop_serving(state):
+ return
def _stop(state, grace):
- with state.lock:
- if state.stage is _ServerStage.STOPPED:
- shutdown_event = threading.Event()
- shutdown_event.set()
- return shutdown_event
- else:
- if state.stage is _ServerStage.STARTED:
- state.server.shutdown(state.completion_queue, _SHUTDOWN_TAG)
- state.stage = _ServerStage.GRACE
- state.shutdown_events = []
- state.due.add(_SHUTDOWN_TAG)
- shutdown_event = threading.Event()
- state.shutdown_events.append(shutdown_event)
- if grace is None:
- state.server.cancel_all_calls()
- # TODO(https://github.com/grpc/grpc/issues/6597): delete this loop.
- for rpc_state in state.rpc_states:
- with rpc_state.condition:
- rpc_state.client = _CANCELLED
- rpc_state.condition.notify_all()
- else:
- def cancel_all_calls_after_grace():
- shutdown_event.wait(timeout=grace)
- with state.lock:
- state.server.cancel_all_calls()
- # TODO(https://github.com/grpc/grpc/issues/6597): delete this loop.
- for rpc_state in state.rpc_states:
- with rpc_state.condition:
- rpc_state.client = _CANCELLED
- rpc_state.condition.notify_all()
- thread = threading.Thread(target=cancel_all_calls_after_grace)
- thread.start()
- return shutdown_event
- shutdown_event.wait()
- return shutdown_event
+ with state.lock:
+ if state.stage is _ServerStage.STOPPED:
+ shutdown_event = threading.Event()
+ shutdown_event.set()
+ return shutdown_event
+ else:
+ if state.stage is _ServerStage.STARTED:
+ state.server.shutdown(state.completion_queue, _SHUTDOWN_TAG)
+ state.stage = _ServerStage.GRACE
+ state.shutdown_events = []
+ state.due.add(_SHUTDOWN_TAG)
+ shutdown_event = threading.Event()
+ state.shutdown_events.append(shutdown_event)
+ if grace is None:
+ state.server.cancel_all_calls()
+ # TODO(https://github.com/grpc/grpc/issues/6597): delete this loop.
+ for rpc_state in state.rpc_states:
+ with rpc_state.condition:
+ rpc_state.client = _CANCELLED
+ rpc_state.condition.notify_all()
+ else:
+
+ def cancel_all_calls_after_grace():
+ shutdown_event.wait(timeout=grace)
+ with state.lock:
+ state.server.cancel_all_calls()
+ # TODO(https://github.com/grpc/grpc/issues/6597): delete this loop.
+ for rpc_state in state.rpc_states:
+ with rpc_state.condition:
+ rpc_state.client = _CANCELLED
+ rpc_state.condition.notify_all()
+
+ thread = threading.Thread(target=cancel_all_calls_after_grace)
+ thread.start()
+ return shutdown_event
+ shutdown_event.wait()
+ return shutdown_event
def _start(state):
- with state.lock:
- if state.stage is not _ServerStage.STOPPED:
- raise ValueError('Cannot start already-started server!')
- state.server.start()
- state.stage = _ServerStage.STARTED
- _request_call(state)
- def cleanup_server(timeout):
- if timeout is None:
- _stop(state, _UNEXPECTED_EXIT_SERVER_GRACE).wait()
- else:
- _stop(state, timeout).wait()
-
- thread = _common.CleanupThread(
- cleanup_server, target=_serve, args=(state,))
- thread.start()
+ with state.lock:
+ if state.stage is not _ServerStage.STOPPED:
+ raise ValueError('Cannot start already-started server!')
+ state.server.start()
+ state.stage = _ServerStage.STARTED
+ _request_call(state)
+
+ def cleanup_server(timeout):
+ if timeout is None:
+ _stop(state, _UNEXPECTED_EXIT_SERVER_GRACE).wait()
+ else:
+ _stop(state, timeout).wait()
+
+ thread = _common.CleanupThread(
+ cleanup_server, target=_serve, args=(state,))
+ thread.start()
+
class Server(grpc.Server):
- def __init__(self, thread_pool, generic_handlers, options):
- completion_queue = cygrpc.CompletionQueue()
- server = cygrpc.Server(_common.channel_args(options))
- server.register_completion_queue(completion_queue)
- self._state = _ServerState(
- completion_queue, server, generic_handlers, thread_pool)
+ def __init__(self, thread_pool, generic_handlers, options):
+ completion_queue = cygrpc.CompletionQueue()
+ server = cygrpc.Server(_common.channel_args(options))
+ server.register_completion_queue(completion_queue)
+ self._state = _ServerState(completion_queue, server, generic_handlers,
+ thread_pool)
- def add_generic_rpc_handlers(self, generic_rpc_handlers):
- _add_generic_handlers(self._state, generic_rpc_handlers)
+ def add_generic_rpc_handlers(self, generic_rpc_handlers):
+ _add_generic_handlers(self._state, generic_rpc_handlers)
- def add_insecure_port(self, address):
- return _add_insecure_port(self._state, _common.encode(address))
+ def add_insecure_port(self, address):
+ return _add_insecure_port(self._state, _common.encode(address))
- def add_secure_port(self, address, server_credentials):
- return _add_secure_port(self._state, _common.encode(address), server_credentials)
+ def add_secure_port(self, address, server_credentials):
+ return _add_secure_port(self._state,
+ _common.encode(address), server_credentials)
- def start(self):
- _start(self._state)
+ def start(self):
+ _start(self._state)
- def stop(self, grace):
- return _stop(self._state, grace)
+ def stop(self, grace):
+ return _stop(self._state, grace)
- def __del__(self):
- _stop(self._state, None)
+ def __del__(self):
+ _stop(self._state, None)
diff --git a/src/python/grpcio/grpc/_utilities.py b/src/python/grpcio/grpc/_utilities.py
index a375896e6e..7c602eb37e 100644
--- a/src/python/grpcio/grpc/_utilities.py
+++ b/src/python/grpcio/grpc/_utilities.py
@@ -26,7 +26,6 @@
# 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.
-
"""Internal utilities for gRPC Python."""
import collections
@@ -44,132 +43,136 @@ _DONE_CALLBACK_EXCEPTION_LOG_MESSAGE = (
class RpcMethodHandler(
- collections.namedtuple(
- '_RpcMethodHandler',
- ('request_streaming', 'response_streaming', 'request_deserializer',
- 'response_serializer', 'unary_unary', 'unary_stream', 'stream_unary',
- 'stream_stream',)),
- grpc.RpcMethodHandler):
- pass
+ collections.namedtuple('_RpcMethodHandler', (
+ 'request_streaming',
+ 'response_streaming',
+ 'request_deserializer',
+ 'response_serializer',
+ 'unary_unary',
+ 'unary_stream',
+ 'stream_unary',
+ 'stream_stream',)), grpc.RpcMethodHandler):
+ pass
class DictionaryGenericHandler(grpc.ServiceRpcHandler):
- def __init__(self, service, method_handlers):
- self._name = service
- self._method_handlers = {
- _common.fully_qualified_method(service, method): method_handler
- for method, method_handler in six.iteritems(method_handlers)}
+ def __init__(self, service, method_handlers):
+ self._name = service
+ self._method_handlers = {
+ _common.fully_qualified_method(service, method): method_handler
+ for method, method_handler in six.iteritems(method_handlers)
+ }
- def service_name(self):
- return self._name
+ def service_name(self):
+ return self._name
- def service(self, handler_call_details):
- return self._method_handlers.get(handler_call_details.method)
+ def service(self, handler_call_details):
+ return self._method_handlers.get(handler_call_details.method)
class _ChannelReadyFuture(grpc.Future):
- def __init__(self, channel):
- self._condition = threading.Condition()
- self._channel = channel
-
- self._matured = False
- self._cancelled = False
- self._done_callbacks = []
-
- def _block(self, timeout):
- until = None if timeout is None else time.time() + timeout
- with self._condition:
- while True:
- if self._cancelled:
- raise grpc.FutureCancelledError()
- elif self._matured:
- return
- else:
- if until is None:
- self._condition.wait()
- else:
- remaining = until - time.time()
- if remaining < 0:
- raise grpc.FutureTimeoutError()
+ def __init__(self, channel):
+ self._condition = threading.Condition()
+ self._channel = channel
+
+ self._matured = False
+ self._cancelled = False
+ self._done_callbacks = []
+
+ def _block(self, timeout):
+ until = None if timeout is None else time.time() + timeout
+ with self._condition:
+ while True:
+ if self._cancelled:
+ raise grpc.FutureCancelledError()
+ elif self._matured:
+ return
+ else:
+ if until is None:
+ self._condition.wait()
+ else:
+ remaining = until - time.time()
+ if remaining < 0:
+ raise grpc.FutureTimeoutError()
+ else:
+ self._condition.wait(timeout=remaining)
+
+ def _update(self, connectivity):
+ with self._condition:
+ if (not self._cancelled and
+ connectivity is grpc.ChannelConnectivity.READY):
+ self._matured = True
+ self._channel.unsubscribe(self._update)
+ self._condition.notify_all()
+ done_callbacks = tuple(self._done_callbacks)
+ self._done_callbacks = None
+ else:
+ return
+
+ for done_callback in done_callbacks:
+ callable_util.call_logging_exceptions(
+ done_callback, _DONE_CALLBACK_EXCEPTION_LOG_MESSAGE, self)
+
+ def cancel(self):
+ with self._condition:
+ if not self._matured:
+ self._cancelled = True
+ self._channel.unsubscribe(self._update)
+ self._condition.notify_all()
+ done_callbacks = tuple(self._done_callbacks)
+ self._done_callbacks = None
else:
- self._condition.wait(timeout=remaining)
-
- def _update(self, connectivity):
- with self._condition:
- if (not self._cancelled and
- connectivity is grpc.ChannelConnectivity.READY):
- self._matured = True
- self._channel.unsubscribe(self._update)
- self._condition.notify_all()
- done_callbacks = tuple(self._done_callbacks)
- self._done_callbacks = None
- else:
- return
-
- for done_callback in done_callbacks:
- callable_util.call_logging_exceptions(
- done_callback, _DONE_CALLBACK_EXCEPTION_LOG_MESSAGE, self)
-
- def cancel(self):
- with self._condition:
- if not self._matured:
- self._cancelled = True
- self._channel.unsubscribe(self._update)
- self._condition.notify_all()
- done_callbacks = tuple(self._done_callbacks)
- self._done_callbacks = None
- else:
- return False
-
- for done_callback in done_callbacks:
- callable_util.call_logging_exceptions(
- done_callback, _DONE_CALLBACK_EXCEPTION_LOG_MESSAGE, self)
-
- def cancelled(self):
- with self._condition:
- return self._cancelled
-
- def running(self):
- with self._condition:
- return not self._cancelled and not self._matured
-
- def done(self):
- with self._condition:
- return self._cancelled or self._matured
-
- def result(self, timeout=None):
- self._block(timeout)
- return None
-
- def exception(self, timeout=None):
- self._block(timeout)
- return None
-
- def traceback(self, timeout=None):
- self._block(timeout)
- return None
-
- def add_done_callback(self, fn):
- with self._condition:
- if not self._cancelled and not self._matured:
- self._done_callbacks.append(fn)
- return
-
- fn(self)
-
- def start(self):
- with self._condition:
- self._channel.subscribe(self._update, try_to_connect=True)
-
- def __del__(self):
- with self._condition:
- if not self._cancelled and not self._matured:
- self._channel.unsubscribe(self._update)
+ return False
+
+ for done_callback in done_callbacks:
+ callable_util.call_logging_exceptions(
+ done_callback, _DONE_CALLBACK_EXCEPTION_LOG_MESSAGE, self)
+
+ def cancelled(self):
+ with self._condition:
+ return self._cancelled
+
+ def running(self):
+ with self._condition:
+ return not self._cancelled and not self._matured
+
+ def done(self):
+ with self._condition:
+ return self._cancelled or self._matured
+
+ def result(self, timeout=None):
+ self._block(timeout)
+ return None
+
+ def exception(self, timeout=None):
+ self._block(timeout)
+ return None
+
+ def traceback(self, timeout=None):
+ self._block(timeout)
+ return None
+
+ def add_done_callback(self, fn):
+ with self._condition:
+ if not self._cancelled and not self._matured:
+ self._done_callbacks.append(fn)
+ return
+
+ fn(self)
+
+ def start(self):
+ with self._condition:
+ self._channel.subscribe(self._update, try_to_connect=True)
+
+ def __del__(self):
+ with self._condition:
+ if not self._cancelled and not self._matured:
+ self._channel.unsubscribe(self._update)
def channel_ready_future(channel):
- ready_future = _ChannelReadyFuture(channel)
- ready_future.start()
- return ready_future
+ ready_future = _ChannelReadyFuture(channel)
+ ready_future.start()
+ return ready_future
diff --git a/src/python/grpcio/grpc/beta/_client_adaptations.py b/src/python/grpcio/grpc/beta/_client_adaptations.py
index e4ee44d7a3..e5b28e9408 100644
--- a/src/python/grpcio/grpc/beta/_client_adaptations.py
+++ b/src/python/grpcio/grpc/beta/_client_adaptations.py
@@ -26,7 +26,6 @@
# 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.
-
"""Translates gRPC's client-side API into gRPC's client-side Beta API."""
import grpc
@@ -38,531 +37,654 @@ from grpc.framework.foundation import future
from grpc.framework.interfaces.face import face
_STATUS_CODE_TO_ABORTION_KIND_AND_ABORTION_ERROR_CLASS = {
- grpc.StatusCode.CANCELLED: (
- face.Abortion.Kind.CANCELLED, face.CancellationError),
- grpc.StatusCode.UNKNOWN: (
- face.Abortion.Kind.REMOTE_FAILURE, face.RemoteError),
- grpc.StatusCode.DEADLINE_EXCEEDED: (
- face.Abortion.Kind.EXPIRED, face.ExpirationError),
- grpc.StatusCode.UNIMPLEMENTED: (
- face.Abortion.Kind.LOCAL_FAILURE, face.LocalError),
+ grpc.StatusCode.CANCELLED: (face.Abortion.Kind.CANCELLED,
+ face.CancellationError),
+ grpc.StatusCode.UNKNOWN: (face.Abortion.Kind.REMOTE_FAILURE,
+ face.RemoteError),
+ grpc.StatusCode.DEADLINE_EXCEEDED: (face.Abortion.Kind.EXPIRED,
+ face.ExpirationError),
+ grpc.StatusCode.UNIMPLEMENTED: (face.Abortion.Kind.LOCAL_FAILURE,
+ face.LocalError),
}
def _effective_metadata(metadata, metadata_transformer):
- non_none_metadata = () if metadata is None else metadata
- if metadata_transformer is None:
- return non_none_metadata
- else:
- return metadata_transformer(non_none_metadata)
+ non_none_metadata = () if metadata is None else metadata
+ if metadata_transformer is None:
+ return non_none_metadata
+ else:
+ return metadata_transformer(non_none_metadata)
def _credentials(grpc_call_options):
- return None if grpc_call_options is None else grpc_call_options.credentials
+ return None if grpc_call_options is None else grpc_call_options.credentials
def _abortion(rpc_error_call):
- code = rpc_error_call.code()
- pair = _STATUS_CODE_TO_ABORTION_KIND_AND_ABORTION_ERROR_CLASS.get(code)
- error_kind = face.Abortion.Kind.LOCAL_FAILURE if pair is None else pair[0]
- return face.Abortion(
- error_kind, rpc_error_call.initial_metadata(),
- rpc_error_call.trailing_metadata(), code, rpc_error_call.details())
+ code = rpc_error_call.code()
+ pair = _STATUS_CODE_TO_ABORTION_KIND_AND_ABORTION_ERROR_CLASS.get(code)
+ error_kind = face.Abortion.Kind.LOCAL_FAILURE if pair is None else pair[0]
+ return face.Abortion(error_kind,
+ rpc_error_call.initial_metadata(),
+ rpc_error_call.trailing_metadata(), code,
+ rpc_error_call.details())
def _abortion_error(rpc_error_call):
- code = rpc_error_call.code()
- pair = _STATUS_CODE_TO_ABORTION_KIND_AND_ABORTION_ERROR_CLASS.get(code)
- exception_class = face.AbortionError if pair is None else pair[1]
- return exception_class(
- rpc_error_call.initial_metadata(), rpc_error_call.trailing_metadata(),
- code, rpc_error_call.details())
+ code = rpc_error_call.code()
+ pair = _STATUS_CODE_TO_ABORTION_KIND_AND_ABORTION_ERROR_CLASS.get(code)
+ exception_class = face.AbortionError if pair is None else pair[1]
+ return exception_class(rpc_error_call.initial_metadata(),
+ rpc_error_call.trailing_metadata(), code,
+ rpc_error_call.details())
class _InvocationProtocolContext(interfaces.GRPCInvocationContext):
- def disable_next_request_compression(self):
- pass # TODO(https://github.com/grpc/grpc/issues/4078): design, implement.
+ def disable_next_request_compression(self):
+ pass # TODO(https://github.com/grpc/grpc/issues/4078): design, implement.
class _Rendezvous(future.Future, face.Call):
- def __init__(self, response_future, response_iterator, call):
- self._future = response_future
- self._iterator = response_iterator
- self._call = call
+ def __init__(self, response_future, response_iterator, call):
+ self._future = response_future
+ self._iterator = response_iterator
+ self._call = call
- def cancel(self):
- return self._call.cancel()
+ def cancel(self):
+ return self._call.cancel()
- def cancelled(self):
- return self._future.cancelled()
+ def cancelled(self):
+ return self._future.cancelled()
- def running(self):
- return self._future.running()
+ def running(self):
+ return self._future.running()
- def done(self):
- return self._future.done()
+ def done(self):
+ return self._future.done()
- def result(self, timeout=None):
- try:
- return self._future.result(timeout=timeout)
- except grpc.RpcError as rpc_error_call:
- raise _abortion_error(rpc_error_call)
- except grpc.FutureTimeoutError:
- raise future.TimeoutError()
- except grpc.FutureCancelledError:
- raise future.CancelledError()
+ def result(self, timeout=None):
+ try:
+ return self._future.result(timeout=timeout)
+ except grpc.RpcError as rpc_error_call:
+ raise _abortion_error(rpc_error_call)
+ except grpc.FutureTimeoutError:
+ raise future.TimeoutError()
+ except grpc.FutureCancelledError:
+ raise future.CancelledError()
- def exception(self, timeout=None):
- try:
- rpc_error_call = self._future.exception(timeout=timeout)
- if rpc_error_call is None:
- return None
- else:
- return _abortion_error(rpc_error_call)
- except grpc.FutureTimeoutError:
- raise future.TimeoutError()
- except grpc.FutureCancelledError:
- raise future.CancelledError()
-
- def traceback(self, timeout=None):
- try:
- return self._future.traceback(timeout=timeout)
- except grpc.FutureTimeoutError:
- raise future.TimeoutError()
- except grpc.FutureCancelledError:
- raise future.CancelledError()
+ def exception(self, timeout=None):
+ try:
+ rpc_error_call = self._future.exception(timeout=timeout)
+ if rpc_error_call is None:
+ return None
+ else:
+ return _abortion_error(rpc_error_call)
+ except grpc.FutureTimeoutError:
+ raise future.TimeoutError()
+ except grpc.FutureCancelledError:
+ raise future.CancelledError()
- def add_done_callback(self, fn):
- self._future.add_done_callback(lambda ignored_callback: fn(self))
+ def traceback(self, timeout=None):
+ try:
+ return self._future.traceback(timeout=timeout)
+ except grpc.FutureTimeoutError:
+ raise future.TimeoutError()
+ except grpc.FutureCancelledError:
+ raise future.CancelledError()
- def __iter__(self):
- return self
+ def add_done_callback(self, fn):
+ self._future.add_done_callback(lambda ignored_callback: fn(self))
- def _next(self):
- try:
- return next(self._iterator)
- except grpc.RpcError as rpc_error_call:
- raise _abortion_error(rpc_error_call)
+ def __iter__(self):
+ return self
+
+ def _next(self):
+ try:
+ return next(self._iterator)
+ except grpc.RpcError as rpc_error_call:
+ raise _abortion_error(rpc_error_call)
+
+ def __next__(self):
+ return self._next()
- def __next__(self):
- return self._next()
+ def next(self):
+ return self._next()
- def next(self):
- return self._next()
+ def is_active(self):
+ return self._call.is_active()
- def is_active(self):
- return self._call.is_active()
+ def time_remaining(self):
+ return self._call.time_remaining()
- def time_remaining(self):
- return self._call.time_remaining()
+ def add_abortion_callback(self, abortion_callback):
- def add_abortion_callback(self, abortion_callback):
- def done_callback():
- if self.code() is not grpc.StatusCode.OK:
- abortion_callback(_abortion(self._call))
- registered = self._call.add_callback(done_callback)
- return None if registered else done_callback()
+ def done_callback():
+ if self.code() is not grpc.StatusCode.OK:
+ abortion_callback(_abortion(self._call))
- def protocol_context(self):
- return _InvocationProtocolContext()
+ registered = self._call.add_callback(done_callback)
+ return None if registered else done_callback()
- def initial_metadata(self):
- return self._call.initial_metadata()
+ def protocol_context(self):
+ return _InvocationProtocolContext()
- def terminal_metadata(self):
- return self._call.terminal_metadata()
+ def initial_metadata(self):
+ return self._call.initial_metadata()
- def code(self):
- return self._call.code()
+ def terminal_metadata(self):
+ return self._call.terminal_metadata()
- def details(self):
- return self._call.details()
+ def code(self):
+ return self._call.code()
+ def details(self):
+ return self._call.details()
-def _blocking_unary_unary(
- channel, group, method, timeout, with_call, protocol_options, metadata,
- metadata_transformer, request, request_serializer, response_deserializer):
- try:
+
+def _blocking_unary_unary(channel, group, method, timeout, with_call,
+ protocol_options, metadata, metadata_transformer,
+ request, request_serializer, response_deserializer):
+ try:
+ multi_callable = channel.unary_unary(
+ _common.fully_qualified_method(group, method),
+ request_serializer=request_serializer,
+ response_deserializer=response_deserializer)
+ effective_metadata = _effective_metadata(metadata, metadata_transformer)
+ if with_call:
+ response, call = multi_callable.with_call(
+ request,
+ timeout=timeout,
+ metadata=effective_metadata,
+ credentials=_credentials(protocol_options))
+ return response, _Rendezvous(None, None, call)
+ else:
+ return multi_callable(
+ request,
+ timeout=timeout,
+ metadata=effective_metadata,
+ credentials=_credentials(protocol_options))
+ except grpc.RpcError as rpc_error_call:
+ raise _abortion_error(rpc_error_call)
+
+
+def _future_unary_unary(channel, group, method, timeout, protocol_options,
+ metadata, metadata_transformer, request,
+ request_serializer, response_deserializer):
multi_callable = channel.unary_unary(
_common.fully_qualified_method(group, method),
request_serializer=request_serializer,
response_deserializer=response_deserializer)
effective_metadata = _effective_metadata(metadata, metadata_transformer)
- if with_call:
- response, call = multi_callable.with_call(
- request, timeout=timeout, metadata=effective_metadata,
- credentials=_credentials(protocol_options))
- return response, _Rendezvous(None, None, call)
- else:
- return multi_callable(
- request, timeout=timeout, metadata=effective_metadata,
- credentials=_credentials(protocol_options))
- except grpc.RpcError as rpc_error_call:
- raise _abortion_error(rpc_error_call)
-
-
-def _future_unary_unary(
- channel, group, method, timeout, protocol_options, metadata,
- metadata_transformer, request, request_serializer, response_deserializer):
- multi_callable = channel.unary_unary(
- _common.fully_qualified_method(group, method),
- request_serializer=request_serializer,
- response_deserializer=response_deserializer)
- effective_metadata = _effective_metadata(metadata, metadata_transformer)
- response_future = multi_callable.future(
- request, timeout=timeout, metadata=effective_metadata,
- credentials=_credentials(protocol_options))
- return _Rendezvous(response_future, None, response_future)
-
-
-def _unary_stream(
- channel, group, method, timeout, protocol_options, metadata,
- metadata_transformer, request, request_serializer, response_deserializer):
- multi_callable = channel.unary_stream(
- _common.fully_qualified_method(group, method),
- request_serializer=request_serializer,
- response_deserializer=response_deserializer)
- effective_metadata = _effective_metadata(metadata, metadata_transformer)
- response_iterator = multi_callable(
- request, timeout=timeout, metadata=effective_metadata,
- credentials=_credentials(protocol_options))
- return _Rendezvous(None, response_iterator, response_iterator)
-
-
-def _blocking_stream_unary(
- channel, group, method, timeout, with_call, protocol_options, metadata,
- metadata_transformer, request_iterator, request_serializer,
- response_deserializer):
- try:
+ response_future = multi_callable.future(
+ request,
+ timeout=timeout,
+ metadata=effective_metadata,
+ credentials=_credentials(protocol_options))
+ return _Rendezvous(response_future, None, response_future)
+
+
+def _unary_stream(channel, group, method, timeout, protocol_options, metadata,
+ metadata_transformer, request, request_serializer,
+ response_deserializer):
+ multi_callable = channel.unary_stream(
+ _common.fully_qualified_method(group, method),
+ request_serializer=request_serializer,
+ response_deserializer=response_deserializer)
+ effective_metadata = _effective_metadata(metadata, metadata_transformer)
+ response_iterator = multi_callable(
+ request,
+ timeout=timeout,
+ metadata=effective_metadata,
+ credentials=_credentials(protocol_options))
+ return _Rendezvous(None, response_iterator, response_iterator)
+
+
+def _blocking_stream_unary(channel, group, method, timeout, with_call,
+ protocol_options, metadata, metadata_transformer,
+ request_iterator, request_serializer,
+ response_deserializer):
+ try:
+ multi_callable = channel.stream_unary(
+ _common.fully_qualified_method(group, method),
+ request_serializer=request_serializer,
+ response_deserializer=response_deserializer)
+ effective_metadata = _effective_metadata(metadata, metadata_transformer)
+ if with_call:
+ response, call = multi_callable.with_call(
+ request_iterator,
+ timeout=timeout,
+ metadata=effective_metadata,
+ credentials=_credentials(protocol_options))
+ return response, _Rendezvous(None, None, call)
+ else:
+ return multi_callable(
+ request_iterator,
+ timeout=timeout,
+ metadata=effective_metadata,
+ credentials=_credentials(protocol_options))
+ except grpc.RpcError as rpc_error_call:
+ raise _abortion_error(rpc_error_call)
+
+
+def _future_stream_unary(channel, group, method, timeout, protocol_options,
+ metadata, metadata_transformer, request_iterator,
+ request_serializer, response_deserializer):
multi_callable = channel.stream_unary(
_common.fully_qualified_method(group, method),
request_serializer=request_serializer,
response_deserializer=response_deserializer)
effective_metadata = _effective_metadata(metadata, metadata_transformer)
- if with_call:
- response, call = multi_callable.with_call(
- request_iterator, timeout=timeout, metadata=effective_metadata,
- credentials=_credentials(protocol_options))
- return response, _Rendezvous(None, None, call)
- else:
- return multi_callable(
- request_iterator, timeout=timeout, metadata=effective_metadata,
- credentials=_credentials(protocol_options))
- except grpc.RpcError as rpc_error_call:
- raise _abortion_error(rpc_error_call)
-
-
-def _future_stream_unary(
- channel, group, method, timeout, protocol_options, metadata,
- metadata_transformer, request_iterator, request_serializer,
- response_deserializer):
- multi_callable = channel.stream_unary(
- _common.fully_qualified_method(group, method),
- request_serializer=request_serializer,
- response_deserializer=response_deserializer)
- effective_metadata = _effective_metadata(metadata, metadata_transformer)
- response_future = multi_callable.future(
- request_iterator, timeout=timeout, metadata=effective_metadata,
- credentials=_credentials(protocol_options))
- return _Rendezvous(response_future, None, response_future)
-
-
-def _stream_stream(
- channel, group, method, timeout, protocol_options, metadata,
- metadata_transformer, request_iterator, request_serializer,
- response_deserializer):
- multi_callable = channel.stream_stream(
- _common.fully_qualified_method(group, method),
- request_serializer=request_serializer,
- response_deserializer=response_deserializer)
- effective_metadata = _effective_metadata(metadata, metadata_transformer)
- response_iterator = multi_callable(
- request_iterator, timeout=timeout, metadata=effective_metadata,
- credentials=_credentials(protocol_options))
- return _Rendezvous(None, response_iterator, response_iterator)
+ response_future = multi_callable.future(
+ request_iterator,
+ timeout=timeout,
+ metadata=effective_metadata,
+ credentials=_credentials(protocol_options))
+ return _Rendezvous(response_future, None, response_future)
+
+
+def _stream_stream(channel, group, method, timeout, protocol_options, metadata,
+ metadata_transformer, request_iterator, request_serializer,
+ response_deserializer):
+ multi_callable = channel.stream_stream(
+ _common.fully_qualified_method(group, method),
+ request_serializer=request_serializer,
+ response_deserializer=response_deserializer)
+ effective_metadata = _effective_metadata(metadata, metadata_transformer)
+ response_iterator = multi_callable(
+ request_iterator,
+ timeout=timeout,
+ metadata=effective_metadata,
+ credentials=_credentials(protocol_options))
+ return _Rendezvous(None, response_iterator, response_iterator)
class _UnaryUnaryMultiCallable(face.UnaryUnaryMultiCallable):
- def __init__(
- self, channel, group, method, metadata_transformer, request_serializer,
- response_deserializer):
- self._channel = channel
- self._group = group
- self._method = method
- self._metadata_transformer = metadata_transformer
- self._request_serializer = request_serializer
- self._response_deserializer = response_deserializer
-
- def __call__(
- self, request, timeout, metadata=None, with_call=False,
- protocol_options=None):
- return _blocking_unary_unary(
- self._channel, self._group, self._method, timeout, with_call,
- protocol_options, metadata, self._metadata_transformer, request,
- self._request_serializer, self._response_deserializer)
-
- def future(self, request, timeout, metadata=None, protocol_options=None):
- return _future_unary_unary(
- self._channel, self._group, self._method, timeout, protocol_options,
- metadata, self._metadata_transformer, request, self._request_serializer,
- self._response_deserializer)
-
- def event(
- self, request, receiver, abortion_callback, timeout,
- metadata=None, protocol_options=None):
- raise NotImplementedError()
+ def __init__(self, channel, group, method, metadata_transformer,
+ request_serializer, response_deserializer):
+ self._channel = channel
+ self._group = group
+ self._method = method
+ self._metadata_transformer = metadata_transformer
+ self._request_serializer = request_serializer
+ self._response_deserializer = response_deserializer
+
+ def __call__(self,
+ request,
+ timeout,
+ metadata=None,
+ with_call=False,
+ protocol_options=None):
+ return _blocking_unary_unary(
+ self._channel, self._group, self._method, timeout, with_call,
+ protocol_options, metadata, self._metadata_transformer, request,
+ self._request_serializer, self._response_deserializer)
+
+ def future(self, request, timeout, metadata=None, protocol_options=None):
+ return _future_unary_unary(
+ self._channel, self._group, self._method, timeout, protocol_options,
+ metadata, self._metadata_transformer, request,
+ self._request_serializer, self._response_deserializer)
+
+ def event(self,
+ request,
+ receiver,
+ abortion_callback,
+ timeout,
+ metadata=None,
+ protocol_options=None):
+ raise NotImplementedError()
class _UnaryStreamMultiCallable(face.UnaryStreamMultiCallable):
- def __init__(
- self, channel, group, method, metadata_transformer, request_serializer,
- response_deserializer):
- self._channel = channel
- self._group = group
- self._method = method
- self._metadata_transformer = metadata_transformer
- self._request_serializer = request_serializer
- self._response_deserializer = response_deserializer
-
- def __call__(self, request, timeout, metadata=None, protocol_options=None):
- return _unary_stream(
- self._channel, self._group, self._method, timeout, protocol_options,
- metadata, self._metadata_transformer, request, self._request_serializer,
- self._response_deserializer)
-
- def event(
- self, request, receiver, abortion_callback, timeout,
- metadata=None, protocol_options=None):
- raise NotImplementedError()
+ def __init__(self, channel, group, method, metadata_transformer,
+ request_serializer, response_deserializer):
+ self._channel = channel
+ self._group = group
+ self._method = method
+ self._metadata_transformer = metadata_transformer
+ self._request_serializer = request_serializer
+ self._response_deserializer = response_deserializer
+
+ def __call__(self, request, timeout, metadata=None, protocol_options=None):
+ return _unary_stream(
+ self._channel, self._group, self._method, timeout, protocol_options,
+ metadata, self._metadata_transformer, request,
+ self._request_serializer, self._response_deserializer)
+
+ def event(self,
+ request,
+ receiver,
+ abortion_callback,
+ timeout,
+ metadata=None,
+ protocol_options=None):
+ raise NotImplementedError()
class _StreamUnaryMultiCallable(face.StreamUnaryMultiCallable):
- def __init__(
- self, channel, group, method, metadata_transformer, request_serializer,
- response_deserializer):
- self._channel = channel
- self._group = group
- self._method = method
- self._metadata_transformer = metadata_transformer
- self._request_serializer = request_serializer
- self._response_deserializer = response_deserializer
-
- def __call__(
- self, request_iterator, timeout, metadata=None, with_call=False,
- protocol_options=None):
- return _blocking_stream_unary(
- self._channel, self._group, self._method, timeout, with_call,
- protocol_options, metadata, self._metadata_transformer,
- request_iterator, self._request_serializer, self._response_deserializer)
-
- def future(
- self, request_iterator, timeout, metadata=None, protocol_options=None):
- return _future_stream_unary(
- self._channel, self._group, self._method, timeout, protocol_options,
- metadata, self._metadata_transformer, request_iterator,
- self._request_serializer, self._response_deserializer)
-
- def event(
- self, receiver, abortion_callback, timeout, metadata=None,
- protocol_options=None):
- raise NotImplementedError()
+ def __init__(self, channel, group, method, metadata_transformer,
+ request_serializer, response_deserializer):
+ self._channel = channel
+ self._group = group
+ self._method = method
+ self._metadata_transformer = metadata_transformer
+ self._request_serializer = request_serializer
+ self._response_deserializer = response_deserializer
+
+ def __call__(self,
+ request_iterator,
+ timeout,
+ metadata=None,
+ with_call=False,
+ protocol_options=None):
+ return _blocking_stream_unary(
+ self._channel, self._group, self._method, timeout, with_call,
+ protocol_options, metadata, self._metadata_transformer,
+ request_iterator, self._request_serializer,
+ self._response_deserializer)
+
+ def future(self,
+ request_iterator,
+ timeout,
+ metadata=None,
+ protocol_options=None):
+ return _future_stream_unary(
+ self._channel, self._group, self._method, timeout, protocol_options,
+ metadata, self._metadata_transformer, request_iterator,
+ self._request_serializer, self._response_deserializer)
+
+ def event(self,
+ receiver,
+ abortion_callback,
+ timeout,
+ metadata=None,
+ protocol_options=None):
+ raise NotImplementedError()
class _StreamStreamMultiCallable(face.StreamStreamMultiCallable):
- def __init__(
- self, channel, group, method, metadata_transformer, request_serializer,
- response_deserializer):
- self._channel = channel
- self._group = group
- self._method = method
- self._metadata_transformer = metadata_transformer
- self._request_serializer = request_serializer
- self._response_deserializer = response_deserializer
-
- def __call__(
- self, request_iterator, timeout, metadata=None, protocol_options=None):
- return _stream_stream(
- self._channel, self._group, self._method, timeout, protocol_options,
- metadata, self._metadata_transformer, request_iterator,
- self._request_serializer, self._response_deserializer)
-
- def event(
- self, receiver, abortion_callback, timeout, metadata=None,
- protocol_options=None):
- raise NotImplementedError()
+ def __init__(self, channel, group, method, metadata_transformer,
+ request_serializer, response_deserializer):
+ self._channel = channel
+ self._group = group
+ self._method = method
+ self._metadata_transformer = metadata_transformer
+ self._request_serializer = request_serializer
+ self._response_deserializer = response_deserializer
+
+ def __call__(self,
+ request_iterator,
+ timeout,
+ metadata=None,
+ protocol_options=None):
+ return _stream_stream(
+ self._channel, self._group, self._method, timeout, protocol_options,
+ metadata, self._metadata_transformer, request_iterator,
+ self._request_serializer, self._response_deserializer)
+
+ def event(self,
+ receiver,
+ abortion_callback,
+ timeout,
+ metadata=None,
+ protocol_options=None):
+ raise NotImplementedError()
class _GenericStub(face.GenericStub):
- def __init__(
- self, channel, metadata_transformer, request_serializers,
- response_deserializers):
- self._channel = channel
- self._metadata_transformer = metadata_transformer
- self._request_serializers = request_serializers or {}
- self._response_deserializers = response_deserializers or {}
-
- def blocking_unary_unary(
- self, group, method, request, timeout, metadata=None,
- with_call=None, protocol_options=None):
- request_serializer = self._request_serializers.get((group, method,))
- response_deserializer = self._response_deserializers.get((group, method,))
- return _blocking_unary_unary(
- self._channel, group, method, timeout, with_call, protocol_options,
- metadata, self._metadata_transformer, request, request_serializer,
- response_deserializer)
-
- def future_unary_unary(
- self, group, method, request, timeout, metadata=None,
- protocol_options=None):
- request_serializer = self._request_serializers.get((group, method,))
- response_deserializer = self._response_deserializers.get((group, method,))
- return _future_unary_unary(
- self._channel, group, method, timeout, protocol_options, metadata,
- self._metadata_transformer, request, request_serializer,
- response_deserializer)
-
- def inline_unary_stream(
- self, group, method, request, timeout, metadata=None,
- protocol_options=None):
- request_serializer = self._request_serializers.get((group, method,))
- response_deserializer = self._response_deserializers.get((group, method,))
- return _unary_stream(
- self._channel, group, method, timeout, protocol_options, metadata,
- self._metadata_transformer, request, request_serializer,
- response_deserializer)
-
- def blocking_stream_unary(
- self, group, method, request_iterator, timeout, metadata=None,
- with_call=None, protocol_options=None):
- request_serializer = self._request_serializers.get((group, method,))
- response_deserializer = self._response_deserializers.get((group, method,))
- return _blocking_stream_unary(
- self._channel, group, method, timeout, with_call, protocol_options,
- metadata, self._metadata_transformer, request_iterator,
- request_serializer, response_deserializer)
-
- def future_stream_unary(
- self, group, method, request_iterator, timeout, metadata=None,
- protocol_options=None):
- request_serializer = self._request_serializers.get((group, method,))
- response_deserializer = self._response_deserializers.get((group, method,))
- return _future_stream_unary(
- self._channel, group, method, timeout, protocol_options, metadata,
- self._metadata_transformer, request_iterator, request_serializer,
- response_deserializer)
-
- def inline_stream_stream(
- self, group, method, request_iterator, timeout, metadata=None,
- protocol_options=None):
- request_serializer = self._request_serializers.get((group, method,))
- response_deserializer = self._response_deserializers.get((group, method,))
- return _stream_stream(
- self._channel, group, method, timeout, protocol_options, metadata,
- self._metadata_transformer, request_iterator, request_serializer,
- response_deserializer)
-
- def event_unary_unary(
- self, group, method, request, receiver, abortion_callback, timeout,
- metadata=None, protocol_options=None):
- raise NotImplementedError()
-
- def event_unary_stream(
- self, group, method, request, receiver, abortion_callback, timeout,
- metadata=None, protocol_options=None):
- raise NotImplementedError()
-
- def event_stream_unary(
- self, group, method, receiver, abortion_callback, timeout,
- metadata=None, protocol_options=None):
- raise NotImplementedError()
-
- def event_stream_stream(
- self, group, method, receiver, abortion_callback, timeout,
- metadata=None, protocol_options=None):
- raise NotImplementedError()
-
- def unary_unary(self, group, method):
- request_serializer = self._request_serializers.get((group, method,))
- response_deserializer = self._response_deserializers.get((group, method,))
- return _UnaryUnaryMultiCallable(
- self._channel, group, method, self._metadata_transformer,
- request_serializer, response_deserializer)
-
- def unary_stream(self, group, method):
- request_serializer = self._request_serializers.get((group, method,))
- response_deserializer = self._response_deserializers.get((group, method,))
- return _UnaryStreamMultiCallable(
- self._channel, group, method, self._metadata_transformer,
- request_serializer, response_deserializer)
-
- def stream_unary(self, group, method):
- request_serializer = self._request_serializers.get((group, method,))
- response_deserializer = self._response_deserializers.get((group, method,))
- return _StreamUnaryMultiCallable(
- self._channel, group, method, self._metadata_transformer,
- request_serializer, response_deserializer)
-
- def stream_stream(self, group, method):
- request_serializer = self._request_serializers.get((group, method,))
- response_deserializer = self._response_deserializers.get((group, method,))
- return _StreamStreamMultiCallable(
- self._channel, group, method, self._metadata_transformer,
- request_serializer, response_deserializer)
-
- def __enter__(self):
- return self
-
- def __exit__(self, exc_type, exc_val, exc_tb):
- return False
+ def __init__(self, channel, metadata_transformer, request_serializers,
+ response_deserializers):
+ self._channel = channel
+ self._metadata_transformer = metadata_transformer
+ self._request_serializers = request_serializers or {}
+ self._response_deserializers = response_deserializers or {}
+
+ def blocking_unary_unary(self,
+ group,
+ method,
+ request,
+ timeout,
+ metadata=None,
+ with_call=None,
+ protocol_options=None):
+ request_serializer = self._request_serializers.get((
+ group,
+ method,))
+ response_deserializer = self._response_deserializers.get((
+ group,
+ method,))
+ return _blocking_unary_unary(self._channel, group, method, timeout,
+ with_call, protocol_options, metadata,
+ self._metadata_transformer, request,
+ request_serializer, response_deserializer)
+
+ def future_unary_unary(self,
+ group,
+ method,
+ request,
+ timeout,
+ metadata=None,
+ protocol_options=None):
+ request_serializer = self._request_serializers.get((
+ group,
+ method,))
+ response_deserializer = self._response_deserializers.get((
+ group,
+ method,))
+ return _future_unary_unary(self._channel, group, method, timeout,
+ protocol_options, metadata,
+ self._metadata_transformer, request,
+ request_serializer, response_deserializer)
+
+ def inline_unary_stream(self,
+ group,
+ method,
+ request,
+ timeout,
+ metadata=None,
+ protocol_options=None):
+ request_serializer = self._request_serializers.get((
+ group,
+ method,))
+ response_deserializer = self._response_deserializers.get((
+ group,
+ method,))
+ return _unary_stream(self._channel, group, method, timeout,
+ protocol_options, metadata,
+ self._metadata_transformer, request,
+ request_serializer, response_deserializer)
+
+ def blocking_stream_unary(self,
+ group,
+ method,
+ request_iterator,
+ timeout,
+ metadata=None,
+ with_call=None,
+ protocol_options=None):
+ request_serializer = self._request_serializers.get((
+ group,
+ method,))
+ response_deserializer = self._response_deserializers.get((
+ group,
+ method,))
+ return _blocking_stream_unary(
+ self._channel, group, method, timeout, with_call, protocol_options,
+ metadata, self._metadata_transformer, request_iterator,
+ request_serializer, response_deserializer)
+
+ def future_stream_unary(self,
+ group,
+ method,
+ request_iterator,
+ timeout,
+ metadata=None,
+ protocol_options=None):
+ request_serializer = self._request_serializers.get((
+ group,
+ method,))
+ response_deserializer = self._response_deserializers.get((
+ group,
+ method,))
+ return _future_stream_unary(
+ self._channel, group, method, timeout, protocol_options, metadata,
+ self._metadata_transformer, request_iterator, request_serializer,
+ response_deserializer)
+
+ def inline_stream_stream(self,
+ group,
+ method,
+ request_iterator,
+ timeout,
+ metadata=None,
+ protocol_options=None):
+ request_serializer = self._request_serializers.get((
+ group,
+ method,))
+ response_deserializer = self._response_deserializers.get((
+ group,
+ method,))
+ return _stream_stream(self._channel, group, method, timeout,
+ protocol_options, metadata,
+ self._metadata_transformer, request_iterator,
+ request_serializer, response_deserializer)
+
+ def event_unary_unary(self,
+ group,
+ method,
+ request,
+ receiver,
+ abortion_callback,
+ timeout,
+ metadata=None,
+ protocol_options=None):
+ raise NotImplementedError()
+
+ def event_unary_stream(self,
+ group,
+ method,
+ request,
+ receiver,
+ abortion_callback,
+ timeout,
+ metadata=None,
+ protocol_options=None):
+ raise NotImplementedError()
+
+ def event_stream_unary(self,
+ group,
+ method,
+ receiver,
+ abortion_callback,
+ timeout,
+ metadata=None,
+ protocol_options=None):
+ raise NotImplementedError()
+
+ def event_stream_stream(self,
+ group,
+ method,
+ receiver,
+ abortion_callback,
+ timeout,
+ metadata=None,
+ protocol_options=None):
+ raise NotImplementedError()
+
+ def unary_unary(self, group, method):
+ request_serializer = self._request_serializers.get((
+ group,
+ method,))
+ response_deserializer = self._response_deserializers.get((
+ group,
+ method,))
+ return _UnaryUnaryMultiCallable(
+ self._channel, group, method, self._metadata_transformer,
+ request_serializer, response_deserializer)
+
+ def unary_stream(self, group, method):
+ request_serializer = self._request_serializers.get((
+ group,
+ method,))
+ response_deserializer = self._response_deserializers.get((
+ group,
+ method,))
+ return _UnaryStreamMultiCallable(
+ self._channel, group, method, self._metadata_transformer,
+ request_serializer, response_deserializer)
+
+ def stream_unary(self, group, method):
+ request_serializer = self._request_serializers.get((
+ group,
+ method,))
+ response_deserializer = self._response_deserializers.get((
+ group,
+ method,))
+ return _StreamUnaryMultiCallable(
+ self._channel, group, method, self._metadata_transformer,
+ request_serializer, response_deserializer)
+
+ def stream_stream(self, group, method):
+ request_serializer = self._request_serializers.get((
+ group,
+ method,))
+ response_deserializer = self._response_deserializers.get((
+ group,
+ method,))
+ return _StreamStreamMultiCallable(
+ self._channel, group, method, self._metadata_transformer,
+ request_serializer, response_deserializer)
+
+ def __enter__(self):
+ return self
+
+ def __exit__(self, exc_type, exc_val, exc_tb):
+ return False
class _DynamicStub(face.DynamicStub):
- def __init__(self, generic_stub, group, cardinalities):
- self._generic_stub = generic_stub
- self._group = group
- self._cardinalities = cardinalities
-
- def __getattr__(self, attr):
- method_cardinality = self._cardinalities.get(attr)
- if method_cardinality is cardinality.Cardinality.UNARY_UNARY:
- return self._generic_stub.unary_unary(self._group, attr)
- elif method_cardinality is cardinality.Cardinality.UNARY_STREAM:
- return self._generic_stub.unary_stream(self._group, attr)
- elif method_cardinality is cardinality.Cardinality.STREAM_UNARY:
- return self._generic_stub.stream_unary(self._group, attr)
- elif method_cardinality is cardinality.Cardinality.STREAM_STREAM:
- return self._generic_stub.stream_stream(self._group, attr)
- else:
- raise AttributeError('_DynamicStub object has no attribute "%s"!' % attr)
-
- def __enter__(self):
- return self
-
- def __exit__(self, exc_type, exc_val, exc_tb):
- return False
-
-
-def generic_stub(
- channel, host, metadata_transformer, request_serializers,
- response_deserializers):
- return _GenericStub(
- channel, metadata_transformer, request_serializers,
- response_deserializers)
-
-
-def dynamic_stub(
- channel, service, cardinalities, host, metadata_transformer,
- request_serializers, response_deserializers):
- return _DynamicStub(
- _GenericStub(
- channel, metadata_transformer, request_serializers,
- response_deserializers),
- service, cardinalities)
+ def __init__(self, generic_stub, group, cardinalities):
+ self._generic_stub = generic_stub
+ self._group = group
+ self._cardinalities = cardinalities
+
+ def __getattr__(self, attr):
+ method_cardinality = self._cardinalities.get(attr)
+ if method_cardinality is cardinality.Cardinality.UNARY_UNARY:
+ return self._generic_stub.unary_unary(self._group, attr)
+ elif method_cardinality is cardinality.Cardinality.UNARY_STREAM:
+ return self._generic_stub.unary_stream(self._group, attr)
+ elif method_cardinality is cardinality.Cardinality.STREAM_UNARY:
+ return self._generic_stub.stream_unary(self._group, attr)
+ elif method_cardinality is cardinality.Cardinality.STREAM_STREAM:
+ return self._generic_stub.stream_stream(self._group, attr)
+ else:
+ raise AttributeError('_DynamicStub object has no attribute "%s"!' %
+ attr)
+
+ def __enter__(self):
+ return self
+
+ def __exit__(self, exc_type, exc_val, exc_tb):
+ return False
+
+
+def generic_stub(channel, host, metadata_transformer, request_serializers,
+ response_deserializers):
+ return _GenericStub(channel, metadata_transformer, request_serializers,
+ response_deserializers)
+
+
+def dynamic_stub(channel, service, cardinalities, host, metadata_transformer,
+ request_serializers, response_deserializers):
+ return _DynamicStub(
+ _GenericStub(channel, metadata_transformer, request_serializers,
+ response_deserializers), service, cardinalities)
diff --git a/src/python/grpcio/grpc/beta/_connectivity_channel.py b/src/python/grpcio/grpc/beta/_connectivity_channel.py
index 61674a70ad..39020d2b4e 100644
--- a/src/python/grpcio/grpc/beta/_connectivity_channel.py
+++ b/src/python/grpcio/grpc/beta/_connectivity_channel.py
@@ -26,7 +26,6 @@
# 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.
-
"""Affords a connectivity-state-listenable channel."""
import threading
@@ -41,116 +40,122 @@ _CHANNEL_SUBSCRIPTION_CALLBACK_ERROR_LOG_MESSAGE = (
'Exception calling channel subscription callback!')
_LOW_CONNECTIVITY_STATE_TO_CHANNEL_CONNECTIVITY = {
- state: connectivity for state, connectivity in zip(
- _types.ConnectivityState, interfaces.ChannelConnectivity)
+ state: connectivity
+ for state, connectivity in zip(_types.ConnectivityState,
+ interfaces.ChannelConnectivity)
}
class ConnectivityChannel(object):
- def __init__(self, low_channel):
- self._lock = threading.Lock()
- self._low_channel = low_channel
-
- self._polling = False
- self._connectivity = None
- self._try_to_connect = False
- self._callbacks_and_connectivities = []
- self._delivering = False
-
- def _deliveries(self, connectivity):
- callbacks_needing_update = []
- for callback_and_connectivity in self._callbacks_and_connectivities:
- callback, callback_connectivity = callback_and_connectivity
- if callback_connectivity is not connectivity:
- callbacks_needing_update.append(callback)
- callback_and_connectivity[1] = connectivity
- return callbacks_needing_update
-
- def _deliver(self, initial_connectivity, initial_callbacks):
- connectivity = initial_connectivity
- callbacks = initial_callbacks
- while True:
- for callback in callbacks:
- callable_util.call_logging_exceptions(
- callback, _CHANNEL_SUBSCRIPTION_CALLBACK_ERROR_LOG_MESSAGE,
- connectivity)
- with self._lock:
- callbacks = self._deliveries(self._connectivity)
- if callbacks:
- connectivity = self._connectivity
- else:
- self._delivering = False
- return
-
- def _spawn_delivery(self, connectivity, callbacks):
- delivering_thread = threading.Thread(
- target=self._deliver, args=(connectivity, callbacks,))
- delivering_thread.start()
- self._delivering = True
+ def __init__(self, low_channel):
+ self._lock = threading.Lock()
+ self._low_channel = low_channel
- # TODO(issue 3064): Don't poll.
- def _poll_connectivity(self, low_channel, initial_try_to_connect):
- try_to_connect = initial_try_to_connect
- low_connectivity = low_channel.check_connectivity_state(try_to_connect)
- with self._lock:
- self._connectivity = _LOW_CONNECTIVITY_STATE_TO_CHANNEL_CONNECTIVITY[
- low_connectivity]
- callbacks = tuple(
- callback for callback, unused_but_known_to_be_none_connectivity
- in self._callbacks_and_connectivities)
- for callback_and_connectivity in self._callbacks_and_connectivities:
- callback_and_connectivity[1] = self._connectivity
- if callbacks:
- self._spawn_delivery(self._connectivity, callbacks)
- completion_queue = _low.CompletionQueue()
- while True:
- low_channel.watch_connectivity_state(
- low_connectivity, time.time() + 0.2, completion_queue, None)
- event = completion_queue.next()
- with self._lock:
- if not self._callbacks_and_connectivities and not self._try_to_connect:
- self._polling = False
- self._connectivity = None
- completion_queue.shutdown()
- break
- try_to_connect = self._try_to_connect
+ self._polling = False
+ self._connectivity = None
self._try_to_connect = False
- if event.success or try_to_connect:
+ self._callbacks_and_connectivities = []
+ self._delivering = False
+
+ def _deliveries(self, connectivity):
+ callbacks_needing_update = []
+ for callback_and_connectivity in self._callbacks_and_connectivities:
+ callback, callback_connectivity = callback_and_connectivity
+ if callback_connectivity is not connectivity:
+ callbacks_needing_update.append(callback)
+ callback_and_connectivity[1] = connectivity
+ return callbacks_needing_update
+
+ def _deliver(self, initial_connectivity, initial_callbacks):
+ connectivity = initial_connectivity
+ callbacks = initial_callbacks
+ while True:
+ for callback in callbacks:
+ callable_util.call_logging_exceptions(
+ callback, _CHANNEL_SUBSCRIPTION_CALLBACK_ERROR_LOG_MESSAGE,
+ connectivity)
+ with self._lock:
+ callbacks = self._deliveries(self._connectivity)
+ if callbacks:
+ connectivity = self._connectivity
+ else:
+ self._delivering = False
+ return
+
+ def _spawn_delivery(self, connectivity, callbacks):
+ delivering_thread = threading.Thread(
+ target=self._deliver, args=(
+ connectivity,
+ callbacks,))
+ delivering_thread.start()
+ self._delivering = True
+
+ # TODO(issue 3064): Don't poll.
+ def _poll_connectivity(self, low_channel, initial_try_to_connect):
+ try_to_connect = initial_try_to_connect
low_connectivity = low_channel.check_connectivity_state(try_to_connect)
with self._lock:
- self._connectivity = _LOW_CONNECTIVITY_STATE_TO_CHANNEL_CONNECTIVITY[
- low_connectivity]
- if not self._delivering:
- callbacks = self._deliveries(self._connectivity)
+ self._connectivity = _LOW_CONNECTIVITY_STATE_TO_CHANNEL_CONNECTIVITY[
+ low_connectivity]
+ callbacks = tuple(
+ callback
+ for callback, unused_but_known_to_be_none_connectivity in
+ self._callbacks_and_connectivities)
+ for callback_and_connectivity in self._callbacks_and_connectivities:
+ callback_and_connectivity[1] = self._connectivity
if callbacks:
- self._spawn_delivery(self._connectivity, callbacks)
-
- def subscribe(self, callback, try_to_connect):
- with self._lock:
- if not self._callbacks_and_connectivities and not self._polling:
- polling_thread = threading.Thread(
- target=self._poll_connectivity,
- args=(self._low_channel, bool(try_to_connect)))
- polling_thread.start()
- self._polling = True
- self._callbacks_and_connectivities.append([callback, None])
- elif not self._delivering and self._connectivity is not None:
- self._spawn_delivery(self._connectivity, (callback,))
- self._try_to_connect |= bool(try_to_connect)
- self._callbacks_and_connectivities.append(
- [callback, self._connectivity])
- else:
- self._try_to_connect |= bool(try_to_connect)
- self._callbacks_and_connectivities.append([callback, None])
-
- def unsubscribe(self, callback):
- with self._lock:
- for index, (subscribed_callback, unused_connectivity) in enumerate(
- self._callbacks_and_connectivities):
- if callback == subscribed_callback:
- self._callbacks_and_connectivities.pop(index)
- break
-
- def low_channel(self):
- return self._low_channel
+ self._spawn_delivery(self._connectivity, callbacks)
+ completion_queue = _low.CompletionQueue()
+ while True:
+ low_channel.watch_connectivity_state(low_connectivity,
+ time.time() + 0.2,
+ completion_queue, None)
+ event = completion_queue.next()
+ with self._lock:
+ if not self._callbacks_and_connectivities and not self._try_to_connect:
+ self._polling = False
+ self._connectivity = None
+ completion_queue.shutdown()
+ break
+ try_to_connect = self._try_to_connect
+ self._try_to_connect = False
+ if event.success or try_to_connect:
+ low_connectivity = low_channel.check_connectivity_state(
+ try_to_connect)
+ with self._lock:
+ self._connectivity = _LOW_CONNECTIVITY_STATE_TO_CHANNEL_CONNECTIVITY[
+ low_connectivity]
+ if not self._delivering:
+ callbacks = self._deliveries(self._connectivity)
+ if callbacks:
+ self._spawn_delivery(self._connectivity, callbacks)
+
+ def subscribe(self, callback, try_to_connect):
+ with self._lock:
+ if not self._callbacks_and_connectivities and not self._polling:
+ polling_thread = threading.Thread(
+ target=self._poll_connectivity,
+ args=(self._low_channel, bool(try_to_connect)))
+ polling_thread.start()
+ self._polling = True
+ self._callbacks_and_connectivities.append([callback, None])
+ elif not self._delivering and self._connectivity is not None:
+ self._spawn_delivery(self._connectivity, (callback,))
+ self._try_to_connect |= bool(try_to_connect)
+ self._callbacks_and_connectivities.append(
+ [callback, self._connectivity])
+ else:
+ self._try_to_connect |= bool(try_to_connect)
+ self._callbacks_and_connectivities.append([callback, None])
+
+ def unsubscribe(self, callback):
+ with self._lock:
+ for index, (subscribed_callback, unused_connectivity
+ ) in enumerate(self._callbacks_and_connectivities):
+ if callback == subscribed_callback:
+ self._callbacks_and_connectivities.pop(index)
+ break
+
+ def low_channel(self):
+ return self._low_channel
diff --git a/src/python/grpcio/grpc/beta/_server_adaptations.py b/src/python/grpcio/grpc/beta/_server_adaptations.py
index cca4a1797a..bb7c0960d5 100644
--- a/src/python/grpcio/grpc/beta/_server_adaptations.py
+++ b/src/python/grpcio/grpc/beta/_server_adaptations.py
@@ -26,7 +26,6 @@
# 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.
-
"""Translates gRPC's server-side API into gRPC's server-side Beta API."""
import collections
@@ -47,329 +46,352 @@ _DEFAULT_POOL_SIZE = 8
class _ServerProtocolContext(interfaces.GRPCServicerContext):
- def __init__(self, servicer_context):
- self._servicer_context = servicer_context
+ def __init__(self, servicer_context):
+ self._servicer_context = servicer_context
- def peer(self):
- return self._servicer_context.peer()
+ def peer(self):
+ return self._servicer_context.peer()
- def disable_next_response_compression(self):
- pass # TODO(https://github.com/grpc/grpc/issues/4078): design, implement.
+ def disable_next_response_compression(self):
+ pass # TODO(https://github.com/grpc/grpc/issues/4078): design, implement.
class _FaceServicerContext(face.ServicerContext):
- def __init__(self, servicer_context):
- self._servicer_context = servicer_context
+ def __init__(self, servicer_context):
+ self._servicer_context = servicer_context
- def is_active(self):
- return self._servicer_context.is_active()
+ def is_active(self):
+ return self._servicer_context.is_active()
- def time_remaining(self):
- return self._servicer_context.time_remaining()
+ def time_remaining(self):
+ return self._servicer_context.time_remaining()
- def add_abortion_callback(self, abortion_callback):
- raise NotImplementedError(
- 'add_abortion_callback no longer supported server-side!')
+ def add_abortion_callback(self, abortion_callback):
+ raise NotImplementedError(
+ 'add_abortion_callback no longer supported server-side!')
- def cancel(self):
- self._servicer_context.cancel()
+ def cancel(self):
+ self._servicer_context.cancel()
- def protocol_context(self):
- return _ServerProtocolContext(self._servicer_context)
+ def protocol_context(self):
+ return _ServerProtocolContext(self._servicer_context)
- def invocation_metadata(self):
- return _common.cygrpc_metadata(
- self._servicer_context.invocation_metadata())
+ def invocation_metadata(self):
+ return _common.cygrpc_metadata(
+ self._servicer_context.invocation_metadata())
- def initial_metadata(self, initial_metadata):
- self._servicer_context.send_initial_metadata(initial_metadata)
+ def initial_metadata(self, initial_metadata):
+ self._servicer_context.send_initial_metadata(initial_metadata)
- def terminal_metadata(self, terminal_metadata):
- self._servicer_context.set_terminal_metadata(terminal_metadata)
+ def terminal_metadata(self, terminal_metadata):
+ self._servicer_context.set_terminal_metadata(terminal_metadata)
- def code(self, code):
- self._servicer_context.set_code(code)
+ def code(self, code):
+ self._servicer_context.set_code(code)
- def details(self, details):
- self._servicer_context.set_details(details)
+ def details(self, details):
+ self._servicer_context.set_details(details)
def _adapt_unary_request_inline(unary_request_inline):
- def adaptation(request, servicer_context):
- return unary_request_inline(request, _FaceServicerContext(servicer_context))
- return adaptation
+
+ def adaptation(request, servicer_context):
+ return unary_request_inline(request,
+ _FaceServicerContext(servicer_context))
+
+ return adaptation
def _adapt_stream_request_inline(stream_request_inline):
- def adaptation(request_iterator, servicer_context):
- return stream_request_inline(
- request_iterator, _FaceServicerContext(servicer_context))
- return adaptation
+
+ def adaptation(request_iterator, servicer_context):
+ return stream_request_inline(request_iterator,
+ _FaceServicerContext(servicer_context))
+
+ return adaptation
class _Callback(stream.Consumer):
- def __init__(self):
- self._condition = threading.Condition()
- self._values = []
- self._terminated = False
- self._cancelled = False
-
- def consume(self, value):
- with self._condition:
- self._values.append(value)
- self._condition.notify_all()
-
- def terminate(self):
- with self._condition:
- self._terminated = True
- self._condition.notify_all()
-
- def consume_and_terminate(self, value):
- with self._condition:
- self._values.append(value)
- self._terminated = True
- self._condition.notify_all()
-
- def cancel(self):
- with self._condition:
- self._cancelled = True
- self._condition.notify_all()
-
- def draw_one_value(self):
- with self._condition:
- while True:
- if self._cancelled:
- raise abandonment.Abandoned()
- elif self._values:
- return self._values.pop(0)
- elif self._terminated:
- return None
- else:
- self._condition.wait()
-
- def draw_all_values(self):
- with self._condition:
- while True:
- if self._cancelled:
- raise abandonment.Abandoned()
- elif self._terminated:
- all_values = tuple(self._values)
- self._values = None
- return all_values
- else:
- self._condition.wait()
+ def __init__(self):
+ self._condition = threading.Condition()
+ self._values = []
+ self._terminated = False
+ self._cancelled = False
+
+ def consume(self, value):
+ with self._condition:
+ self._values.append(value)
+ self._condition.notify_all()
+
+ def terminate(self):
+ with self._condition:
+ self._terminated = True
+ self._condition.notify_all()
+
+ def consume_and_terminate(self, value):
+ with self._condition:
+ self._values.append(value)
+ self._terminated = True
+ self._condition.notify_all()
+
+ def cancel(self):
+ with self._condition:
+ self._cancelled = True
+ self._condition.notify_all()
+
+ def draw_one_value(self):
+ with self._condition:
+ while True:
+ if self._cancelled:
+ raise abandonment.Abandoned()
+ elif self._values:
+ return self._values.pop(0)
+ elif self._terminated:
+ return None
+ else:
+ self._condition.wait()
+
+ def draw_all_values(self):
+ with self._condition:
+ while True:
+ if self._cancelled:
+ raise abandonment.Abandoned()
+ elif self._terminated:
+ all_values = tuple(self._values)
+ self._values = None
+ return all_values
+ else:
+ self._condition.wait()
def _run_request_pipe_thread(request_iterator, request_consumer,
servicer_context):
- thread_joined = threading.Event()
- def pipe_requests():
- for request in request_iterator:
- if not servicer_context.is_active() or thread_joined.is_set():
- return
- request_consumer.consume(request)
- if not servicer_context.is_active() or thread_joined.is_set():
- return
- request_consumer.terminate()
+ thread_joined = threading.Event()
+
+ def pipe_requests():
+ for request in request_iterator:
+ if not servicer_context.is_active() or thread_joined.is_set():
+ return
+ request_consumer.consume(request)
+ if not servicer_context.is_active() or thread_joined.is_set():
+ return
+ request_consumer.terminate()
- def stop_request_pipe(timeout):
- thread_joined.set()
+ def stop_request_pipe(timeout):
+ thread_joined.set()
- request_pipe_thread = _common.CleanupThread(
- stop_request_pipe, target=pipe_requests)
- request_pipe_thread.start()
+ request_pipe_thread = _common.CleanupThread(
+ stop_request_pipe, target=pipe_requests)
+ request_pipe_thread.start()
def _adapt_unary_unary_event(unary_unary_event):
- def adaptation(request, servicer_context):
- callback = _Callback()
- if not servicer_context.add_callback(callback.cancel):
- raise abandonment.Abandoned()
- unary_unary_event(
- request, callback.consume_and_terminate,
- _FaceServicerContext(servicer_context))
- return callback.draw_all_values()[0]
- return adaptation
+
+ def adaptation(request, servicer_context):
+ callback = _Callback()
+ if not servicer_context.add_callback(callback.cancel):
+ raise abandonment.Abandoned()
+ unary_unary_event(request, callback.consume_and_terminate,
+ _FaceServicerContext(servicer_context))
+ return callback.draw_all_values()[0]
+
+ return adaptation
def _adapt_unary_stream_event(unary_stream_event):
- def adaptation(request, servicer_context):
- callback = _Callback()
- if not servicer_context.add_callback(callback.cancel):
- raise abandonment.Abandoned()
- unary_stream_event(
- request, callback, _FaceServicerContext(servicer_context))
- while True:
- response = callback.draw_one_value()
- if response is None:
- return
- else:
- yield response
- return adaptation
+
+ def adaptation(request, servicer_context):
+ callback = _Callback()
+ if not servicer_context.add_callback(callback.cancel):
+ raise abandonment.Abandoned()
+ unary_stream_event(request, callback,
+ _FaceServicerContext(servicer_context))
+ while True:
+ response = callback.draw_one_value()
+ if response is None:
+ return
+ else:
+ yield response
+
+ return adaptation
def _adapt_stream_unary_event(stream_unary_event):
- def adaptation(request_iterator, servicer_context):
- callback = _Callback()
- if not servicer_context.add_callback(callback.cancel):
- raise abandonment.Abandoned()
- request_consumer = stream_unary_event(
- callback.consume_and_terminate, _FaceServicerContext(servicer_context))
- _run_request_pipe_thread(
- request_iterator, request_consumer, servicer_context)
- return callback.draw_all_values()[0]
- return adaptation
+
+ def adaptation(request_iterator, servicer_context):
+ callback = _Callback()
+ if not servicer_context.add_callback(callback.cancel):
+ raise abandonment.Abandoned()
+ request_consumer = stream_unary_event(
+ callback.consume_and_terminate,
+ _FaceServicerContext(servicer_context))
+ _run_request_pipe_thread(request_iterator, request_consumer,
+ servicer_context)
+ return callback.draw_all_values()[0]
+
+ return adaptation
def _adapt_stream_stream_event(stream_stream_event):
- def adaptation(request_iterator, servicer_context):
- callback = _Callback()
- if not servicer_context.add_callback(callback.cancel):
- raise abandonment.Abandoned()
- request_consumer = stream_stream_event(
- callback, _FaceServicerContext(servicer_context))
- _run_request_pipe_thread(
- request_iterator, request_consumer, servicer_context)
- while True:
- response = callback.draw_one_value()
- if response is None:
- return
- else:
- yield response
- return adaptation
+
+ def adaptation(request_iterator, servicer_context):
+ callback = _Callback()
+ if not servicer_context.add_callback(callback.cancel):
+ raise abandonment.Abandoned()
+ request_consumer = stream_stream_event(
+ callback, _FaceServicerContext(servicer_context))
+ _run_request_pipe_thread(request_iterator, request_consumer,
+ servicer_context)
+ while True:
+ response = callback.draw_one_value()
+ if response is None:
+ return
+ else:
+ yield response
+
+ return adaptation
class _SimpleMethodHandler(
- collections.namedtuple(
- '_MethodHandler',
- ('request_streaming', 'response_streaming', 'request_deserializer',
- 'response_serializer', 'unary_unary', 'unary_stream', 'stream_unary',
- 'stream_stream',)),
- grpc.RpcMethodHandler):
- pass
-
-
-def _simple_method_handler(
- implementation, request_deserializer, response_serializer):
- if implementation.style is style.Service.INLINE:
- if implementation.cardinality is cardinality.Cardinality.UNARY_UNARY:
- return _SimpleMethodHandler(
- False, False, request_deserializer, response_serializer,
- _adapt_unary_request_inline(implementation.unary_unary_inline), None,
- None, None)
- elif implementation.cardinality is cardinality.Cardinality.UNARY_STREAM:
- return _SimpleMethodHandler(
- False, True, request_deserializer, response_serializer, None,
- _adapt_unary_request_inline(implementation.unary_stream_inline), None,
- None)
- elif implementation.cardinality is cardinality.Cardinality.STREAM_UNARY:
- return _SimpleMethodHandler(
- True, False, request_deserializer, response_serializer, None, None,
- _adapt_stream_request_inline(implementation.stream_unary_inline),
- None)
- elif implementation.cardinality is cardinality.Cardinality.STREAM_STREAM:
- return _SimpleMethodHandler(
- True, True, request_deserializer, response_serializer, None, None,
- None,
- _adapt_stream_request_inline(implementation.stream_stream_inline))
- elif implementation.style is style.Service.EVENT:
- if implementation.cardinality is cardinality.Cardinality.UNARY_UNARY:
- return _SimpleMethodHandler(
- False, False, request_deserializer, response_serializer,
- _adapt_unary_unary_event(implementation.unary_unary_event), None,
- None, None)
- elif implementation.cardinality is cardinality.Cardinality.UNARY_STREAM:
- return _SimpleMethodHandler(
- False, True, request_deserializer, response_serializer, None,
- _adapt_unary_stream_event(implementation.unary_stream_event), None,
- None)
- elif implementation.cardinality is cardinality.Cardinality.STREAM_UNARY:
- return _SimpleMethodHandler(
- True, False, request_deserializer, response_serializer, None, None,
- _adapt_stream_unary_event(implementation.stream_unary_event), None)
- elif implementation.cardinality is cardinality.Cardinality.STREAM_STREAM:
- return _SimpleMethodHandler(
- True, True, request_deserializer, response_serializer, None, None,
- None, _adapt_stream_stream_event(implementation.stream_stream_event))
+ collections.namedtuple('_MethodHandler', (
+ 'request_streaming',
+ 'response_streaming',
+ 'request_deserializer',
+ 'response_serializer',
+ 'unary_unary',
+ 'unary_stream',
+ 'stream_unary',
+ 'stream_stream',)), grpc.RpcMethodHandler):
+ pass
+
+
+def _simple_method_handler(implementation, request_deserializer,
+ response_serializer):
+ if implementation.style is style.Service.INLINE:
+ if implementation.cardinality is cardinality.Cardinality.UNARY_UNARY:
+ return _SimpleMethodHandler(
+ False, False, request_deserializer, response_serializer,
+ _adapt_unary_request_inline(implementation.unary_unary_inline),
+ None, None, None)
+ elif implementation.cardinality is cardinality.Cardinality.UNARY_STREAM:
+ return _SimpleMethodHandler(
+ False, True, request_deserializer, response_serializer, None,
+ _adapt_unary_request_inline(implementation.unary_stream_inline),
+ None, None)
+ elif implementation.cardinality is cardinality.Cardinality.STREAM_UNARY:
+ return _SimpleMethodHandler(True, False, request_deserializer,
+ response_serializer, None, None,
+ _adapt_stream_request_inline(
+ implementation.stream_unary_inline),
+ None)
+ elif implementation.cardinality is cardinality.Cardinality.STREAM_STREAM:
+ return _SimpleMethodHandler(
+ True, True, request_deserializer, response_serializer, None,
+ None, None,
+ _adapt_stream_request_inline(
+ implementation.stream_stream_inline))
+ elif implementation.style is style.Service.EVENT:
+ if implementation.cardinality is cardinality.Cardinality.UNARY_UNARY:
+ return _SimpleMethodHandler(
+ False, False, request_deserializer, response_serializer,
+ _adapt_unary_unary_event(implementation.unary_unary_event),
+ None, None, None)
+ elif implementation.cardinality is cardinality.Cardinality.UNARY_STREAM:
+ return _SimpleMethodHandler(
+ False, True, request_deserializer, response_serializer, None,
+ _adapt_unary_stream_event(implementation.unary_stream_event),
+ None, None)
+ elif implementation.cardinality is cardinality.Cardinality.STREAM_UNARY:
+ return _SimpleMethodHandler(
+ True, False, request_deserializer, response_serializer, None,
+ None,
+ _adapt_stream_unary_event(implementation.stream_unary_event),
+ None)
+ elif implementation.cardinality is cardinality.Cardinality.STREAM_STREAM:
+ return _SimpleMethodHandler(
+ True, True, request_deserializer, response_serializer, None,
+ None, None,
+ _adapt_stream_stream_event(implementation.stream_stream_event))
def _flatten_method_pair_map(method_pair_map):
- method_pair_map = method_pair_map or {}
- flat_map = {}
- for method_pair in method_pair_map:
- method = _common.fully_qualified_method(method_pair[0], method_pair[1])
- flat_map[method] = method_pair_map[method_pair]
- return flat_map
+ method_pair_map = method_pair_map or {}
+ flat_map = {}
+ for method_pair in method_pair_map:
+ method = _common.fully_qualified_method(method_pair[0], method_pair[1])
+ flat_map[method] = method_pair_map[method_pair]
+ return flat_map
class _GenericRpcHandler(grpc.GenericRpcHandler):
- def __init__(
- self, method_implementations, multi_method_implementation,
- request_deserializers, response_serializers):
- self._method_implementations = _flatten_method_pair_map(
- method_implementations)
- self._request_deserializers = _flatten_method_pair_map(
- request_deserializers)
- self._response_serializers = _flatten_method_pair_map(
- response_serializers)
- self._multi_method_implementation = multi_method_implementation
-
- def service(self, handler_call_details):
- method_implementation = self._method_implementations.get(
- handler_call_details.method)
- if method_implementation is not None:
- return _simple_method_handler(
- method_implementation,
- self._request_deserializers.get(handler_call_details.method),
- self._response_serializers.get(handler_call_details.method))
- elif self._multi_method_implementation is None:
- return None
- else:
- try:
- return None #TODO(nathaniel): call the multimethod.
- except face.NoSuchMethodError:
- return None
+ def __init__(self, method_implementations, multi_method_implementation,
+ request_deserializers, response_serializers):
+ self._method_implementations = _flatten_method_pair_map(
+ method_implementations)
+ self._request_deserializers = _flatten_method_pair_map(
+ request_deserializers)
+ self._response_serializers = _flatten_method_pair_map(
+ response_serializers)
+ self._multi_method_implementation = multi_method_implementation
+
+ def service(self, handler_call_details):
+ method_implementation = self._method_implementations.get(
+ handler_call_details.method)
+ if method_implementation is not None:
+ return _simple_method_handler(
+ method_implementation,
+ self._request_deserializers.get(handler_call_details.method),
+ self._response_serializers.get(handler_call_details.method))
+ elif self._multi_method_implementation is None:
+ return None
+ else:
+ try:
+ return None #TODO(nathaniel): call the multimethod.
+ except face.NoSuchMethodError:
+ return None
class _Server(interfaces.Server):
- def __init__(self, server):
- self._server = server
+ def __init__(self, server):
+ self._server = server
- def add_insecure_port(self, address):
- return self._server.add_insecure_port(address)
+ def add_insecure_port(self, address):
+ return self._server.add_insecure_port(address)
- def add_secure_port(self, address, server_credentials):
- return self._server.add_secure_port(address, server_credentials)
+ def add_secure_port(self, address, server_credentials):
+ return self._server.add_secure_port(address, server_credentials)
- def start(self):
- self._server.start()
+ def start(self):
+ self._server.start()
- def stop(self, grace):
- return self._server.stop(grace)
+ def stop(self, grace):
+ return self._server.stop(grace)
- def __enter__(self):
- self._server.start()
- return self
+ def __enter__(self):
+ self._server.start()
+ return self
- def __exit__(self, exc_type, exc_val, exc_tb):
- self._server.stop(None)
- return False
+ def __exit__(self, exc_type, exc_val, exc_tb):
+ self._server.stop(None)
+ return False
-def server(
- service_implementations, multi_method_implementation, request_deserializers,
- response_serializers, thread_pool, thread_pool_size):
- generic_rpc_handler = _GenericRpcHandler(
- service_implementations, multi_method_implementation,
- request_deserializers, response_serializers)
- if thread_pool is None:
- effective_thread_pool = logging_pool.pool(
- _DEFAULT_POOL_SIZE if thread_pool_size is None else thread_pool_size)
- else:
- effective_thread_pool = thread_pool
- return _Server(
- grpc.server(effective_thread_pool, handlers=(generic_rpc_handler,)))
+def server(service_implementations, multi_method_implementation,
+ request_deserializers, response_serializers, thread_pool,
+ thread_pool_size):
+ generic_rpc_handler = _GenericRpcHandler(
+ service_implementations, multi_method_implementation,
+ request_deserializers, response_serializers)
+ if thread_pool is None:
+ effective_thread_pool = logging_pool.pool(_DEFAULT_POOL_SIZE
+ if thread_pool_size is None
+ else thread_pool_size)
+ else:
+ effective_thread_pool = thread_pool
+ return _Server(
+ grpc.server(
+ effective_thread_pool, handlers=(generic_rpc_handler,)))
diff --git a/src/python/grpcio/grpc/beta/implementations.py b/src/python/grpcio/grpc/beta/implementations.py
index ab25fd5eec..7093852278 100644
--- a/src/python/grpcio/grpc/beta/implementations.py
+++ b/src/python/grpcio/grpc/beta/implementations.py
@@ -26,7 +26,6 @@
# 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.
-
"""Entry points into the Beta API of gRPC Python."""
# threading is referenced from specification in this module.
@@ -43,7 +42,6 @@ from grpc.beta import interfaces
from grpc.framework.common import cardinality # pylint: disable=unused-import
from grpc.framework.interfaces.face import face # pylint: disable=unused-import
-
ChannelCredentials = grpc.ChannelCredentials
ssl_channel_credentials = grpc.ssl_channel_credentials
CallCredentials = grpc.CallCredentials
@@ -51,7 +49,7 @@ metadata_call_credentials = grpc.metadata_call_credentials
def google_call_credentials(credentials):
- """Construct CallCredentials from GoogleCredentials.
+ """Construct CallCredentials from GoogleCredentials.
Args:
credentials: A GoogleCredentials object from the oauth2client library.
@@ -59,7 +57,8 @@ def google_call_credentials(credentials):
Returns:
A CallCredentials object for use in a GRPCCallOptions object.
"""
- return metadata_call_credentials(_auth.GoogleCallCredentials(credentials))
+ return metadata_call_credentials(_auth.GoogleCallCredentials(credentials))
+
access_token_call_credentials = grpc.access_token_call_credentials
composite_call_credentials = grpc.composite_call_credentials
@@ -67,18 +66,18 @@ composite_channel_credentials = grpc.composite_channel_credentials
class Channel(object):
- """A channel to a remote host through which RPCs may be conducted.
+ """A channel to a remote host through which RPCs may be conducted.
Only the "subscribe" and "unsubscribe" methods are supported for application
use. This class' instance constructor and all other attributes are
unsupported.
"""
- def __init__(self, channel):
- self._channel = channel
+ def __init__(self, channel):
+ self._channel = channel
- def subscribe(self, callback, try_to_connect=None):
- """Subscribes to this Channel's connectivity.
+ def subscribe(self, callback, try_to_connect=None):
+ """Subscribes to this Channel's connectivity.
Args:
callback: A callable to be invoked and passed an
@@ -90,20 +89,20 @@ class Channel(object):
attempt to connect if it is not already connected and ready to conduct
RPCs.
"""
- self._channel.subscribe(callback, try_to_connect=try_to_connect)
+ self._channel.subscribe(callback, try_to_connect=try_to_connect)
- def unsubscribe(self, callback):
- """Unsubscribes a callback from this Channel's connectivity.
+ def unsubscribe(self, callback):
+ """Unsubscribes a callback from this Channel's connectivity.
Args:
callback: A callable previously registered with this Channel from having
been passed to its "subscribe" method.
"""
- self._channel.unsubscribe(callback)
+ self._channel.unsubscribe(callback)
def insecure_channel(host, port):
- """Creates an insecure Channel to a remote host.
+ """Creates an insecure Channel to a remote host.
Args:
host: The name of the remote host to which to connect.
@@ -113,13 +112,13 @@ def insecure_channel(host, port):
Returns:
A Channel to the remote host through which RPCs may be conducted.
"""
- channel = grpc.insecure_channel(
- host if port is None else '%s:%d' % (host, port))
- return Channel(channel)
+ channel = grpc.insecure_channel(host
+ if port is None else '%s:%d' % (host, port))
+ return Channel(channel)
def secure_channel(host, port, channel_credentials):
- """Creates a secure Channel to a remote host.
+ """Creates a secure Channel to a remote host.
Args:
host: The name of the remote host to which to connect.
@@ -130,37 +129,39 @@ def secure_channel(host, port, channel_credentials):
Returns:
A secure Channel to the remote host through which RPCs may be conducted.
"""
- channel = grpc.secure_channel(
- host if port is None else '%s:%d' % (host, port), channel_credentials)
- return Channel(channel)
+ channel = grpc.secure_channel(host if port is None else
+ '%s:%d' % (host, port), channel_credentials)
+ return Channel(channel)
class StubOptions(object):
- """A value encapsulating the various options for creation of a Stub.
+ """A value encapsulating the various options for creation of a Stub.
This class and its instances have no supported interface - it exists to define
the type of its instances and its instances exist to be passed to other
functions.
"""
- def __init__(
- self, host, request_serializers, response_deserializers,
- metadata_transformer, thread_pool, thread_pool_size):
- self.host = host
- self.request_serializers = request_serializers
- self.response_deserializers = response_deserializers
- self.metadata_transformer = metadata_transformer
- self.thread_pool = thread_pool
- self.thread_pool_size = thread_pool_size
+ def __init__(self, host, request_serializers, response_deserializers,
+ metadata_transformer, thread_pool, thread_pool_size):
+ self.host = host
+ self.request_serializers = request_serializers
+ self.response_deserializers = response_deserializers
+ self.metadata_transformer = metadata_transformer
+ self.thread_pool = thread_pool
+ self.thread_pool_size = thread_pool_size
-_EMPTY_STUB_OPTIONS = StubOptions(
- None, None, None, None, None, None)
+_EMPTY_STUB_OPTIONS = StubOptions(None, None, None, None, None, None)
-def stub_options(
- host=None, request_serializers=None, response_deserializers=None,
- metadata_transformer=None, thread_pool=None, thread_pool_size=None):
- """Creates a StubOptions value to be passed at stub creation.
+
+def stub_options(host=None,
+ request_serializers=None,
+ response_deserializers=None,
+ metadata_transformer=None,
+ thread_pool=None,
+ thread_pool_size=None):
+ """Creates a StubOptions value to be passed at stub creation.
All parameters are optional and should always be passed by keyword.
@@ -180,13 +181,12 @@ def stub_options(
Returns:
A StubOptions value created from the passed parameters.
"""
- return StubOptions(
- host, request_serializers, response_deserializers,
- metadata_transformer, thread_pool, thread_pool_size)
+ return StubOptions(host, request_serializers, response_deserializers,
+ metadata_transformer, thread_pool, thread_pool_size)
def generic_stub(channel, options=None):
- """Creates a face.GenericStub on which RPCs can be made.
+ """Creates a face.GenericStub on which RPCs can be made.
Args:
channel: A Channel for use by the created stub.
@@ -195,16 +195,17 @@ def generic_stub(channel, options=None):
Returns:
A face.GenericStub on which RPCs can be made.
"""
- effective_options = _EMPTY_STUB_OPTIONS if options is None else options
- return _client_adaptations.generic_stub(
- channel._channel, # pylint: disable=protected-access
- effective_options.host, effective_options.metadata_transformer,
- effective_options.request_serializers,
- effective_options.response_deserializers)
+ effective_options = _EMPTY_STUB_OPTIONS if options is None else options
+ return _client_adaptations.generic_stub(
+ channel._channel, # pylint: disable=protected-access
+ effective_options.host,
+ effective_options.metadata_transformer,
+ effective_options.request_serializers,
+ effective_options.response_deserializers)
def dynamic_stub(channel, service, cardinalities, options=None):
- """Creates a face.DynamicStub with which RPCs can be invoked.
+ """Creates a face.DynamicStub with which RPCs can be invoked.
Args:
channel: A Channel for the returned face.DynamicStub to use.
@@ -217,13 +218,15 @@ def dynamic_stub(channel, service, cardinalities, options=None):
Returns:
A face.DynamicStub with which RPCs can be invoked.
"""
- effective_options = StubOptions() if options is None else options
- return _client_adaptations.dynamic_stub(
- channel._channel, # pylint: disable=protected-access
- service, cardinalities, effective_options.host,
- effective_options.metadata_transformer,
- effective_options.request_serializers,
- effective_options.response_deserializers)
+ effective_options = StubOptions() if options is None else options
+ return _client_adaptations.dynamic_stub(
+ channel._channel, # pylint: disable=protected-access
+ service,
+ cardinalities,
+ effective_options.host,
+ effective_options.metadata_transformer,
+ effective_options.request_serializers,
+ effective_options.response_deserializers)
ServerCredentials = grpc.ServerCredentials
@@ -231,34 +234,36 @@ ssl_server_credentials = grpc.ssl_server_credentials
class ServerOptions(object):
- """A value encapsulating the various options for creation of a Server.
+ """A value encapsulating the various options for creation of a Server.
This class and its instances have no supported interface - it exists to define
the type of its instances and its instances exist to be passed to other
functions.
"""
- def __init__(
- self, multi_method_implementation, request_deserializers,
- response_serializers, thread_pool, thread_pool_size, default_timeout,
- maximum_timeout):
- self.multi_method_implementation = multi_method_implementation
- self.request_deserializers = request_deserializers
- self.response_serializers = response_serializers
- self.thread_pool = thread_pool
- self.thread_pool_size = thread_pool_size
- self.default_timeout = default_timeout
- self.maximum_timeout = maximum_timeout
+ def __init__(self, multi_method_implementation, request_deserializers,
+ response_serializers, thread_pool, thread_pool_size,
+ default_timeout, maximum_timeout):
+ self.multi_method_implementation = multi_method_implementation
+ self.request_deserializers = request_deserializers
+ self.response_serializers = response_serializers
+ self.thread_pool = thread_pool
+ self.thread_pool_size = thread_pool_size
+ self.default_timeout = default_timeout
+ self.maximum_timeout = maximum_timeout
+
-_EMPTY_SERVER_OPTIONS = ServerOptions(
- None, None, None, None, None, None, None)
+_EMPTY_SERVER_OPTIONS = ServerOptions(None, None, None, None, None, None, None)
-def server_options(
- multi_method_implementation=None, request_deserializers=None,
- response_serializers=None, thread_pool=None, thread_pool_size=None,
- default_timeout=None, maximum_timeout=None):
- """Creates a ServerOptions value to be passed at server creation.
+def server_options(multi_method_implementation=None,
+ request_deserializers=None,
+ response_serializers=None,
+ thread_pool=None,
+ thread_pool_size=None,
+ default_timeout=None,
+ maximum_timeout=None):
+ """Creates a ServerOptions value to be passed at server creation.
All parameters are optional and should always be passed by keyword.
@@ -282,13 +287,13 @@ def server_options(
Returns:
A StubOptions value created from the passed parameters.
"""
- return ServerOptions(
- multi_method_implementation, request_deserializers, response_serializers,
- thread_pool, thread_pool_size, default_timeout, maximum_timeout)
+ return ServerOptions(multi_method_implementation, request_deserializers,
+ response_serializers, thread_pool, thread_pool_size,
+ default_timeout, maximum_timeout)
def server(service_implementations, options=None):
- """Creates an interfaces.Server with which RPCs can be serviced.
+ """Creates an interfaces.Server with which RPCs can be serviced.
Args:
service_implementations: A dictionary from service name-method name pair to
@@ -299,9 +304,9 @@ def server(service_implementations, options=None):
Returns:
An interfaces.Server with which RPCs can be serviced.
"""
- effective_options = _EMPTY_SERVER_OPTIONS if options is None else options
- return _server_adaptations.server(
- service_implementations, effective_options.multi_method_implementation,
- effective_options.request_deserializers,
- effective_options.response_serializers, effective_options.thread_pool,
- effective_options.thread_pool_size)
+ effective_options = _EMPTY_SERVER_OPTIONS if options is None else options
+ return _server_adaptations.server(
+ service_implementations, effective_options.multi_method_implementation,
+ effective_options.request_deserializers,
+ effective_options.response_serializers, effective_options.thread_pool,
+ effective_options.thread_pool_size)
diff --git a/src/python/grpcio/grpc/beta/interfaces.py b/src/python/grpcio/grpc/beta/interfaces.py
index 90f6bbbfcc..361d1bcffe 100644
--- a/src/python/grpcio/grpc/beta/interfaces.py
+++ b/src/python/grpcio/grpc/beta/interfaces.py
@@ -26,7 +26,6 @@
# 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.
-
"""Constants and interfaces of the Beta API of gRPC Python."""
import abc
@@ -43,21 +42,21 @@ StatusCode = grpc.StatusCode
class GRPCCallOptions(object):
- """A value encapsulating gRPC-specific options passed on RPC invocation.
+ """A value encapsulating gRPC-specific options passed on RPC invocation.
This class and its instances have no supported interface - it exists to
define the type of its instances and its instances exist to be passed to
other functions.
"""
- def __init__(self, disable_compression, subcall_of, credentials):
- self.disable_compression = disable_compression
- self.subcall_of = subcall_of
- self.credentials = credentials
+ def __init__(self, disable_compression, subcall_of, credentials):
+ self.disable_compression = disable_compression
+ self.subcall_of = subcall_of
+ self.credentials = credentials
def grpc_call_options(disable_compression=False, credentials=None):
- """Creates a GRPCCallOptions value to be passed at RPC invocation.
+ """Creates a GRPCCallOptions value to be passed at RPC invocation.
All parameters are optional and should always be passed by keyword.
@@ -67,7 +66,8 @@ def grpc_call_options(disable_compression=False, credentials=None):
request-unary RPCs.
credentials: A CallCredentials object to use for the invoked RPC.
"""
- return GRPCCallOptions(disable_compression, None, credentials)
+ return GRPCCallOptions(disable_compression, None, credentials)
+
GRPCAuthMetadataContext = grpc.AuthMetadataContext
GRPCAuthMetadataPluginCallback = grpc.AuthMetadataPluginCallback
@@ -75,38 +75,38 @@ GRPCAuthMetadataPlugin = grpc.AuthMetadataPlugin
class GRPCServicerContext(six.with_metaclass(abc.ABCMeta)):
- """Exposes gRPC-specific options and behaviors to code servicing RPCs."""
+ """Exposes gRPC-specific options and behaviors to code servicing RPCs."""
- @abc.abstractmethod
- def peer(self):
- """Identifies the peer that invoked the RPC being serviced.
+ @abc.abstractmethod
+ def peer(self):
+ """Identifies the peer that invoked the RPC being serviced.
Returns:
A string identifying the peer that invoked the RPC being serviced.
"""
- raise NotImplementedError()
+ raise NotImplementedError()
- @abc.abstractmethod
- def disable_next_response_compression(self):
- """Disables compression of the next response passed by the application."""
- raise NotImplementedError()
+ @abc.abstractmethod
+ def disable_next_response_compression(self):
+ """Disables compression of the next response passed by the application."""
+ raise NotImplementedError()
class GRPCInvocationContext(six.with_metaclass(abc.ABCMeta)):
- """Exposes gRPC-specific options and behaviors to code invoking RPCs."""
+ """Exposes gRPC-specific options and behaviors to code invoking RPCs."""
- @abc.abstractmethod
- def disable_next_request_compression(self):
- """Disables compression of the next request passed by the application."""
- raise NotImplementedError()
+ @abc.abstractmethod
+ def disable_next_request_compression(self):
+ """Disables compression of the next request passed by the application."""
+ raise NotImplementedError()
class Server(six.with_metaclass(abc.ABCMeta)):
- """Services RPCs."""
+ """Services RPCs."""
- @abc.abstractmethod
- def add_insecure_port(self, address):
- """Reserves a port for insecure RPC service once this Server becomes active.
+ @abc.abstractmethod
+ def add_insecure_port(self, address):
+ """Reserves a port for insecure RPC service once this Server becomes active.
This method may only be called before calling this Server's start method is
called.
@@ -120,11 +120,11 @@ class Server(six.with_metaclass(abc.ABCMeta)):
in the passed address, but will likely be different if the port number
contained in the passed address was zero.
"""
- raise NotImplementedError()
+ raise NotImplementedError()
- @abc.abstractmethod
- def add_secure_port(self, address, server_credentials):
- """Reserves a port for secure RPC service after this Server becomes active.
+ @abc.abstractmethod
+ def add_secure_port(self, address, server_credentials):
+ """Reserves a port for secure RPC service after this Server becomes active.
This method may only be called before calling this Server's start method is
called.
@@ -139,20 +139,20 @@ class Server(six.with_metaclass(abc.ABCMeta)):
in the passed address, but will likely be different if the port number
contained in the passed address was zero.
"""
- raise NotImplementedError()
+ raise NotImplementedError()
- @abc.abstractmethod
- def start(self):
- """Starts this Server's service of RPCs.
+ @abc.abstractmethod
+ def start(self):
+ """Starts this Server's service of RPCs.
This method may only be called while the server is not serving RPCs (i.e. it
is not idempotent).
"""
- raise NotImplementedError()
+ raise NotImplementedError()
- @abc.abstractmethod
- def stop(self, grace):
- """Stops this Server's service of RPCs.
+ @abc.abstractmethod
+ def stop(self, grace):
+ """Stops this Server's service of RPCs.
All calls to this method immediately stop service of new RPCs. When existing
RPCs are aborted is controlled by the grace period parameter passed to this
@@ -177,4 +177,4 @@ class Server(six.with_metaclass(abc.ABCMeta)):
at the time it was stopped or if all RPCs that it had underway completed
very early in the grace period).
"""
- raise NotImplementedError()
+ raise NotImplementedError()
diff --git a/src/python/grpcio/grpc/beta/utilities.py b/src/python/grpcio/grpc/beta/utilities.py
index fb07a76579..60525350a7 100644
--- a/src/python/grpcio/grpc/beta/utilities.py
+++ b/src/python/grpcio/grpc/beta/utilities.py
@@ -26,7 +26,6 @@
# 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 the gRPC Python Beta API."""
import threading
@@ -44,107 +43,107 @@ _DONE_CALLBACK_EXCEPTION_LOG_MESSAGE = (
class _ChannelReadyFuture(future.Future):
- def __init__(self, channel):
- self._condition = threading.Condition()
- self._channel = channel
-
- self._matured = False
- self._cancelled = False
- self._done_callbacks = []
-
- def _block(self, timeout):
- until = None if timeout is None else time.time() + timeout
- with self._condition:
- while True:
- if self._cancelled:
- raise future.CancelledError()
- elif self._matured:
- return
- else:
- if until is None:
- self._condition.wait()
- else:
- remaining = until - time.time()
- if remaining < 0:
- raise future.TimeoutError()
+ def __init__(self, channel):
+ self._condition = threading.Condition()
+ self._channel = channel
+
+ self._matured = False
+ self._cancelled = False
+ self._done_callbacks = []
+
+ def _block(self, timeout):
+ until = None if timeout is None else time.time() + timeout
+ with self._condition:
+ while True:
+ if self._cancelled:
+ raise future.CancelledError()
+ elif self._matured:
+ return
+ else:
+ if until is None:
+ self._condition.wait()
+ else:
+ remaining = until - time.time()
+ if remaining < 0:
+ raise future.TimeoutError()
+ else:
+ self._condition.wait(timeout=remaining)
+
+ def _update(self, connectivity):
+ with self._condition:
+ if (not self._cancelled and
+ connectivity is interfaces.ChannelConnectivity.READY):
+ self._matured = True
+ self._channel.unsubscribe(self._update)
+ self._condition.notify_all()
+ done_callbacks = tuple(self._done_callbacks)
+ self._done_callbacks = None
+ else:
+ return
+
+ for done_callback in done_callbacks:
+ callable_util.call_logging_exceptions(
+ done_callback, _DONE_CALLBACK_EXCEPTION_LOG_MESSAGE, self)
+
+ def cancel(self):
+ with self._condition:
+ if not self._matured:
+ self._cancelled = True
+ self._channel.unsubscribe(self._update)
+ self._condition.notify_all()
+ done_callbacks = tuple(self._done_callbacks)
+ self._done_callbacks = None
else:
- self._condition.wait(timeout=remaining)
-
- def _update(self, connectivity):
- with self._condition:
- if (not self._cancelled and
- connectivity is interfaces.ChannelConnectivity.READY):
- self._matured = True
- self._channel.unsubscribe(self._update)
- self._condition.notify_all()
- done_callbacks = tuple(self._done_callbacks)
- self._done_callbacks = None
- else:
- return
-
- for done_callback in done_callbacks:
- callable_util.call_logging_exceptions(
- done_callback, _DONE_CALLBACK_EXCEPTION_LOG_MESSAGE, self)
-
- def cancel(self):
- with self._condition:
- if not self._matured:
- self._cancelled = True
- self._channel.unsubscribe(self._update)
- self._condition.notify_all()
- done_callbacks = tuple(self._done_callbacks)
- self._done_callbacks = None
- else:
- return False
-
- for done_callback in done_callbacks:
- callable_util.call_logging_exceptions(
- done_callback, _DONE_CALLBACK_EXCEPTION_LOG_MESSAGE, self)
-
- def cancelled(self):
- with self._condition:
- return self._cancelled
-
- def running(self):
- with self._condition:
- return not self._cancelled and not self._matured
-
- def done(self):
- with self._condition:
- return self._cancelled or self._matured
-
- def result(self, timeout=None):
- self._block(timeout)
- return None
-
- def exception(self, timeout=None):
- self._block(timeout)
- return None
-
- def traceback(self, timeout=None):
- self._block(timeout)
- return None
-
- def add_done_callback(self, fn):
- with self._condition:
- if not self._cancelled and not self._matured:
- self._done_callbacks.append(fn)
- return
-
- fn(self)
-
- def start(self):
- with self._condition:
- self._channel.subscribe(self._update, try_to_connect=True)
-
- def __del__(self):
- with self._condition:
- if not self._cancelled and not self._matured:
- self._channel.unsubscribe(self._update)
+ return False
+
+ for done_callback in done_callbacks:
+ callable_util.call_logging_exceptions(
+ done_callback, _DONE_CALLBACK_EXCEPTION_LOG_MESSAGE, self)
+
+ def cancelled(self):
+ with self._condition:
+ return self._cancelled
+
+ def running(self):
+ with self._condition:
+ return not self._cancelled and not self._matured
+
+ def done(self):
+ with self._condition:
+ return self._cancelled or self._matured
+
+ def result(self, timeout=None):
+ self._block(timeout)
+ return None
+
+ def exception(self, timeout=None):
+ self._block(timeout)
+ return None
+
+ def traceback(self, timeout=None):
+ self._block(timeout)
+ return None
+
+ def add_done_callback(self, fn):
+ with self._condition:
+ if not self._cancelled and not self._matured:
+ self._done_callbacks.append(fn)
+ return
+
+ fn(self)
+
+ def start(self):
+ with self._condition:
+ self._channel.subscribe(self._update, try_to_connect=True)
+
+ def __del__(self):
+ with self._condition:
+ if not self._cancelled and not self._matured:
+ self._channel.unsubscribe(self._update)
def channel_ready_future(channel):
- """Creates a future.Future tracking when an implementations.Channel is ready.
+ """Creates a future.Future tracking when an implementations.Channel is ready.
Cancelling the returned future.Future does not tell the given
implementations.Channel to abandon attempts it may have been making to
@@ -158,7 +157,6 @@ def channel_ready_future(channel):
A future.Future that matures when the given Channel has connectivity
interfaces.ChannelConnectivity.READY.
"""
- ready_future = _ChannelReadyFuture(channel)
- ready_future.start()
- return ready_future
-
+ ready_future = _ChannelReadyFuture(channel)
+ ready_future.start()
+ return ready_future
diff --git a/src/python/grpcio/grpc/framework/__init__.py b/src/python/grpcio/grpc/framework/__init__.py
index 7086519106..b89398809f 100644
--- a/src/python/grpcio/grpc/framework/__init__.py
+++ b/src/python/grpcio/grpc/framework/__init__.py
@@ -26,5 +26,3 @@
# 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.
-
-
diff --git a/src/python/grpcio/grpc/framework/common/__init__.py b/src/python/grpcio/grpc/framework/common/__init__.py
index 7086519106..b89398809f 100644
--- a/src/python/grpcio/grpc/framework/common/__init__.py
+++ b/src/python/grpcio/grpc/framework/common/__init__.py
@@ -26,5 +26,3 @@
# 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.
-
-
diff --git a/src/python/grpcio/grpc/framework/common/cardinality.py b/src/python/grpcio/grpc/framework/common/cardinality.py
index 610425e803..d8927cf9b0 100644
--- a/src/python/grpcio/grpc/framework/common/cardinality.py
+++ b/src/python/grpcio/grpc/framework/common/cardinality.py
@@ -26,7 +26,6 @@
# 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.
-
"""Defines an enum for classifying RPC methods by streaming semantics."""
import enum
@@ -34,9 +33,9 @@ import enum
@enum.unique
class Cardinality(enum.Enum):
- """Describes the streaming semantics of an RPC method."""
+ """Describes the streaming semantics of an RPC method."""
- UNARY_UNARY = 'request-unary/response-unary'
- UNARY_STREAM = 'request-unary/response-streaming'
- STREAM_UNARY = 'request-streaming/response-unary'
- STREAM_STREAM = 'request-streaming/response-streaming'
+ UNARY_UNARY = 'request-unary/response-unary'
+ UNARY_STREAM = 'request-unary/response-streaming'
+ STREAM_UNARY = 'request-streaming/response-unary'
+ STREAM_STREAM = 'request-streaming/response-streaming'
diff --git a/src/python/grpcio/grpc/framework/common/style.py b/src/python/grpcio/grpc/framework/common/style.py
index 6ae694bdcb..43f4211145 100644
--- a/src/python/grpcio/grpc/framework/common/style.py
+++ b/src/python/grpcio/grpc/framework/common/style.py
@@ -26,7 +26,6 @@
# 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.
-
"""Defines an enum for classifying RPC methods by control flow semantics."""
import enum
@@ -34,7 +33,7 @@ import enum
@enum.unique
class Service(enum.Enum):
- """Describes the control flow style of RPC method implementation."""
+ """Describes the control flow style of RPC method implementation."""
- INLINE = 'inline'
- EVENT = 'event'
+ INLINE = 'inline'
+ EVENT = 'event'
diff --git a/src/python/grpcio/grpc/framework/foundation/__init__.py b/src/python/grpcio/grpc/framework/foundation/__init__.py
index 7086519106..b89398809f 100644
--- a/src/python/grpcio/grpc/framework/foundation/__init__.py
+++ b/src/python/grpcio/grpc/framework/foundation/__init__.py
@@ -26,5 +26,3 @@
# 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.
-
-
diff --git a/src/python/grpcio/grpc/framework/foundation/abandonment.py b/src/python/grpcio/grpc/framework/foundation/abandonment.py
index 960b4d06b4..32385b9657 100644
--- a/src/python/grpcio/grpc/framework/foundation/abandonment.py
+++ b/src/python/grpcio/grpc/framework/foundation/abandonment.py
@@ -26,12 +26,11 @@
# 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 indicating abandonment of computation."""
class Abandoned(Exception):
- """Indicates that some computation is being abandoned.
+ """Indicates that some computation is being abandoned.
Abandoning a computation is different than returning a value or raising
an exception indicating some operational or programming defect.
diff --git a/src/python/grpcio/grpc/framework/foundation/callable_util.py b/src/python/grpcio/grpc/framework/foundation/callable_util.py
index 4f029f97bb..3b8351c19b 100644
--- a/src/python/grpcio/grpc/framework/foundation/callable_util.py
+++ b/src/python/grpcio/grpc/framework/foundation/callable_util.py
@@ -26,7 +26,6 @@
# 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 working with callables."""
import abc
@@ -39,7 +38,7 @@ import six
class Outcome(six.with_metaclass(abc.ABCMeta)):
- """A sum type describing the outcome of some call.
+ """A sum type describing the outcome of some call.
Attributes:
kind: One of Kind.RETURNED or Kind.RAISED respectively indicating that the
@@ -50,31 +49,31 @@ class Outcome(six.with_metaclass(abc.ABCMeta)):
Kind.RAISED.
"""
- @enum.unique
- class Kind(enum.Enum):
- """Identifies the general kind of the outcome of some call."""
+ @enum.unique
+ class Kind(enum.Enum):
+ """Identifies the general kind of the outcome of some call."""
- RETURNED = object()
- RAISED = object()
+ RETURNED = object()
+ RAISED = object()
class _EasyOutcome(
- collections.namedtuple(
- '_EasyOutcome', ['kind', 'return_value', 'exception']),
- Outcome):
- """A trivial implementation of Outcome."""
+ collections.namedtuple('_EasyOutcome',
+ ['kind', 'return_value', 'exception']), Outcome):
+ """A trivial implementation of Outcome."""
def _call_logging_exceptions(behavior, message, *args, **kwargs):
- try:
- return _EasyOutcome(Outcome.Kind.RETURNED, behavior(*args, **kwargs), None)
- except Exception as e: # pylint: disable=broad-except
- logging.exception(message)
- return _EasyOutcome(Outcome.Kind.RAISED, None, e)
+ try:
+ return _EasyOutcome(Outcome.Kind.RETURNED,
+ behavior(*args, **kwargs), None)
+ except Exception as e: # pylint: disable=broad-except
+ logging.exception(message)
+ return _EasyOutcome(Outcome.Kind.RAISED, None, e)
def with_exceptions_logged(behavior, message):
- """Wraps a callable in a try-except that logs any exceptions it raises.
+ """Wraps a callable in a try-except that logs any exceptions it raises.
Args:
behavior: Any callable.
@@ -86,14 +85,16 @@ def with_exceptions_logged(behavior, message):
future.Outcome describing whether the given behavior returned a value or
raised an exception.
"""
- @functools.wraps(behavior)
- def wrapped_behavior(*args, **kwargs):
- return _call_logging_exceptions(behavior, message, *args, **kwargs)
- return wrapped_behavior
+
+ @functools.wraps(behavior)
+ def wrapped_behavior(*args, **kwargs):
+ return _call_logging_exceptions(behavior, message, *args, **kwargs)
+
+ return wrapped_behavior
def call_logging_exceptions(behavior, message, *args, **kwargs):
- """Calls a behavior in a try-except that logs any exceptions it raises.
+ """Calls a behavior in a try-except that logs any exceptions it raises.
Args:
behavior: Any callable.
@@ -105,4 +106,4 @@ def call_logging_exceptions(behavior, message, *args, **kwargs):
An Outcome describing whether the given behavior returned a value or raised
an exception.
"""
- return _call_logging_exceptions(behavior, message, *args, **kwargs)
+ return _call_logging_exceptions(behavior, message, *args, **kwargs)
diff --git a/src/python/grpcio/grpc/framework/foundation/future.py b/src/python/grpcio/grpc/framework/foundation/future.py
index 6fb58eadb6..e2ecf62921 100644
--- a/src/python/grpcio/grpc/framework/foundation/future.py
+++ b/src/python/grpcio/grpc/framework/foundation/future.py
@@ -26,7 +26,6 @@
# 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.
-
"""A Future interface.
Python doesn't have a Future interface in its standard library. In the absence
@@ -53,33 +52,33 @@ import six
class TimeoutError(Exception):
- """Indicates that a particular call timed out."""
+ """Indicates that a particular call timed out."""
class CancelledError(Exception):
- """Indicates that the computation underlying a Future was cancelled."""
+ """Indicates that the computation underlying a Future was cancelled."""
class Future(six.with_metaclass(abc.ABCMeta)):
- """A representation of a computation in another control flow.
+ """A representation of a computation in another control flow.
Computations represented by a Future may be yet to be begun, may be ongoing,
or may have already completed.
"""
- # NOTE(nathaniel): This isn't the return type that I would want to have if it
- # were up to me. Were this interface being written from scratch, the return
- # type of this method would probably be a sum type like:
- #
- # NOT_COMMENCED
- # COMMENCED_AND_NOT_COMPLETED
- # PARTIAL_RESULT<Partial_Result_Type>
- # COMPLETED<Result_Type>
- # UNCANCELLABLE
- # NOT_IMMEDIATELY_DETERMINABLE
- @abc.abstractmethod
- def cancel(self):
- """Attempts to cancel the computation.
+ # NOTE(nathaniel): This isn't the return type that I would want to have if it
+ # were up to me. Were this interface being written from scratch, the return
+ # type of this method would probably be a sum type like:
+ #
+ # NOT_COMMENCED
+ # COMMENCED_AND_NOT_COMPLETED
+ # PARTIAL_RESULT<Partial_Result_Type>
+ # COMPLETED<Result_Type>
+ # UNCANCELLABLE
+ # NOT_IMMEDIATELY_DETERMINABLE
+ @abc.abstractmethod
+ def cancel(self):
+ """Attempts to cancel the computation.
This method does not block.
@@ -92,25 +91,25 @@ class Future(six.with_metaclass(abc.ABCMeta)):
remote system for which a determination of whether or not it commenced
before being cancelled cannot be made without blocking.
"""
- raise NotImplementedError()
-
- # NOTE(nathaniel): Here too this isn't the return type that I'd want this
- # method to have if it were up to me. I think I'd go with another sum type
- # like:
- #
- # NOT_CANCELLED (this object's cancel method hasn't been called)
- # NOT_COMMENCED
- # COMMENCED_AND_NOT_COMPLETED
- # PARTIAL_RESULT<Partial_Result_Type>
- # COMPLETED<Result_Type>
- # UNCANCELLABLE
- # NOT_IMMEDIATELY_DETERMINABLE
- #
- # Notice how giving the cancel method the right semantics obviates most
- # reasons for this method to exist.
- @abc.abstractmethod
- def cancelled(self):
- """Describes whether the computation was cancelled.
+ raise NotImplementedError()
+
+ # NOTE(nathaniel): Here too this isn't the return type that I'd want this
+ # method to have if it were up to me. I think I'd go with another sum type
+ # like:
+ #
+ # NOT_CANCELLED (this object's cancel method hasn't been called)
+ # NOT_COMMENCED
+ # COMMENCED_AND_NOT_COMPLETED
+ # PARTIAL_RESULT<Partial_Result_Type>
+ # COMPLETED<Result_Type>
+ # UNCANCELLABLE
+ # NOT_IMMEDIATELY_DETERMINABLE
+ #
+ # Notice how giving the cancel method the right semantics obviates most
+ # reasons for this method to exist.
+ @abc.abstractmethod
+ def cancelled(self):
+ """Describes whether the computation was cancelled.
This method does not block.
@@ -120,11 +119,11 @@ class Future(six.with_metaclass(abc.ABCMeta)):
not limited to this object's cancel method not having been called and
the computation's result having become immediately available.
"""
- raise NotImplementedError()
+ raise NotImplementedError()
- @abc.abstractmethod
- def running(self):
- """Describes whether the computation is taking place.
+ @abc.abstractmethod
+ def running(self):
+ """Describes whether the computation is taking place.
This method does not block.
@@ -133,15 +132,15 @@ class Future(six.with_metaclass(abc.ABCMeta)):
taking place now, or False if the computation took place in the past or
was cancelled.
"""
- raise NotImplementedError()
+ raise NotImplementedError()
- # NOTE(nathaniel): These aren't quite the semantics I'd like here either. I
- # would rather this only returned True in cases in which the underlying
- # computation completed successfully. A computation's having been cancelled
- # conflicts with considering that computation "done".
- @abc.abstractmethod
- def done(self):
- """Describes whether the computation has taken place.
+ # NOTE(nathaniel): These aren't quite the semantics I'd like here either. I
+ # would rather this only returned True in cases in which the underlying
+ # computation completed successfully. A computation's having been cancelled
+ # conflicts with considering that computation "done".
+ @abc.abstractmethod
+ def done(self):
+ """Describes whether the computation has taken place.
This method does not block.
@@ -150,11 +149,11 @@ class Future(six.with_metaclass(abc.ABCMeta)):
unscheduled or interrupted. False if the computation may possibly be
executing or scheduled to execute later.
"""
- raise NotImplementedError()
+ raise NotImplementedError()
- @abc.abstractmethod
- def result(self, timeout=None):
- """Accesses the outcome of the computation or raises its exception.
+ @abc.abstractmethod
+ def result(self, timeout=None):
+ """Accesses the outcome of the computation or raises its exception.
This method may return immediately or may block.
@@ -173,11 +172,11 @@ class Future(six.with_metaclass(abc.ABCMeta)):
Exception: If the computation raised an exception, this call will raise
the same exception.
"""
- raise NotImplementedError()
+ raise NotImplementedError()
- @abc.abstractmethod
- def exception(self, timeout=None):
- """Return the exception raised by the computation.
+ @abc.abstractmethod
+ def exception(self, timeout=None):
+ """Return the exception raised by the computation.
This method may return immediately or may block.
@@ -196,11 +195,11 @@ class Future(six.with_metaclass(abc.ABCMeta)):
terminate within the allotted time.
CancelledError: If the computation was cancelled.
"""
- raise NotImplementedError()
+ raise NotImplementedError()
- @abc.abstractmethod
- def traceback(self, timeout=None):
- """Access the traceback of the exception raised by the computation.
+ @abc.abstractmethod
+ def traceback(self, timeout=None):
+ """Access the traceback of the exception raised by the computation.
This method may return immediately or may block.
@@ -219,11 +218,11 @@ class Future(six.with_metaclass(abc.ABCMeta)):
terminate within the allotted time.
CancelledError: If the computation was cancelled.
"""
- raise NotImplementedError()
+ raise NotImplementedError()
- @abc.abstractmethod
- def add_done_callback(self, fn):
- """Adds a function to be called at completion of the computation.
+ @abc.abstractmethod
+ def add_done_callback(self, fn):
+ """Adds a function to be called at completion of the computation.
The callback will be passed this Future object describing the outcome of
the computation.
@@ -234,4 +233,4 @@ class Future(six.with_metaclass(abc.ABCMeta)):
Args:
fn: A callable taking this Future object as its single parameter.
"""
- raise NotImplementedError()
+ raise NotImplementedError()
diff --git a/src/python/grpcio/grpc/framework/foundation/logging_pool.py b/src/python/grpcio/grpc/framework/foundation/logging_pool.py
index 9b469a1452..9164173d34 100644
--- a/src/python/grpcio/grpc/framework/foundation/logging_pool.py
+++ b/src/python/grpcio/grpc/framework/foundation/logging_pool.py
@@ -26,7 +26,6 @@
# 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.
-
"""A thread pool that logs exceptions raised by tasks executed within it."""
import logging
@@ -35,42 +34,46 @@ from concurrent import futures
def _wrap(behavior):
- """Wraps an arbitrary callable behavior in exception-logging."""
- def _wrapping(*args, **kwargs):
- try:
- return behavior(*args, **kwargs)
- except Exception as e:
- logging.exception(
- 'Unexpected exception from %s executed in logging pool!', behavior)
- raise
- return _wrapping
+ """Wraps an arbitrary callable behavior in exception-logging."""
+
+ def _wrapping(*args, **kwargs):
+ try:
+ return behavior(*args, **kwargs)
+ except Exception as e:
+ logging.exception(
+ 'Unexpected exception from %s executed in logging pool!',
+ behavior)
+ raise
+
+ return _wrapping
class _LoggingPool(object):
- """An exception-logging futures.ThreadPoolExecutor-compatible thread pool."""
+ """An exception-logging futures.ThreadPoolExecutor-compatible thread pool."""
- def __init__(self, backing_pool):
- self._backing_pool = backing_pool
+ def __init__(self, backing_pool):
+ self._backing_pool = backing_pool
- def __enter__(self):
- return self
+ def __enter__(self):
+ return self
- def __exit__(self, exc_type, exc_val, exc_tb):
- self._backing_pool.shutdown(wait=True)
+ def __exit__(self, exc_type, exc_val, exc_tb):
+ self._backing_pool.shutdown(wait=True)
- def submit(self, fn, *args, **kwargs):
- return self._backing_pool.submit(_wrap(fn), *args, **kwargs)
+ def submit(self, fn, *args, **kwargs):
+ return self._backing_pool.submit(_wrap(fn), *args, **kwargs)
- def map(self, func, *iterables, **kwargs):
- return self._backing_pool.map(
- _wrap(func), *iterables, timeout=kwargs.get('timeout', None))
+ def map(self, func, *iterables, **kwargs):
+ return self._backing_pool.map(_wrap(func),
+ *iterables,
+ timeout=kwargs.get('timeout', None))
- def shutdown(self, wait=True):
- self._backing_pool.shutdown(wait=wait)
+ def shutdown(self, wait=True):
+ self._backing_pool.shutdown(wait=wait)
def pool(max_workers):
- """Creates a thread pool that logs exceptions raised by the tasks within it.
+ """Creates a thread pool that logs exceptions raised by the tasks within it.
Args:
max_workers: The maximum number of worker threads to allow the pool.
@@ -79,4 +82,4 @@ def pool(max_workers):
A futures.ThreadPoolExecutor-compatible thread pool that logs exceptions
raised by the tasks executed within it.
"""
- return _LoggingPool(futures.ThreadPoolExecutor(max_workers))
+ return _LoggingPool(futures.ThreadPoolExecutor(max_workers))
diff --git a/src/python/grpcio/grpc/framework/foundation/stream.py b/src/python/grpcio/grpc/framework/foundation/stream.py
index ddd6cc496a..2529a6944b 100644
--- a/src/python/grpcio/grpc/framework/foundation/stream.py
+++ b/src/python/grpcio/grpc/framework/foundation/stream.py
@@ -26,35 +26,35 @@
# 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 related to streams of values or objects."""
import abc
import six
+
class Consumer(six.with_metaclass(abc.ABCMeta)):
- """Interface for consumers of finite streams of values or objects."""
+ """Interface for consumers of finite streams of values or objects."""
- @abc.abstractmethod
- def consume(self, value):
- """Accepts a value.
+ @abc.abstractmethod
+ def consume(self, value):
+ """Accepts a value.
Args:
value: Any value accepted by this Consumer.
"""
- raise NotImplementedError()
+ raise NotImplementedError()
- @abc.abstractmethod
- def terminate(self):
- """Indicates to this Consumer that no more values will be supplied."""
- raise NotImplementedError()
+ @abc.abstractmethod
+ def terminate(self):
+ """Indicates to this Consumer that no more values will be supplied."""
+ raise NotImplementedError()
- @abc.abstractmethod
- def consume_and_terminate(self, value):
- """Supplies a value and signals that no more values will be supplied.
+ @abc.abstractmethod
+ def consume_and_terminate(self, value):
+ """Supplies a value and signals that no more values will be supplied.
Args:
value: Any value accepted by this Consumer.
"""
- raise NotImplementedError()
+ raise NotImplementedError()
diff --git a/src/python/grpcio/grpc/framework/foundation/stream_util.py b/src/python/grpcio/grpc/framework/foundation/stream_util.py
index a6f234f1fe..6b356f176f 100644
--- a/src/python/grpcio/grpc/framework/foundation/stream_util.py
+++ b/src/python/grpcio/grpc/framework/foundation/stream_util.py
@@ -26,7 +26,6 @@
# 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.
-
"""Helpful utilities related to the stream module."""
import logging
@@ -38,126 +37,126 @@ _NO_VALUE = object()
class TransformingConsumer(stream.Consumer):
- """A stream.Consumer that passes a transformation of its input to another."""
+ """A stream.Consumer that passes a transformation of its input to another."""
- def __init__(self, transformation, downstream):
- self._transformation = transformation
- self._downstream = downstream
+ def __init__(self, transformation, downstream):
+ self._transformation = transformation
+ self._downstream = downstream
- def consume(self, value):
- self._downstream.consume(self._transformation(value))
+ def consume(self, value):
+ self._downstream.consume(self._transformation(value))
- def terminate(self):
- self._downstream.terminate()
+ def terminate(self):
+ self._downstream.terminate()
- def consume_and_terminate(self, value):
- self._downstream.consume_and_terminate(self._transformation(value))
+ def consume_and_terminate(self, value):
+ self._downstream.consume_and_terminate(self._transformation(value))
class IterableConsumer(stream.Consumer):
- """A Consumer that when iterated over emits the values it has consumed."""
-
- def __init__(self):
- self._condition = threading.Condition()
- self._values = []
- self._active = True
-
- def consume(self, stock_reply):
- with self._condition:
- if self._active:
- self._values.append(stock_reply)
- self._condition.notify()
-
- def terminate(self):
- with self._condition:
- self._active = False
- self._condition.notify()
-
- def consume_and_terminate(self, stock_reply):
- with self._condition:
- if self._active:
- self._values.append(stock_reply)
- self._active = False
- self._condition.notify()
-
- def __iter__(self):
- return self
-
- def __next__(self):
- return self.next()
-
- def next(self):
- with self._condition:
- while self._active and not self._values:
- self._condition.wait()
- if self._values:
- return self._values.pop(0)
- else:
- raise StopIteration()
+ """A Consumer that when iterated over emits the values it has consumed."""
+
+ def __init__(self):
+ self._condition = threading.Condition()
+ self._values = []
+ self._active = True
+
+ def consume(self, stock_reply):
+ with self._condition:
+ if self._active:
+ self._values.append(stock_reply)
+ self._condition.notify()
+
+ def terminate(self):
+ with self._condition:
+ self._active = False
+ self._condition.notify()
+
+ def consume_and_terminate(self, stock_reply):
+ with self._condition:
+ if self._active:
+ self._values.append(stock_reply)
+ self._active = False
+ self._condition.notify()
+
+ def __iter__(self):
+ return self
+
+ def __next__(self):
+ return self.next()
+
+ def next(self):
+ with self._condition:
+ while self._active and not self._values:
+ self._condition.wait()
+ if self._values:
+ return self._values.pop(0)
+ else:
+ raise StopIteration()
class ThreadSwitchingConsumer(stream.Consumer):
- """A Consumer decorator that affords serialization and asynchrony."""
-
- def __init__(self, sink, pool):
- self._lock = threading.Lock()
- self._sink = sink
- self._pool = pool
- # True if self._spin has been submitted to the pool to be called once and
- # that call has not yet returned, False otherwise.
- self._spinning = False
- self._values = []
- self._active = True
-
- def _spin(self, sink, value, terminate):
- while True:
- try:
- if value is _NO_VALUE:
- sink.terminate()
- elif terminate:
- sink.consume_and_terminate(value)
- else:
- sink.consume(value)
- except Exception as e: # pylint:disable=broad-except
- logging.exception(e)
-
- with self._lock:
- if terminate:
- self._spinning = False
- return
- elif self._values:
- value = self._values.pop(0)
- terminate = not self._values and not self._active
- elif not self._active:
- value = _NO_VALUE
- terminate = True
- else:
- self._spinning = False
- return
-
- def consume(self, value):
- with self._lock:
- if self._active:
- if self._spinning:
- self._values.append(value)
- else:
- self._pool.submit(self._spin, self._sink, value, False)
- self._spinning = True
-
- def terminate(self):
- with self._lock:
- if self._active:
- self._active = False
- if not self._spinning:
- self._pool.submit(self._spin, self._sink, _NO_VALUE, True)
- self._spinning = True
-
- def consume_and_terminate(self, value):
- with self._lock:
- if self._active:
- self._active = False
- if self._spinning:
- self._values.append(value)
- else:
- self._pool.submit(self._spin, self._sink, value, True)
- self._spinning = True
+ """A Consumer decorator that affords serialization and asynchrony."""
+
+ def __init__(self, sink, pool):
+ self._lock = threading.Lock()
+ self._sink = sink
+ self._pool = pool
+ # True if self._spin has been submitted to the pool to be called once and
+ # that call has not yet returned, False otherwise.
+ self._spinning = False
+ self._values = []
+ self._active = True
+
+ def _spin(self, sink, value, terminate):
+ while True:
+ try:
+ if value is _NO_VALUE:
+ sink.terminate()
+ elif terminate:
+ sink.consume_and_terminate(value)
+ else:
+ sink.consume(value)
+ except Exception as e: # pylint:disable=broad-except
+ logging.exception(e)
+
+ with self._lock:
+ if terminate:
+ self._spinning = False
+ return
+ elif self._values:
+ value = self._values.pop(0)
+ terminate = not self._values and not self._active
+ elif not self._active:
+ value = _NO_VALUE
+ terminate = True
+ else:
+ self._spinning = False
+ return
+
+ def consume(self, value):
+ with self._lock:
+ if self._active:
+ if self._spinning:
+ self._values.append(value)
+ else:
+ self._pool.submit(self._spin, self._sink, value, False)
+ self._spinning = True
+
+ def terminate(self):
+ with self._lock:
+ if self._active:
+ self._active = False
+ if not self._spinning:
+ self._pool.submit(self._spin, self._sink, _NO_VALUE, True)
+ self._spinning = True
+
+ def consume_and_terminate(self, value):
+ with self._lock:
+ if self._active:
+ self._active = False
+ if self._spinning:
+ self._values.append(value)
+ else:
+ self._pool.submit(self._spin, self._sink, value, True)
+ self._spinning = True
diff --git a/src/python/grpcio/grpc/framework/interfaces/__init__.py b/src/python/grpcio/grpc/framework/interfaces/__init__.py
index 7086519106..b89398809f 100644
--- a/src/python/grpcio/grpc/framework/interfaces/__init__.py
+++ b/src/python/grpcio/grpc/framework/interfaces/__init__.py
@@ -26,5 +26,3 @@
# 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.
-
-
diff --git a/src/python/grpcio/grpc/framework/interfaces/base/__init__.py b/src/python/grpcio/grpc/framework/interfaces/base/__init__.py
index 7086519106..b89398809f 100644
--- a/src/python/grpcio/grpc/framework/interfaces/base/__init__.py
+++ b/src/python/grpcio/grpc/framework/interfaces/base/__init__.py
@@ -26,5 +26,3 @@
# 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.
-
-
diff --git a/src/python/grpcio/grpc/framework/interfaces/base/base.py b/src/python/grpcio/grpc/framework/interfaces/base/base.py
index a2ddd9c474..cb3328296c 100644
--- a/src/python/grpcio/grpc/framework/interfaces/base/base.py
+++ b/src/python/grpcio/grpc/framework/interfaces/base/base.py
@@ -26,7 +26,6 @@
# 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.
-
"""The base interface of RPC Framework.
Implementations of this interface support the conduct of "operations":
@@ -49,7 +48,7 @@ from grpc.framework.foundation import abandonment # pylint: disable=unused-impo
class NoSuchMethodError(Exception):
- """Indicates that an unrecognized operation has been called.
+ """Indicates that an unrecognized operation has been called.
Attributes:
code: A code value to communicate to the other side of the operation along
@@ -58,8 +57,8 @@ class NoSuchMethodError(Exception):
along with indication of operation termination. May be None.
"""
- def __init__(self, code, details):
- """Constructor.
+ def __init__(self, code, details):
+ """Constructor.
Args:
code: A code value to communicate to the other side of the operation
@@ -67,12 +66,12 @@ class NoSuchMethodError(Exception):
details: A details value to communicate to the other side of the
operation along with indication of operation termination. May be None.
"""
- self.code = code
- self.details = details
+ self.code = code
+ self.details = details
class Outcome(object):
- """The outcome of an operation.
+ """The outcome of an operation.
Attributes:
kind: A Kind value coarsely identifying how the operation terminated.
@@ -82,23 +81,23 @@ class Outcome(object):
provided.
"""
- @enum.unique
- class Kind(enum.Enum):
- """Ways in which an operation can terminate."""
+ @enum.unique
+ class Kind(enum.Enum):
+ """Ways in which an operation can terminate."""
- COMPLETED = 'completed'
- CANCELLED = 'cancelled'
- EXPIRED = 'expired'
- LOCAL_SHUTDOWN = 'local shutdown'
- REMOTE_SHUTDOWN = 'remote shutdown'
- RECEPTION_FAILURE = 'reception failure'
- TRANSMISSION_FAILURE = 'transmission failure'
- LOCAL_FAILURE = 'local failure'
- REMOTE_FAILURE = 'remote failure'
+ COMPLETED = 'completed'
+ CANCELLED = 'cancelled'
+ EXPIRED = 'expired'
+ LOCAL_SHUTDOWN = 'local shutdown'
+ REMOTE_SHUTDOWN = 'remote shutdown'
+ RECEPTION_FAILURE = 'reception failure'
+ TRANSMISSION_FAILURE = 'transmission failure'
+ LOCAL_FAILURE = 'local failure'
+ REMOTE_FAILURE = 'remote failure'
class Completion(six.with_metaclass(abc.ABCMeta)):
- """An aggregate of the values exchanged upon operation completion.
+ """An aggregate of the values exchanged upon operation completion.
Attributes:
terminal_metadata: A terminal metadata value for the operaton.
@@ -108,21 +107,21 @@ class Completion(six.with_metaclass(abc.ABCMeta)):
class OperationContext(six.with_metaclass(abc.ABCMeta)):
- """Provides operation-related information and action."""
+ """Provides operation-related information and action."""
- @abc.abstractmethod
- def outcome(self):
- """Indicates the operation's outcome (or that the operation is ongoing).
+ @abc.abstractmethod
+ def outcome(self):
+ """Indicates the operation's outcome (or that the operation is ongoing).
Returns:
None if the operation is still active or the Outcome value for the
operation if it has terminated.
"""
- raise NotImplementedError()
+ raise NotImplementedError()
- @abc.abstractmethod
- def add_termination_callback(self, callback):
- """Adds a function to be called upon operation termination.
+ @abc.abstractmethod
+ def add_termination_callback(self, callback):
+ """Adds a function to be called upon operation termination.
Args:
callback: A callable to be passed an Outcome value on operation
@@ -134,42 +133,44 @@ class OperationContext(six.with_metaclass(abc.ABCMeta)):
terminated an Outcome value describing the operation termination and the
passed callback will not be called as a result of this method call.
"""
- raise NotImplementedError()
+ raise NotImplementedError()
- @abc.abstractmethod
- def time_remaining(self):
- """Describes the length of allowed time remaining for the operation.
+ @abc.abstractmethod
+ def time_remaining(self):
+ """Describes the length of allowed time remaining for the operation.
Returns:
A nonnegative float indicating the length of allowed time in seconds
remaining for the operation to complete before it is considered to have
timed out. Zero is returned if the operation has terminated.
"""
- raise NotImplementedError()
+ raise NotImplementedError()
- @abc.abstractmethod
- def cancel(self):
- """Cancels the operation if the operation has not yet terminated."""
- raise NotImplementedError()
+ @abc.abstractmethod
+ def cancel(self):
+ """Cancels the operation if the operation has not yet terminated."""
+ raise NotImplementedError()
- @abc.abstractmethod
- def fail(self, exception):
- """Indicates that the operation has failed.
+ @abc.abstractmethod
+ def fail(self, exception):
+ """Indicates that the operation has failed.
Args:
exception: An exception germane to the operation failure. May be None.
"""
- raise NotImplementedError()
+ raise NotImplementedError()
class Operator(six.with_metaclass(abc.ABCMeta)):
- """An interface through which to participate in an operation."""
+ """An interface through which to participate in an operation."""
- @abc.abstractmethod
- def advance(
- self, initial_metadata=None, payload=None, completion=None,
- allowance=None):
- """Progresses the operation.
+ @abc.abstractmethod
+ def advance(self,
+ initial_metadata=None,
+ payload=None,
+ completion=None,
+ allowance=None):
+ """Progresses the operation.
Args:
initial_metadata: An initial metadata value. Only one may ever be
@@ -181,23 +182,24 @@ class Operator(six.with_metaclass(abc.ABCMeta)):
allowance: A positive integer communicating the number of additional
payloads allowed to be passed by the remote side of the operation.
"""
- raise NotImplementedError()
+ raise NotImplementedError()
+
class ProtocolReceiver(six.with_metaclass(abc.ABCMeta)):
- """A means of receiving protocol values during an operation."""
+ """A means of receiving protocol values during an operation."""
- @abc.abstractmethod
- def context(self, protocol_context):
- """Accepts the protocol context object for the operation.
+ @abc.abstractmethod
+ def context(self, protocol_context):
+ """Accepts the protocol context object for the operation.
Args:
protocol_context: The protocol context object for the operation.
"""
- raise NotImplementedError()
+ raise NotImplementedError()
class Subscription(six.with_metaclass(abc.ABCMeta)):
- """Describes customer code's interest in values from the other side.
+ """Describes customer code's interest in values from the other side.
Attributes:
kind: A Kind value describing the overall kind of this value.
@@ -215,20 +217,20 @@ class Subscription(six.with_metaclass(abc.ABCMeta)):
Kind.FULL.
"""
- @enum.unique
- class Kind(enum.Enum):
+ @enum.unique
+ class Kind(enum.Enum):
- NONE = 'none'
- TERMINATION_ONLY = 'termination only'
- FULL = 'full'
+ NONE = 'none'
+ TERMINATION_ONLY = 'termination only'
+ FULL = 'full'
class Servicer(six.with_metaclass(abc.ABCMeta)):
- """Interface for service implementations."""
+ """Interface for service implementations."""
- @abc.abstractmethod
- def service(self, group, method, context, output_operator):
- """Services an operation.
+ @abc.abstractmethod
+ def service(self, group, method, context, output_operator):
+ """Services an operation.
Args:
group: The group identifier of the operation to be serviced.
@@ -248,20 +250,20 @@ class Servicer(six.with_metaclass(abc.ABCMeta)):
abandonment.Abandoned: If the operation has been aborted and there no
longer is any reason to service the operation.
"""
- raise NotImplementedError()
+ raise NotImplementedError()
class End(six.with_metaclass(abc.ABCMeta)):
- """Common type for entry-point objects on both sides of an operation."""
+ """Common type for entry-point objects on both sides of an operation."""
- @abc.abstractmethod
- def start(self):
- """Starts this object's service of operations."""
- raise NotImplementedError()
+ @abc.abstractmethod
+ def start(self):
+ """Starts this object's service of operations."""
+ raise NotImplementedError()
- @abc.abstractmethod
- def stop(self, grace):
- """Stops this object's service of operations.
+ @abc.abstractmethod
+ def stop(self, grace):
+ """Stops this object's service of operations.
This object will refuse service of new operations as soon as this method is
called but operations under way at the time of the call may be given a
@@ -281,13 +283,19 @@ class End(six.with_metaclass(abc.ABCMeta)):
much sooner (if for example this End had no operations in progress at
the time its stop method was called).
"""
- raise NotImplementedError()
-
- @abc.abstractmethod
- def operate(
- self, group, method, subscription, timeout, initial_metadata=None,
- payload=None, completion=None, protocol_options=None):
- """Commences an operation.
+ raise NotImplementedError()
+
+ @abc.abstractmethod
+ def operate(self,
+ group,
+ method,
+ subscription,
+ timeout,
+ initial_metadata=None,
+ payload=None,
+ completion=None,
+ protocol_options=None):
+ """Commences an operation.
Args:
group: The group identifier of the invoked operation.
@@ -312,23 +320,23 @@ class End(six.with_metaclass(abc.ABCMeta)):
returned pair is an Operator to which operation values not passed in
this call should later be passed.
"""
- raise NotImplementedError()
+ raise NotImplementedError()
- @abc.abstractmethod
- def operation_stats(self):
- """Reports the number of terminated operations broken down by outcome.
+ @abc.abstractmethod
+ def operation_stats(self):
+ """Reports the number of terminated operations broken down by outcome.
Returns:
A dictionary from Outcome.Kind value to an integer identifying the number
of operations that terminated with that outcome kind.
"""
- raise NotImplementedError()
+ raise NotImplementedError()
- @abc.abstractmethod
- def add_idle_action(self, action):
- """Adds an action to be called when this End has no ongoing operations.
+ @abc.abstractmethod
+ def add_idle_action(self, action):
+ """Adds an action to be called when this End has no ongoing operations.
Args:
action: A callable that accepts no arguments.
"""
- raise NotImplementedError()
+ raise NotImplementedError()
diff --git a/src/python/grpcio/grpc/framework/interfaces/base/utilities.py b/src/python/grpcio/grpc/framework/interfaces/base/utilities.py
index 87a85018f5..461706ff9f 100644
--- a/src/python/grpcio/grpc/framework/interfaces/base/utilities.py
+++ b/src/python/grpcio/grpc/framework/interfaces/base/utilities.py
@@ -26,7 +26,6 @@
# 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 use with the base interface of RPC Framework."""
import collections
@@ -34,27 +33,30 @@ import collections
from grpc.framework.interfaces.base import base
-class _Completion(
- base.Completion,
- collections.namedtuple(
- '_Completion', ('terminal_metadata', 'code', 'message',))):
- """A trivial implementation of base.Completion."""
+class _Completion(base.Completion,
+ collections.namedtuple('_Completion', (
+ 'terminal_metadata',
+ 'code',
+ 'message',))):
+ """A trivial implementation of base.Completion."""
+
+class _Subscription(base.Subscription,
+ collections.namedtuple('_Subscription', (
+ 'kind',
+ 'termination_callback',
+ 'allowance',
+ 'operator',
+ 'protocol_receiver',))):
+ """A trivial implementation of base.Subscription."""
-class _Subscription(
- base.Subscription,
- collections.namedtuple(
- '_Subscription',
- ('kind', 'termination_callback', 'allowance', 'operator',
- 'protocol_receiver',))):
- """A trivial implementation of base.Subscription."""
-_NONE_SUBSCRIPTION = _Subscription(
- base.Subscription.Kind.NONE, None, None, None, None)
+_NONE_SUBSCRIPTION = _Subscription(base.Subscription.Kind.NONE, None, None,
+ None, None)
def completion(terminal_metadata, code, message):
- """Creates a base.Completion aggregating the given operation values.
+ """Creates a base.Completion aggregating the given operation values.
Args:
terminal_metadata: A terminal metadata value for an operaton.
@@ -64,11 +66,11 @@ def completion(terminal_metadata, code, message):
Returns:
A base.Completion aggregating the given operation values.
"""
- return _Completion(terminal_metadata, code, message)
+ return _Completion(terminal_metadata, code, message)
def full_subscription(operator, protocol_receiver):
- """Creates a "full" base.Subscription for the given base.Operator.
+ """Creates a "full" base.Subscription for the given base.Operator.
Args:
operator: A base.Operator to be used in an operation.
@@ -78,5 +80,5 @@ def full_subscription(operator, protocol_receiver):
A base.Subscription of kind base.Subscription.Kind.FULL wrapping the given
base.Operator and base.ProtocolReceiver.
"""
- return _Subscription(
- base.Subscription.Kind.FULL, None, None, operator, protocol_receiver)
+ return _Subscription(base.Subscription.Kind.FULL, None, None, operator,
+ protocol_receiver)
diff --git a/src/python/grpcio/grpc/framework/interfaces/face/__init__.py b/src/python/grpcio/grpc/framework/interfaces/face/__init__.py
index 7086519106..b89398809f 100644
--- a/src/python/grpcio/grpc/framework/interfaces/face/__init__.py
+++ b/src/python/grpcio/grpc/framework/interfaces/face/__init__.py
@@ -26,5 +26,3 @@
# 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.
-
-
diff --git a/src/python/grpcio/grpc/framework/interfaces/face/face.py b/src/python/grpcio/grpc/framework/interfaces/face/face.py
index 4826e7fff6..36ddca18c1 100644
--- a/src/python/grpcio/grpc/framework/interfaces/face/face.py
+++ b/src/python/grpcio/grpc/framework/interfaces/face/face.py
@@ -26,7 +26,6 @@
# 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
@@ -45,33 +44,38 @@ from grpc.framework.foundation import stream # pylint: disable=unused-import
class NoSuchMethodError(Exception):
- """Raised by customer code to indicate an unrecognized method.
+ """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.
+ 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
+ super(NoSuchMethodError, self).__init__()
+ self.group = group
+ self.method = method
- def __repr__(self):
- return 'face.NoSuchMethodError(%s, %s)' % (self.group, self.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.
+ 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.
@@ -85,21 +89,21 @@ class Abortion(
details value was received.
"""
- @enum.unique
- class Kind(enum.Enum):
- """Types of RPC abortion."""
+ @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'
+ 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(six.with_metaclass(abc.ABCMeta, Exception)):
- """Common super type for exceptions indicating RPC abortion.
+ """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.
@@ -111,100 +115,100 @@ class AbortionError(six.with_metaclass(abc.ABCMeta, Exception)):
details value was received.
"""
- 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
+ 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
- def __str__(self):
- return '%s(code=%s, details="%s")' % (
- self.__class__.__name__, self.code, self.details)
+ def __str__(self):
+ return '%s(code=%s, details="%s")' % (self.__class__.__name__,
+ self.code, self.details)
class CancellationError(AbortionError):
- """Indicates that an RPC has been cancelled."""
+ """Indicates that an RPC has been cancelled."""
class ExpirationError(AbortionError):
- """Indicates that an RPC has expired ("timed out")."""
+ """Indicates that an RPC has expired ("timed out")."""
class LocalShutdownError(AbortionError):
- """Indicates that an RPC has terminated due to local shutdown of RPCs."""
+ """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."""
+ """Indicates that an RPC has terminated due to remote shutdown of RPCs."""
class NetworkError(AbortionError):
- """Indicates that some error occurred on the network."""
+ """Indicates that some error occurred on the network."""
class LocalError(AbortionError):
- """Indicates that an RPC has terminated due to a local defect."""
+ """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."""
+ """Indicates that an RPC has terminated due to a remote defect."""
class RpcContext(six.with_metaclass(abc.ABCMeta)):
- """Provides RPC-related information and action."""
+ """Provides RPC-related information and action."""
- @abc.abstractmethod
- def is_active(self):
- """Describes whether the RPC is active or has terminated."""
- raise NotImplementedError()
+ @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.
+ @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()
+ raise NotImplementedError()
- @abc.abstractmethod
- def add_abortion_callback(self, abortion_callback):
- """Registers a callback to be called if the RPC is aborted.
+ @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()
+ raise NotImplementedError()
- @abc.abstractmethod
- def cancel(self):
- """Cancels the RPC.
+ @abc.abstractmethod
+ def cancel(self):
+ """Cancels the RPC.
Idempotent and has no effect if the RPC has already terminated.
"""
- raise NotImplementedError()
+ raise NotImplementedError()
- @abc.abstractmethod
- def protocol_context(self):
- """Accesses a custom object specified by an implementation provider.
+ @abc.abstractmethod
+ def protocol_context(self):
+ """Accesses a custom object specified by an implementation provider.
Returns:
A value specified by the provider of a Face interface implementation
affording custom state and behavior.
"""
- raise NotImplementedError()
+ raise NotImplementedError()
class Call(six.with_metaclass(abc.ABCMeta, RpcContext)):
- """Invocation-side utility object for an RPC."""
+ """Invocation-side utility object for an RPC."""
- @abc.abstractmethod
- def initial_metadata(self):
- """Accesses the initial metadata from the service-side of the RPC.
+ @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.
@@ -213,11 +217,11 @@ class Call(six.with_metaclass(abc.ABCMeta, RpcContext)):
The initial metadata object emitted by the service-side of the RPC, or
None if there was no such value.
"""
- raise NotImplementedError()
+ raise NotImplementedError()
- @abc.abstractmethod
- def terminal_metadata(self):
- """Accesses the terminal metadata from the service-side of the RPC.
+ @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.
@@ -226,11 +230,11 @@ class Call(six.with_metaclass(abc.ABCMeta, RpcContext)):
The terminal metadata object emitted by the service-side of the RPC, or
None if there was no such value.
"""
- raise NotImplementedError()
+ raise NotImplementedError()
- @abc.abstractmethod
- def code(self):
- """Accesses the code emitted by the service-side of the RPC.
+ @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.
@@ -239,11 +243,11 @@ class Call(six.with_metaclass(abc.ABCMeta, RpcContext)):
The code object emitted by the service-side of the RPC, or None if there
was no such value.
"""
- raise NotImplementedError()
+ raise NotImplementedError()
- @abc.abstractmethod
- def details(self):
- """Accesses the details value emitted by the service-side of the RPC.
+ @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.
@@ -252,15 +256,15 @@ class Call(six.with_metaclass(abc.ABCMeta, RpcContext)):
The details value emitted by the service-side of the RPC, or None if there
was no such value.
"""
- raise NotImplementedError()
+ raise NotImplementedError()
class ServicerContext(six.with_metaclass(abc.ABCMeta, RpcContext)):
- """A context object passed to method implementations."""
+ """A context object passed to method implementations."""
- @abc.abstractmethod
- def invocation_metadata(self):
- """Accesses the metadata from the invocation-side of the RPC.
+ @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.
@@ -269,11 +273,11 @@ class ServicerContext(six.with_metaclass(abc.ABCMeta, RpcContext)):
The metadata object emitted by the invocation-side of the RPC, or None if
there was no such value.
"""
- raise NotImplementedError()
+ raise NotImplementedError()
- @abc.abstractmethod
- def initial_metadata(self, initial_metadata):
- """Accepts the service-side initial metadata value of the RPC.
+ @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.
@@ -282,11 +286,11 @@ class ServicerContext(six.with_metaclass(abc.ABCMeta, RpcContext)):
initial_metadata: The service-side initial metadata value of the RPC to
be transmitted to the invocation side of the RPC.
"""
- raise NotImplementedError()
+ raise NotImplementedError()
- @abc.abstractmethod
- def terminal_metadata(self, terminal_metadata):
- """Accepts the service-side terminal metadata value of the RPC.
+ @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.
@@ -295,11 +299,11 @@ class ServicerContext(six.with_metaclass(abc.ABCMeta, RpcContext)):
terminal_metadata: The service-side terminal metadata value of the RPC to
be transmitted to the invocation side of the RPC.
"""
- raise NotImplementedError()
+ raise NotImplementedError()
- @abc.abstractmethod
- def code(self, code):
- """Accepts the service-side code of the RPC.
+ @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.
@@ -308,11 +312,11 @@ class ServicerContext(six.with_metaclass(abc.ABCMeta, RpcContext)):
code: The code of the RPC to be transmitted to the invocation side of the
RPC.
"""
- raise NotImplementedError()
+ raise NotImplementedError()
- @abc.abstractmethod
- def details(self, details):
- """Accepts the service-side details of the RPC.
+ @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.
@@ -321,34 +325,34 @@ class ServicerContext(six.with_metaclass(abc.ABCMeta, RpcContext)):
details: The service-side details value of the RPC to be transmitted to
the invocation side of the RPC.
"""
- raise NotImplementedError()
+ raise NotImplementedError()
class ResponseReceiver(six.with_metaclass(abc.ABCMeta)):
- """Invocation-side object used to accept the output of an RPC."""
+ """Invocation-side object used to accept the output of an RPC."""
- @abc.abstractmethod
- def initial_metadata(self, initial_metadata):
- """Receives the initial metadata from the service-side of the RPC.
+ @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()
+ raise NotImplementedError()
- @abc.abstractmethod
- def response(self, response):
- """Receives a response from the service-side of the RPC.
+ @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()
+ raise NotImplementedError()
- @abc.abstractmethod
- def complete(self, terminal_metadata, code, details):
- """Receives the completion values emitted from the service-side of the RPC.
+ @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
@@ -356,17 +360,20 @@ class ResponseReceiver(six.with_metaclass(abc.ABCMeta)):
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()
+ raise NotImplementedError()
class UnaryUnaryMultiCallable(six.with_metaclass(abc.ABCMeta)):
- """Affords invoking a unary-unary RPC in any call style."""
+ """Affords invoking a unary-unary RPC in any call style."""
- @abc.abstractmethod
- def __call__(
- self, request, timeout, metadata=None, with_call=False,
- protocol_options=None):
- """Synchronously invokes the underlying RPC.
+ @abc.abstractmethod
+ def __call__(self,
+ request,
+ timeout,
+ metadata=None,
+ with_call=False,
+ protocol_options=None):
+ """Synchronously invokes the underlying RPC.
Args:
request: The request value for the RPC.
@@ -385,11 +392,11 @@ class UnaryUnaryMultiCallable(six.with_metaclass(abc.ABCMeta)):
Raises:
AbortionError: Indicating that the RPC was aborted.
"""
- raise NotImplementedError()
+ raise NotImplementedError()
- @abc.abstractmethod
- def future(self, request, timeout, metadata=None, protocol_options=None):
- """Asynchronously invokes the underlying RPC.
+ @abc.abstractmethod
+ def future(self, request, timeout, metadata=None, protocol_options=None):
+ """Asynchronously invokes the underlying RPC.
Args:
request: The request value for the RPC.
@@ -405,13 +412,17 @@ class UnaryUnaryMultiCallable(six.with_metaclass(abc.ABCMeta)):
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, protocol_options=None):
- """Asynchronously invokes the underlying RPC.
+ raise NotImplementedError()
+
+ @abc.abstractmethod
+ def event(self,
+ request,
+ receiver,
+ abortion_callback,
+ timeout,
+ metadata=None,
+ protocol_options=None):
+ """Asynchronously invokes the underlying RPC.
Args:
request: The request value for the RPC.
@@ -427,15 +438,15 @@ class UnaryUnaryMultiCallable(six.with_metaclass(abc.ABCMeta)):
Returns:
A Call for the RPC.
"""
- raise NotImplementedError()
+ raise NotImplementedError()
class UnaryStreamMultiCallable(six.with_metaclass(abc.ABCMeta)):
- """Affords invoking a unary-stream RPC in any call style."""
+ """Affords invoking a unary-stream RPC in any call style."""
- @abc.abstractmethod
- def __call__(self, request, timeout, metadata=None, protocol_options=None):
- """Invokes the underlying RPC.
+ @abc.abstractmethod
+ def __call__(self, request, timeout, metadata=None, protocol_options=None):
+ """Invokes the underlying RPC.
Args:
request: The request value for the RPC.
@@ -450,13 +461,17 @@ class UnaryStreamMultiCallable(six.with_metaclass(abc.ABCMeta)):
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, protocol_options=None):
- """Asynchronously invokes the underlying RPC.
+ raise NotImplementedError()
+
+ @abc.abstractmethod
+ def event(self,
+ request,
+ receiver,
+ abortion_callback,
+ timeout,
+ metadata=None,
+ protocol_options=None):
+ """Asynchronously invokes the underlying RPC.
Args:
request: The request value for the RPC.
@@ -472,17 +487,20 @@ class UnaryStreamMultiCallable(six.with_metaclass(abc.ABCMeta)):
Returns:
A Call object for the RPC.
"""
- raise NotImplementedError()
+ raise NotImplementedError()
class StreamUnaryMultiCallable(six.with_metaclass(abc.ABCMeta)):
- """Affords invoking a stream-unary RPC in any call style."""
+ """Affords invoking a stream-unary RPC in any call style."""
- @abc.abstractmethod
- def __call__(
- self, request_iterator, timeout, metadata=None,
- with_call=False, protocol_options=None):
- """Synchronously invokes the underlying RPC.
+ @abc.abstractmethod
+ def __call__(self,
+ request_iterator,
+ timeout,
+ metadata=None,
+ with_call=False,
+ protocol_options=None):
+ """Synchronously invokes the underlying RPC.
Args:
request_iterator: An iterator that yields request values for the RPC.
@@ -501,12 +519,15 @@ class StreamUnaryMultiCallable(six.with_metaclass(abc.ABCMeta)):
Raises:
AbortionError: Indicating that the RPC was aborted.
"""
- raise NotImplementedError()
+ raise NotImplementedError()
- @abc.abstractmethod
- def future(
- self, request_iterator, timeout, metadata=None, protocol_options=None):
- """Asynchronously invokes the underlying RPC.
+ @abc.abstractmethod
+ def future(self,
+ request_iterator,
+ timeout,
+ metadata=None,
+ protocol_options=None):
+ """Asynchronously invokes the underlying RPC.
Args:
request_iterator: An iterator that yields request values for the RPC.
@@ -522,13 +543,16 @@ class StreamUnaryMultiCallable(six.with_metaclass(abc.ABCMeta)):
response value of the RPC. In the event of RPC abortion, the returned
Future's exception value will be an AbortionError.
"""
- raise NotImplementedError()
+ raise NotImplementedError()
- @abc.abstractmethod
- def event(
- self, receiver, abortion_callback, timeout, metadata=None,
- protocol_options=None):
- """Asynchronously invokes the underlying RPC.
+ @abc.abstractmethod
+ def event(self,
+ receiver,
+ abortion_callback,
+ timeout,
+ metadata=None,
+ protocol_options=None):
+ """Asynchronously invokes the underlying RPC.
Args:
receiver: A ResponseReceiver to be passed the response data of the RPC.
@@ -544,16 +568,19 @@ class StreamUnaryMultiCallable(six.with_metaclass(abc.ABCMeta)):
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()
+ raise NotImplementedError()
class StreamStreamMultiCallable(six.with_metaclass(abc.ABCMeta)):
- """Affords invoking a stream-stream RPC in any call style."""
+ """Affords invoking a stream-stream RPC in any call style."""
- @abc.abstractmethod
- def __call__(
- self, request_iterator, timeout, metadata=None, protocol_options=None):
- """Invokes the underlying RPC.
+ @abc.abstractmethod
+ def __call__(self,
+ request_iterator,
+ timeout,
+ metadata=None,
+ protocol_options=None):
+ """Invokes the underlying RPC.
Args:
request_iterator: An iterator that yields request values for the RPC.
@@ -568,13 +595,16 @@ class StreamStreamMultiCallable(six.with_metaclass(abc.ABCMeta)):
values. Drawing response values from the returned iterator may raise
AbortionError indicating abortion of the RPC.
"""
- raise NotImplementedError()
+ raise NotImplementedError()
- @abc.abstractmethod
- def event(
- self, receiver, abortion_callback, timeout, metadata=None,
- protocol_options=None):
- """Asynchronously invokes the underlying RPC.
+ @abc.abstractmethod
+ def event(self,
+ receiver,
+ abortion_callback,
+ timeout,
+ metadata=None,
+ protocol_options=None):
+ """Asynchronously invokes the underlying RPC.
Args:
receiver: A ResponseReceiver to be passed the response data of the RPC.
@@ -590,11 +620,11 @@ class StreamStreamMultiCallable(six.with_metaclass(abc.ABCMeta)):
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()
+ raise NotImplementedError()
class MethodImplementation(six.with_metaclass(abc.ABCMeta)):
- """A sum type that describes a method implementation.
+ """A sum type that describes a method implementation.
Attributes:
cardinality: A cardinality.Cardinality value.
@@ -639,11 +669,11 @@ class MethodImplementation(six.with_metaclass(abc.ABCMeta)):
class MultiMethodImplementation(six.with_metaclass(abc.ABCMeta)):
- """A general type able to service many methods."""
+ """A general type able to service many methods."""
- @abc.abstractmethod
- def service(self, group, method, response_consumer, context):
- """Services an RPC.
+ @abc.abstractmethod
+ def service(self, group, method, response_consumer, context):
+ """Services an RPC.
Args:
group: The group identifier of the RPC.
@@ -666,17 +696,22 @@ class MultiMethodImplementation(six.with_metaclass(abc.ABCMeta)):
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()
+ raise NotImplementedError()
class GenericStub(six.with_metaclass(abc.ABCMeta)):
- """Affords RPC invocation via generic methods."""
-
- @abc.abstractmethod
- def blocking_unary_unary(
- self, group, method, request, timeout, metadata=None,
- with_call=False, protocol_options=None):
- """Invokes a unary-request-unary-response method.
+ """Affords RPC invocation via generic methods."""
+
+ @abc.abstractmethod
+ def blocking_unary_unary(self,
+ group,
+ method,
+ request,
+ timeout,
+ metadata=None,
+ with_call=False,
+ protocol_options=None):
+ """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
@@ -700,13 +735,17 @@ class GenericStub(six.with_metaclass(abc.ABCMeta)):
Raises:
AbortionError: Indicating that the RPC was aborted.
"""
- raise NotImplementedError()
-
- @abc.abstractmethod
- def future_unary_unary(
- self, group, method, request, timeout, metadata=None,
- protocol_options=None):
- """Invokes a unary-request-unary-response method.
+ raise NotImplementedError()
+
+ @abc.abstractmethod
+ def future_unary_unary(self,
+ group,
+ method,
+ request,
+ timeout,
+ metadata=None,
+ protocol_options=None):
+ """Invokes a unary-request-unary-response method.
Args:
group: The group identifier of the RPC.
@@ -723,13 +762,17 @@ class GenericStub(six.with_metaclass(abc.ABCMeta)):
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,
- protocol_options=None):
- """Invokes a unary-request-stream-response method.
+ raise NotImplementedError()
+
+ @abc.abstractmethod
+ def inline_unary_stream(self,
+ group,
+ method,
+ request,
+ timeout,
+ metadata=None,
+ protocol_options=None):
+ """Invokes a unary-request-stream-response method.
Args:
group: The group identifier of the RPC.
@@ -745,13 +788,18 @@ class GenericStub(six.with_metaclass(abc.ABCMeta)):
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, protocol_options=None):
- """Invokes a stream-request-unary-response method.
+ raise NotImplementedError()
+
+ @abc.abstractmethod
+ def blocking_stream_unary(self,
+ group,
+ method,
+ request_iterator,
+ timeout,
+ metadata=None,
+ with_call=False,
+ protocol_options=None):
+ """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
@@ -775,13 +823,17 @@ class GenericStub(six.with_metaclass(abc.ABCMeta)):
Raises:
AbortionError: Indicating that the RPC was aborted.
"""
- raise NotImplementedError()
-
- @abc.abstractmethod
- def future_stream_unary(
- self, group, method, request_iterator, timeout, metadata=None,
- protocol_options=None):
- """Invokes a stream-request-unary-response method.
+ raise NotImplementedError()
+
+ @abc.abstractmethod
+ def future_stream_unary(self,
+ group,
+ method,
+ request_iterator,
+ timeout,
+ metadata=None,
+ protocol_options=None):
+ """Invokes a stream-request-unary-response method.
Args:
group: The group identifier of the RPC.
@@ -798,13 +850,17 @@ class GenericStub(six.with_metaclass(abc.ABCMeta)):
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,
- protocol_options=None):
- """Invokes a stream-request-stream-response method.
+ raise NotImplementedError()
+
+ @abc.abstractmethod
+ def inline_stream_stream(self,
+ group,
+ method,
+ request_iterator,
+ timeout,
+ metadata=None,
+ protocol_options=None):
+ """Invokes a stream-request-stream-response method.
Args:
group: The group identifier of the RPC.
@@ -820,13 +876,19 @@ class GenericStub(six.with_metaclass(abc.ABCMeta)):
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, protocol_options=None):
- """Event-driven invocation of a unary-request-unary-response method.
+ raise NotImplementedError()
+
+ @abc.abstractmethod
+ def event_unary_unary(self,
+ group,
+ method,
+ request,
+ receiver,
+ abortion_callback,
+ timeout,
+ metadata=None,
+ protocol_options=None):
+ """Event-driven invocation of a unary-request-unary-response method.
Args:
group: The group identifier of the RPC.
@@ -843,13 +905,19 @@ class GenericStub(six.with_metaclass(abc.ABCMeta)):
Returns:
A Call for the RPC.
"""
- raise NotImplementedError()
-
- @abc.abstractmethod
- def event_unary_stream(
- self, group, method, request, receiver, abortion_callback, timeout,
- metadata=None, protocol_options=None):
- """Event-driven invocation of a unary-request-stream-response method.
+ raise NotImplementedError()
+
+ @abc.abstractmethod
+ def event_unary_stream(self,
+ group,
+ method,
+ request,
+ receiver,
+ abortion_callback,
+ timeout,
+ metadata=None,
+ protocol_options=None):
+ """Event-driven invocation of a unary-request-stream-response method.
Args:
group: The group identifier of the RPC.
@@ -866,13 +934,18 @@ class GenericStub(six.with_metaclass(abc.ABCMeta)):
Returns:
A Call for the RPC.
"""
- raise NotImplementedError()
-
- @abc.abstractmethod
- def event_stream_unary(
- self, group, method, receiver, abortion_callback, timeout,
- metadata=None, protocol_options=None):
- """Event-driven invocation of a unary-request-unary-response method.
+ raise NotImplementedError()
+
+ @abc.abstractmethod
+ def event_stream_unary(self,
+ group,
+ method,
+ receiver,
+ abortion_callback,
+ timeout,
+ metadata=None,
+ protocol_options=None):
+ """Event-driven invocation of a unary-request-unary-response method.
Args:
group: The group identifier of the RPC.
@@ -889,13 +962,18 @@ class GenericStub(six.with_metaclass(abc.ABCMeta)):
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, protocol_options=None):
- """Event-driven invocation of a unary-request-stream-response method.
+ raise NotImplementedError()
+
+ @abc.abstractmethod
+ def event_stream_stream(self,
+ group,
+ method,
+ receiver,
+ abortion_callback,
+ timeout,
+ metadata=None,
+ protocol_options=None):
+ """Event-driven invocation of a unary-request-stream-response method.
Args:
group: The group identifier of the RPC.
@@ -912,11 +990,11 @@ class GenericStub(six.with_metaclass(abc.ABCMeta)):
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()
+ raise NotImplementedError()
- @abc.abstractmethod
- def unary_unary(self, group, method):
- """Creates a UnaryUnaryMultiCallable for a unary-unary method.
+ @abc.abstractmethod
+ def unary_unary(self, group, method):
+ """Creates a UnaryUnaryMultiCallable for a unary-unary method.
Args:
group: The group identifier of the RPC.
@@ -925,11 +1003,11 @@ class GenericStub(six.with_metaclass(abc.ABCMeta)):
Returns:
A UnaryUnaryMultiCallable value for the named unary-unary method.
"""
- raise NotImplementedError()
+ raise NotImplementedError()
- @abc.abstractmethod
- def unary_stream(self, group, method):
- """Creates a UnaryStreamMultiCallable for a unary-stream method.
+ @abc.abstractmethod
+ def unary_stream(self, group, method):
+ """Creates a UnaryStreamMultiCallable for a unary-stream method.
Args:
group: The group identifier of the RPC.
@@ -938,11 +1016,11 @@ class GenericStub(six.with_metaclass(abc.ABCMeta)):
Returns:
A UnaryStreamMultiCallable value for the name unary-stream method.
"""
- raise NotImplementedError()
+ raise NotImplementedError()
- @abc.abstractmethod
- def stream_unary(self, group, method):
- """Creates a StreamUnaryMultiCallable for a stream-unary method.
+ @abc.abstractmethod
+ def stream_unary(self, group, method):
+ """Creates a StreamUnaryMultiCallable for a stream-unary method.
Args:
group: The group identifier of the RPC.
@@ -951,11 +1029,11 @@ class GenericStub(six.with_metaclass(abc.ABCMeta)):
Returns:
A StreamUnaryMultiCallable value for the named stream-unary method.
"""
- raise NotImplementedError()
+ raise NotImplementedError()
- @abc.abstractmethod
- def stream_stream(self, group, method):
- """Creates a StreamStreamMultiCallable for a stream-stream method.
+ @abc.abstractmethod
+ def stream_stream(self, group, method):
+ """Creates a StreamStreamMultiCallable for a stream-stream method.
Args:
group: The group identifier of the RPC.
@@ -964,11 +1042,11 @@ class GenericStub(six.with_metaclass(abc.ABCMeta)):
Returns:
A StreamStreamMultiCallable value for the named stream-stream method.
"""
- raise NotImplementedError()
+ raise NotImplementedError()
class DynamicStub(six.with_metaclass(abc.ABCMeta)):
- """Affords RPC invocation via attributes corresponding to afforded methods.
+ """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.
diff --git a/src/python/grpcio/grpc/framework/interfaces/face/utilities.py b/src/python/grpcio/grpc/framework/interfaces/face/utilities.py
index db2ec6ed87..39a642f0ae 100644
--- a/src/python/grpcio/grpc/framework/interfaces/face/utilities.py
+++ b/src/python/grpcio/grpc/framework/interfaces/face/utilities.py
@@ -26,7 +26,6 @@
# 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
@@ -38,18 +37,24 @@ 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
+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.
+ """Creates an face.MethodImplementation for the given behavior.
Args:
behavior: The implementation of a unary-unary RPC method as a callable value
@@ -59,13 +64,13 @@ def unary_unary_inline(behavior):
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)
+ 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.
+ """Creates an face.MethodImplementation for the given behavior.
Args:
behavior: The implementation of a unary-stream RPC method as a callable
@@ -75,13 +80,13 @@ def unary_stream_inline(behavior):
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)
+ 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.
+ """Creates an face.MethodImplementation for the given behavior.
Args:
behavior: The implementation of a stream-unary RPC method as a callable
@@ -91,13 +96,13 @@ def stream_unary_inline(behavior):
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)
+ 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.
+ """Creates an face.MethodImplementation for the given behavior.
Args:
behavior: The implementation of a stream-stream RPC method as a callable
@@ -107,13 +112,13 @@ def stream_stream_inline(behavior):
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)
+ 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.
+ """Creates an face.MethodImplementation for the given behavior.
Args:
behavior: The implementation of a unary-unary RPC method as a callable
@@ -123,13 +128,13 @@ def unary_unary_event(behavior):
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)
+ 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.
+ """Creates an face.MethodImplementation for the given behavior.
Args:
behavior: The implementation of a unary-stream RPC method as a callable
@@ -139,13 +144,13 @@ def unary_stream_event(behavior):
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)
+ 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.
+ """Creates an face.MethodImplementation for the given behavior.
Args:
behavior: The implementation of a stream-unary RPC method as a callable
@@ -156,13 +161,13 @@ def stream_unary_event(behavior):
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)
+ 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.
+ """Creates an face.MethodImplementation for the given behavior.
Args:
behavior: The implementation of a stream-stream RPC method as a callable
@@ -173,6 +178,6 @@ def stream_stream_event(behavior):
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)
+ return _MethodImplementation(cardinality.Cardinality.STREAM_STREAM,
+ style.Service.EVENT, None, None, None, None,
+ None, None, None, behavior)
diff --git a/src/python/grpcio/support.py b/src/python/grpcio/support.py
index b226e690fd..a228ba4a48 100644
--- a/src/python/grpcio/support.py
+++ b/src/python/grpcio/support.py
@@ -27,7 +27,6 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
import os
import os.path
import shutil
@@ -38,7 +37,6 @@ from distutils import errors
import commands
-
C_PYTHON_DEV = """
#include <Python.h>
int main(int argc, char **argv) { return 0; }
@@ -55,69 +53,70 @@ Could not find <Python.h>. This could mean the following:
(check your environment variables or try re-installing?)
"""
-C_CHECKS = {
- C_PYTHON_DEV: C_PYTHON_DEV_ERROR_MESSAGE,
-}
+C_CHECKS = {C_PYTHON_DEV: C_PYTHON_DEV_ERROR_MESSAGE,}
+
def _compile(compiler, source_string):
- tempdir = tempfile.mkdtemp()
- cpath = os.path.join(tempdir, 'a.c')
- with open(cpath, 'w') as cfile:
- cfile.write(source_string)
- try:
- compiler.compile([cpath])
- except errors.CompileError as error:
- return error
- finally:
- shutil.rmtree(tempdir)
+ tempdir = tempfile.mkdtemp()
+ cpath = os.path.join(tempdir, 'a.c')
+ with open(cpath, 'w') as cfile:
+ cfile.write(source_string)
+ try:
+ compiler.compile([cpath])
+ except errors.CompileError as error:
+ return error
+ finally:
+ shutil.rmtree(tempdir)
+
def _expect_compile(compiler, source_string, error_message):
- if _compile(compiler, source_string) is not None:
- sys.stderr.write(error_message)
- raise commands.CommandError(
- "Diagnostics found a compilation environment issue:\n{}"
+ if _compile(compiler, source_string) is not None:
+ sys.stderr.write(error_message)
+ raise commands.CommandError(
+ "Diagnostics found a compilation environment issue:\n{}"
.format(error_message))
+
def diagnose_compile_error(build_ext, error):
- """Attempt to diagnose an error during compilation."""
- for c_check, message in C_CHECKS.items():
- _expect_compile(build_ext.compiler, c_check, message)
- python_sources = [
- source for source in build_ext.get_source_files()
- if source.startswith('./src/python') and source.endswith('c')
- ]
- for source in python_sources:
- if not os.path.isfile(source):
- raise commands.CommandError(
- ("Diagnostics found a missing Python extension source file:\n{}\n\n"
- "This is usually because the Cython sources haven't been transpiled "
- "into C yet and you're building from source.\n"
- "Try setting the environment variable "
- "`GRPC_PYTHON_BUILD_WITH_CYTHON=1` when invoking `setup.py` or "
- "when using `pip`, e.g.:\n\n"
- "pip install -rrequirements.txt\n"
- "GRPC_PYTHON_BUILD_WITH_CYTHON=1 pip install .")
- .format(source)
- )
+ """Attempt to diagnose an error during compilation."""
+ for c_check, message in C_CHECKS.items():
+ _expect_compile(build_ext.compiler, c_check, message)
+ python_sources = [
+ source for source in build_ext.get_source_files()
+ if source.startswith('./src/python') and source.endswith('c')
+ ]
+ for source in python_sources:
+ if not os.path.isfile(source):
+ raise commands.CommandError((
+ "Diagnostics found a missing Python extension source file:\n{}\n\n"
+ "This is usually because the Cython sources haven't been transpiled "
+ "into C yet and you're building from source.\n"
+ "Try setting the environment variable "
+ "`GRPC_PYTHON_BUILD_WITH_CYTHON=1` when invoking `setup.py` or "
+ "when using `pip`, e.g.:\n\n"
+ "pip install -rrequirements.txt\n"
+ "GRPC_PYTHON_BUILD_WITH_CYTHON=1 pip install .").format(source))
+
def diagnose_attribute_error(build_ext, error):
- if any('_needs_stub' in arg for arg in error.args):
- raise commands.CommandError(
- "We expect a missing `_needs_stub` attribute from older versions of "
- "setuptools. Consider upgrading setuptools.")
+ if any('_needs_stub' in arg for arg in error.args):
+ raise commands.CommandError(
+ "We expect a missing `_needs_stub` attribute from older versions of "
+ "setuptools. Consider upgrading setuptools.")
+
_ERROR_DIAGNOSES = {
errors.CompileError: diagnose_compile_error,
AttributeError: diagnose_attribute_error
}
-def diagnose_build_ext_error(build_ext, error, formatted):
- diagnostic = _ERROR_DIAGNOSES.get(type(error))
- if diagnostic is None:
- raise commands.CommandError(
- "\n\nWe could not diagnose your build failure. Please file an issue at "
- "http://www.github.com/grpc/grpc with `[Python install]` in the title."
- "\n\n{}".format(formatted))
- else:
- diagnostic(build_ext, error)
+def diagnose_build_ext_error(build_ext, error, formatted):
+ diagnostic = _ERROR_DIAGNOSES.get(type(error))
+ if diagnostic is None:
+ raise commands.CommandError(
+ "\n\nWe could not diagnose your build failure. Please file an issue at "
+ "http://www.github.com/grpc/grpc with `[Python install]` in the title."
+ "\n\n{}".format(formatted))
+ else:
+ diagnostic(build_ext, error)