Skip to content

Instantly share code, notes, and snippets.

@cooperreid-optimizely
Last active June 13, 2017 17:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cooperreid-optimizely/4d57682b39deb3557d437ae79c991eb3 to your computer and use it in GitHub Desktop.
Save cooperreid-optimizely/4d57682b39deb3557d437ae79c991eb3 to your computer and use it in GitHub Desktop.
# Copyright 2016, Optimizely
# 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 json
import logging
import grequests
from requests import exceptions as request_exception
from optimizely.helpers import enums
REQUEST_TIMEOUT = 10
class AsyncEventDispatcher(object):
@staticmethod
def dispatch_event(event):
""" Dispatch the event being represented by the Event object.
Args:
event: Object holding information about the request to be dispatched to the Optimizely backend.
"""
try:
if event.http_verb == enums.HTTPVerbs.GET:
unsent_req = [grequests.get(event.url, params=event.params, timeout=REQUEST_TIMEOUT)]
grequests.map(unsent_req)
elif event.http_verb == enums.HTTPVerbs.POST:
unsent_req = [grequests.post(event.url, data=json.dumps(event.params), headers=event.headers, timeout=REQUEST_TIMEOUT)]
grequests.map(unsent_req)
except request_exception.RequestException as error:
logging.error('Dispatch event failed. Error: %s' % str(error))
@cooperreid-optimizely
Copy link
Author

cooperreid-optimizely commented May 15, 2017

Install grequests package for async http requests

pip install grequests

instantiate client with async event dispatcher

from async_event_dispatcher import AsyncEventDispatcher
optimizely.Optimizely(datafile, event_dispatcher=AsyncEventDispatcher)

@mhb11
Copy link

mhb11 commented May 27, 2017

I just tried this asynch event dispatcher with an Optimizely full stack experiment (Django project, using PSQL and Redis backend, gunicorn+nginx reverse proxy). It ends up throwing an exception: ('This operation would block forever', <Hub at 0x7f5230a08230 epoll pending=0 ref=0 fileno=23>)

Full traceback:

Traceback (most recent call last):
  File "/home/myuser/.virtualenvs/myenv/local/lib/python2.7/site-packages/django/core/handlers/base.py", line 115, in get_response
    response = callback(request, *callback_args, **callback_kwargs)
  File "/home/myuser/.virtualenvs/myenv/local/lib/python2.7/site-packages/newrelic-2.56.0.42/newrelic/hooks/framework_django.py", line 499, in wrapper
    return wrapped(*args, **kwargs)
  File "/home/myuser/.virtualenvs/myenv/local/lib/python2.7/site-packages/django/utils/decorators.py", line 91, in _wrapped_view
    response = view_func(request, *args, **kwargs)
  File "/home/myuser/Desktop/myproject/links/views.py", line 2868, in create_nick
    elif account_creation_disallowed(getip(request)):
  File "/home/myuser/Desktop/myproject/links/redis1.py", line 255, in account_creation_disallowed
    if my_server.exists(registered_ip):
  File "/home/myuser/.virtualenvs/myenv/local/lib/python2.7/site-packages/newrelic-2.56.0.42/newrelic/api/datastore_trace.py", line 70, in _nr_datastore_trace_wrapper_
    return wrapped(*args, **kwargs)
  File "/home/myuser/.virtualenvs/myenv/local/lib/python2.7/site-packages/redis/client.py", line 838, in exists
    return self.execute_command('EXISTS', name)
  File "/home/myuser/.virtualenvs/myenv/local/lib/python2.7/site-packages/redis/client.py", line 565, in execute_command
    return self.parse_response(connection, command_name, **options)
  File "/home/myuser/.virtualenvs/myenv/local/lib/python2.7/site-packages/redis/client.py", line 577, in parse_response
    response = connection.read_response()
  File "/home/myuser/.virtualenvs/myenv/local/lib/python2.7/site-packages/redis/connection.py", line 569, in read_response
    response = self._parser.read_response()
  File "/home/myuser/.virtualenvs/myenv/local/lib/python2.7/site-packages/redis/connection.py", line 224, in read_response
    response = self._buffer.readline()
  File "/home/myuser/.virtualenvs/myenv/local/lib/python2.7/site-packages/redis/connection.py", line 162, in readline
    self._read_from_socket()
  File "/home/myuser/.virtualenvs/myenv/local/lib/python2.7/site-packages/redis/connection.py", line 120, in _read_from_socket
    data = self._sock.recv(socket_read_size)
  File "/home/myuser/.virtualenvs/myenv/local/lib/python2.7/site-packages/gevent/_socket2.py", line 283, in recv
    self._wait(self._read_event)
  File "/home/myuser/.virtualenvs/myenv/local/lib/python2.7/site-packages/gevent/_socket2.py", line 182, in _wait
    self.hub.wait(watcher)
  File "/home/myuser/.virtualenvs/myenv/local/lib/python2.7/site-packages/gevent/hub.py", line 651, in wait
    result = waiter.get()
  File "/home/myuser/.virtualenvs/myenv/local/lib/python2.7/site-packages/gevent/hub.py", line 899, in get
    return self.hub.switch()
  File "/home/myuser/.virtualenvs/myenv/local/lib/python2.7/site-packages/gevent/hub.py", line 630, in switch
    return RawGreenlet.switch(self)
LoopExit: ('This operation would block forever', <Hub at 0x7f5230a08230 epoll pending=0 ref=0 fileno=23>)

@cooperreid-optimizely
Copy link
Author

cooperreid-optimizely commented Jun 13, 2017

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment