Skip to content

Instantly share code, notes, and snippets.

@daniel-garcia
Created September 16, 2014 18:49
Show Gist options
  • Save daniel-garcia/4d8853ab60b202e4254c to your computer and use it in GitHub Desktop.
Save daniel-garcia/4d8853ab60b202e4254c to your computer and use it in GitHub Desktop.
patch to metricpublisher to lock connection before performing redis operations
diff --git a/Products/ZenHub/metricpublisher/publisher.py b/Products/ZenHub/metricpublisher/publisher.py
index 96872c2..7c4ae85 100644
--- a/Products/ZenHub/metricpublisher/publisher.py
+++ b/Products/ZenHub/metricpublisher/publisher.py
@@ -20,6 +20,7 @@ from twisted.web.iweb import IBodyProducer
from twisted.web.http_headers import Headers
from zope.interface import implements
from txredis import RedisClientFactory
+from threading import Lock
import json as _stdlib_json
from .compat import json
@@ -135,6 +136,7 @@ class RedisListPublisher(BasePublisher):
self._connection = reactor.connectTCP(self._host,
self._port,
self._redis)
+ self._connection_lock = Lock()
reactor.addSystemEventTrigger('before', 'shutdown', self._shutdown)
def build_metric(self, metric, value, timestamp, tags):
@@ -180,6 +182,11 @@ class RedisListPublisher(BasePublisher):
@defer.inlineCallbacks
def _flush():
+ # try to get lock on connection
+ if not self._connection_lock.acquire(False):
+ # could not get lock, another call to _flush() must be running
+ yield defer.succeed(0)
+ raise StopIteration
client = self._redis.client
try:
yield client.multi()
@@ -195,6 +202,8 @@ class RedisListPublisher(BasePublisher):
except Exception:
pass
self._publish_failed(e, metrics=metrics)
+ finally:
+ self._connection_lock.release()
return _flush()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment