Skip to content
This repository was archived by the owner on Sep 17, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,7 @@ OpenCensus supports integration with popular web frameworks, client libraries an

- `Django`_
- `Flask`_
- `gevent`_
- `Google Cloud Client Libraries`_
- `gRPC`_
- `httplib`_
Expand Down Expand Up @@ -216,6 +217,7 @@ Stats Exporter
.. _Azure: https://github.com/census-instrumentation/opencensus-python/tree/master/contrib/opencensus-ext-azure
.. _Django: https://github.com/census-instrumentation/opencensus-python/tree/master/contrib/opencensus-ext-django
.. _Flask: https://github.com/census-instrumentation/opencensus-python/tree/master/contrib/opencensus-ext-flask
.. _gevent: https://github.com/census-instrumentation/opencensus-python/tree/master/contrib/opencensus-ext-gevent
.. _Google Cloud Client Libraries: https://github.com/census-instrumentation/opencensus-python/tree/master/contrib/opencensus-ext-google-cloud-clientlibs
.. _gRPC: https://github.com/census-instrumentation/opencensus-python/tree/master/contrib/opencensus-ext-grpc
.. _httplib: https://github.com/census-instrumentation/opencensus-python/tree/master/contrib/opencensus-ext-httplib
Expand Down
5 changes: 5 additions & 0 deletions contrib/opencensus-ext-gevent/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Changelog

## Unreleased

- Initial version
41 changes: 41 additions & 0 deletions contrib/opencensus-ext-gevent/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
OpenCensus gevent helper
============================================================================

|pypi|

.. |pypi| image:: https://badge.fury.io/py/opencensus-ext-gevent.svg
:target: https://pypi.org/project/opencensus-ext-gevent/

Installation
------------

::

pip install opencensus-ext-gevent

Usage
-----

As gevent is to date `incompatible <https://github.com/gevent/gevent/issues/1407>`_ with
the new context variables the **OpenCensus gevent helper** configures OpenCensus to use
a compatible thread based runtime context implementation.

No action apart from installing the package is needed as it listens to events
`emitted by gevent <http://www.gevent.org/api/gevent.monkey.html#plugins>`_ once
patching via ``patch_all`` is complete.


Warning
-------

OpenCensus itself is completely compatible with gevent. Be aware though that not all
available OpenCensus integrations are compatible.

You should check this on a case by case basis.


References
----------

* `OpenCensus Project <https://opencensus.io/>`_
* `gevent <https://www.gevent.org/>`_
1 change: 1 addition & 0 deletions contrib/opencensus-ext-gevent/opencensus/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
__path__ = __import__('pkgutil').extend_path(__path__, __name__)
1 change: 1 addition & 0 deletions contrib/opencensus-ext-gevent/opencensus/ext/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
__path__ = __import__('pkgutil').extend_path(__path__, __name__)
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
__path__ = __import__('pkgutil').extend_path(__path__, __name__)
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import logging
import gevent.monkey


def patch_opencensus(event):
# Switch from the default runtime context using ContextVar to one
# using thread locals. Needed until gevent supports ContextVar.
# See https://github.com/gevent/gevent/issues/1407
import opencensus.common.runtime_context as runtime_context

if not gevent.monkey.is_module_patched("contextvars"):
runtime_context.RuntimeContext = (
runtime_context._ThreadLocalRuntimeContext()
)

logging.warning("OpenCensus patched for gevent compatibility")
else:
logging.warning(
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice!

"OpenCensus is already compatible with your gevent version. "
"Feel free to uninstall the opencensus-ext-gevent package."
)
2 changes: 2 additions & 0 deletions contrib/opencensus-ext-gevent/setup.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[bdist_wheel]
universal = 1
56 changes: 56 additions & 0 deletions contrib/opencensus-ext-gevent/setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Copyright 2019, OpenCensus Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from setuptools import find_packages
from setuptools import setup
from version import __version__

setup(
name='opencensus-ext-gevent',
version=__version__, # noqa
author='OpenCensus Authors',
author_email='census-developers@googlegroups.com',
classifiers=[
'Intended Audience :: Developers',
'Development Status :: 3 - Alpha',
'Intended Audience :: Developers',
'License :: OSI Approved :: Apache Software License',
'Programming Language :: Python',
'Programming Language :: Python :: 2',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7',
],
description='OpenCensus gevent compatibility helper',
include_package_data=True,
long_description=open('README.rst').read(),
install_requires=[
'opencensus >= 0.6.dev0, < 1.0.0',
'gevent >= 1.3'
],
extras_require={},
license='Apache-2.0',
packages=find_packages(exclude=('tests',)),
namespace_packages=[],
url='https://github.com/census-instrumentation/opencensus-python/tree/master/contrib/opencensus-ext-gevent', # noqa: E501
zip_safe=False,
entry_points={
"gevent.plugins.monkey.did_patch_builtins": [
"opencensus = opencensus.ext.gevent.geventcompatibility:patch_opencensus" # noqa: E501
]
},
)
96 changes: 96 additions & 0 deletions contrib/opencensus-ext-gevent/tests/test_patching.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
# Copyright 2019, OpenCensus Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import unittest

import opencensus.common.runtime_context as runtime_context
import gevent.monkey

import mock


class TestPatching(unittest.TestCase):
def setUp(self):
self.original_context = runtime_context.RuntimeContext

def tearDown(self):
runtime_context.RuntimeContext = self.original_context

@mock.patch("gevent.monkey.is_module_patched", return_value=False)
def test_context_is_switched_without_contextvar_support(
self, patched_is_module_patched
):
# patched_is_module_patched.return_value = False

# Trick gevent into thinking it is run for the first time.
# Allows to run multiple tests.
gevent.monkey.saved = {}

# All module patching is disabled to avoid the need of "unpatching".
# The needed events are emitted nevertheless.
gevent.monkey.patch_all(
contextvar=False,
socket=False,
dns=False,
time=False,
select=False,
thread=False,
os=False,
ssl=False,
httplib=False,
subprocess=False,
sys=False,
aggressive=False,
Event=False,
builtins=False,
signal=False,
queue=False
)

assert isinstance(
runtime_context.RuntimeContext,
runtime_context._ThreadLocalRuntimeContext,
)

@mock.patch("gevent.monkey.is_module_patched", return_value=True)
def test_context_is_switched_with_contextvar_support(
self, patched_is_module_patched
):

# Trick gevent into thinking it is run for the first time.
# Allows to run multiple tests.
gevent.monkey.saved = {}

# All module patching is disabled to avoid the need of "unpatching".
# The needed events are emitted nevertheless.
gevent.monkey.patch_all(
contextvar=False,
socket=False,
dns=False,
time=False,
select=False,
thread=False,
os=False,
ssl=False,
httplib=False,
subprocess=False,
sys=False,
aggressive=False,
Event=False,
builtins=False,
signal=False,
queue=False
)

assert runtime_context.RuntimeContext is self.original_context
15 changes: 15 additions & 0 deletions contrib/opencensus-ext-gevent/version.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Copyright 2019, OpenCensus Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

__version__ = '0.1.dev0'
1 change: 1 addition & 0 deletions nox.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ def _install_dev_packages(session):
session.install('-e', 'contrib/opencensus-ext-dbapi')
session.install('-e', 'contrib/opencensus-ext-django')
session.install('-e', 'contrib/opencensus-ext-flask')
session.install('-e', 'contrib/opencensus-ext-gevent')
session.install('-e', 'contrib/opencensus-ext-grpc')
session.install('-e', 'contrib/opencensus-ext-httplib')
session.install('-e', 'contrib/opencensus-ext-jaeger')
Expand Down