New events and service calls now use a shared thread pool
This commit is contained in:
parent
70d2506e01
commit
2758d81525
2 changed files with 151 additions and 57 deletions
|
@ -1,5 +1,6 @@
|
|||
""" Helper methods for various modules. """
|
||||
|
||||
import threading
|
||||
import Queue
|
||||
import datetime
|
||||
import re
|
||||
|
||||
|
@ -53,3 +54,56 @@ def filter_entity_ids(entity_ids, domain_filter=None, strip_domain=False):
|
|||
for entity_id in entity_ids if
|
||||
not domain_filter or entity_id.startswith(domain_filter)
|
||||
]
|
||||
|
||||
|
||||
def repr_helper(inp):
|
||||
""" Helps creating a more readable string representation of objects. """
|
||||
if isinstance(inp, dict):
|
||||
return ", ".join(
|
||||
repr_helper(key)+"="+repr_helper(item) for key, item in inp.items()
|
||||
)
|
||||
elif isinstance(inp, list):
|
||||
return '[' + ', '.join(inp) + ']'
|
||||
elif isinstance(inp, datetime.datetime):
|
||||
return datetime_to_str(inp)
|
||||
else:
|
||||
return str(inp)
|
||||
|
||||
|
||||
# Reason why I decided to roll my own ThreadPool instead of using
|
||||
# multiprocessing.dummy.pool or even better, use multiprocessing.pool and
|
||||
# not be hurt by the GIL in the cpython interpreter:
|
||||
# 1. The built in threadpool does not allow me to create custom workers and so
|
||||
# I would have to wrap every listener that I passed into it with code to log
|
||||
# the exceptions. Saving a reference to the logger in the worker seemed
|
||||
# like a more sane thing to do.
|
||||
# 2. Most event listeners are simple checks if attributes match. If the method
|
||||
# that they will call takes a long time to complete it might be better to
|
||||
# put that request in a seperate thread. This is for every component to
|
||||
# decide on its own instead of enforcing it for everyone.
|
||||
class ThreadPool(object):
|
||||
""" A simple queue-based thread pool.
|
||||
|
||||
Will initiate it's workers using worker(queue).start() """
|
||||
|
||||
# pylint: disable=too-few-public-methods
|
||||
def __init__(self, worker_count, job_handler):
|
||||
queue = self.queue = Queue.Queue()
|
||||
|
||||
for _ in xrange(worker_count):
|
||||
worker = threading.Thread(target=_threadpool_worker,
|
||||
args=(queue, job_handler))
|
||||
worker.daemon = True
|
||||
worker.start()
|
||||
|
||||
def add_job(self, *args):
|
||||
""" Add a job to be sent to the workers. """
|
||||
self.queue.put(args)
|
||||
|
||||
|
||||
def _threadpool_worker(queue, job_handler):
|
||||
""" Provides the base functionality of a worker for the thread pool. """
|
||||
while True:
|
||||
job = queue.get()
|
||||
job_handler(job)
|
||||
queue.task_done()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue