Change in vdsm[ovirt-3.6]: concurrent: Introduce concurrent.thread() utility

fromani at redhat.com fromani at redhat.com
Fri Jan 22 14:17:45 UTC 2016


Hello Piotr Kliczewski, Nir Soffer,

I'd like you to do a code review.  Please visit

    https://gerrit.ovirt.org/52624

to review the following change.

Change subject: concurrent: Introduce concurrent.thread() utility
......................................................................

concurrent: Introduce concurrent.thread() utility

We are repeating this boilerplate code everywhere:

    def __init__(self):
        self._thread = threading.Thread(target=self._run, name="foobar")
        self._thread.daemon = True

    @utils.traceback(on=log.name)
    def _run(self):
        # stuff to run in thread

This boilerplate is going to become worse since we want to set thread
system name in the thread target method.

This patch introduces concurrent.thread() utility function, eliminating
the boilerplate:

    def __init__(self):
        self._thread = concurrent.thread(self._run, name="foobar",
                                         logger=self.log.name)

    def _run(self):
        # stuff to run in thread

This utility will be extended later to set system thread name based on
Python thread name.

Change-Id: I92bbf3ea55365e110038d5d50f200d5fc8a6a06f
Signed-off-by: Nir Soffer <nsoffer at redhat.com>
Reviewed-on: https://gerrit.ovirt.org/44894
Continuous-Integration: Jenkins CI
Reviewed-by: Francesco Romani <fromani at redhat.com>
Reviewed-by: Piotr Kliczewski <piotr.kliczewski at gmail.com>
---
M lib/vdsm/concurrent.py
M tests/concurrentTests.py
2 files changed, 72 insertions(+), 0 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/24/52624/1

diff --git a/lib/vdsm/concurrent.py b/lib/vdsm/concurrent.py
index 6d9890b..5a9df85 100644
--- a/lib/vdsm/concurrent.py
+++ b/lib/vdsm/concurrent.py
@@ -21,6 +21,7 @@
 from __future__ import absolute_import
 import threading
 from collections import namedtuple
+
 from . import utils
 
 
@@ -148,3 +149,29 @@
         t.join()
 
     return results
+
+
+def thread(func, args=(), name=None, daemon=True, logger=None):
+    """
+    Create a thread for runnning func with args.
+
+    Arguments:
+
+    func        Function to run in a new thread.
+
+    args        Arguments to pass to func
+
+    name        If set, set thread name.
+
+    daemon      If True, create a daemon thread.
+
+    logger      If set, unhandled exception will be logged on this logger.
+                Otherwise the root logger will be used.
+    """
+    @utils.traceback(on=logger)
+    def run():
+        return func(*args)
+
+    thread = threading.Thread(target=run, name=name)
+    thread.daemon = daemon
+    return thread
diff --git a/tests/concurrentTests.py b/tests/concurrentTests.py
index e9c35b0..62ca833 100644
--- a/tests/concurrentTests.py
+++ b/tests/concurrentTests.py
@@ -184,3 +184,48 @@
         results = concurrent.tmap(func, range(10))
         expected = [concurrent.Result(False, error)] * 10
         self.assertEqual(results, expected)
+
+
+class ThreadTests(VdsmTestCase):
+
+    def test_run_callable_in_thread(self):
+        self.thread = threading.current_thread()
+
+        def run():
+            self.thread = threading.current_thread()
+
+        t = concurrent.thread(run)
+        t.start()
+        t.join()
+        self.assertEqual(t, self.thread)
+
+    def test_default_daemon_thread(self):
+        t = concurrent.thread(lambda: None)
+        t.start()
+        try:
+            self.assertTrue(t.daemon)
+        finally:
+            t.join()
+
+    def test_non_daemon_thread(self):
+        t = concurrent.thread(lambda: None, daemon=False)
+        t.start()
+        try:
+            self.assertFalse(t.daemon)
+        finally:
+            t.join()
+
+    def test_name(self):
+        t = concurrent.thread(lambda: None, name="foobar")
+        self.assertEqual("foobar", t.name)
+
+    def test_pass_args(self):
+        self.args = ()
+
+        def run(*args):
+            self.args = args
+
+        t = concurrent.thread(run, args=(1, 2, 3))
+        t.start()
+        t.join()
+        self.assertEqual((1, 2, 3), self.args)


-- 
To view, visit https://gerrit.ovirt.org/52624
To unsubscribe, visit https://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I92bbf3ea55365e110038d5d50f200d5fc8a6a06f
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: ovirt-3.6
Gerrit-Owner: Francesco Romani <fromani at redhat.com>
Gerrit-Reviewer: Nir Soffer <nsoffer at redhat.com>
Gerrit-Reviewer: Piotr Kliczewski <piotr.kliczewski at gmail.com>


More information about the vdsm-patches mailing list