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

fromani at redhat.com fromani at redhat.com
Mon Jan 25 16:13:53 UTC 2016


Hello Piotr Kliczewski, Nir Soffer,

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

    https://gerrit.ovirt.org/52699

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.

3.5 backport notice:
- concurrent.py is not available on this branch, hence
- concurrent.thread was moved in utils.py
- concurrentTests were moved in utilsTests.py

Change-Id: I92bbf3ea55365e110038d5d50f200d5fc8a6a06f
Signed-off-by: Nir Soffer <nsoffer at redhat.com>
Bug-Url: https://bugzilla.redhat.com/1269424
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/utils.py
M tests/utilsTests.py
2 files changed, 71 insertions(+), 0 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/99/52699/1

diff --git a/lib/vdsm/utils.py b/lib/vdsm/utils.py
index 09aa219..dcbe5c9 100644
--- a/lib/vdsm/utils.py
+++ b/lib/vdsm/utils.py
@@ -1413,3 +1413,29 @@
         return func(inst, *args, **kwargs)
 
     return wrapper
+
+
+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.
+    """
+    @traceback(on=logger)
+    def run():
+        return func(*args)
+
+    thread = threading.Thread(target=run, name=name)
+    thread.daemon = daemon
+    return thread
diff --git a/tests/utilsTests.py b/tests/utilsTests.py
index 7970993..634bd97 100644
--- a/tests/utilsTests.py
+++ b/tests/utilsTests.py
@@ -808,3 +808,48 @@
         with utils.stopwatch("message", log=log):
             pass
         self.assertEqual(log.messages, [])
+
+
+class ThreadTests(TestCaseBase):
+
+    def test_run_callable_in_thread(self):
+        self.thread = threading.current_thread()
+
+        def run():
+            self.thread = threading.current_thread()
+
+        t = utils.thread(run)
+        t.start()
+        t.join()
+        self.assertEqual(t, self.thread)
+
+    def test_default_daemon_thread(self):
+        t = utils.thread(lambda: None)
+        t.start()
+        try:
+            self.assertTrue(t.daemon)
+        finally:
+            t.join()
+
+    def test_non_daemon_thread(self):
+        t = utils.thread(lambda: None, daemon=False)
+        t.start()
+        try:
+            self.assertFalse(t.daemon)
+        finally:
+            t.join()
+
+    def test_name(self):
+        t = utils.thread(lambda: None, name="foobar")
+        self.assertEqual("foobar", t.name)
+
+    def test_pass_args(self):
+        self.args = ()
+
+        def run(*args):
+            self.args = args
+
+        t = utils.thread(run, args=(1, 2, 3))
+        t.start()
+        t.join()
+        self.assertEqual((1, 2, 3), self.args)


-- 
To view, visit https://gerrit.ovirt.org/52699
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.5
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