From ecc4a478caac474a57ba0f2d53b550a9ee6081b6 Mon Sep 17 00:00:00 2001 From: Dominic Cerquetti Date: Sat, 20 Aug 2016 10:15:08 -0400 Subject: [PATCH 1/5] set thread names on startup - this code monkeypatches the start of each thread to call prctl() which sets the thread name - this allows external utilities, like top and ps, to show thread names - this is great because if a particular thread is going off the rails, we can now see which one using external tools - requires build-package and libcap to be installed on the system --- requirements.txt | 1 + sideboard/lib/_threads.py | 16 ++++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/requirements.txt b/requirements.txt index ae3f855..d3df306 100644 --- a/requirements.txt +++ b/requirements.txt @@ -16,3 +16,4 @@ paver==1.2.2 wheel==0.24.0 pip==1.5.6 sh==1.09 +python-prctl==1.6.1 \ No newline at end of file diff --git a/sideboard/lib/_threads.py b/sideboard/lib/_threads.py index c8b8d37..614ce6c 100644 --- a/sideboard/lib/_threads.py +++ b/sideboard/lib/_threads.py @@ -1,6 +1,8 @@ from __future__ import unicode_literals import time import heapq +import prctl +import threading from warnings import warn from threading import Thread, Timer, Event, Lock @@ -8,6 +10,20 @@ from sideboard.lib import log, on_startup, on_shutdown +# inject our own code at the start of every thread's start() method which sets the thread name via prctl(). +# This is an optional but nice thing. Python thread names will now be shown in +# external system tools like 'top', '/proc', etc. +def _thread_name_insert(self): + if self.name: + # linux doesn't allow thread names > 15 chars, and we ideally want to see the end of the name. + # attempt to shorten the name if we need to. + shorter_name = self.name if len(self.name) < 15 else self.name.replace('CP Server Thread', 'CPServ') + prctl.set_name(shorter_name) + threading.Thread._bootstrap_inner_original(self) +threading.Thread._bootstrap_inner_original = threading.Thread._bootstrap_inner +threading.Thread._bootstrap_inner = _thread_name_insert + +prctl.set_name("sideboard") class DaemonTask(object): def __init__(self, func, interval=0.1, threads=1): From 6b51bcacaa5133a619a75e79fdb06a7826d198e8 Mon Sep 17 00:00:00 2001 From: Eli Courtwright Date: Sun, 21 Aug 2016 01:32:57 -0400 Subject: [PATCH 2/5] made use of prctl switch on Python version --- requirements.txt | 1 - setup.py | 4 ++++ sideboard/lib/_threads.py | 33 ++++++++++++++++++--------------- 3 files changed, 22 insertions(+), 16 deletions(-) diff --git a/requirements.txt b/requirements.txt index d3df306..ae3f855 100644 --- a/requirements.txt +++ b/requirements.txt @@ -16,4 +16,3 @@ paver==1.2.2 wheel==0.24.0 pip==1.5.6 sh==1.09 -python-prctl==1.6.1 \ No newline at end of file diff --git a/setup.py b/setup.py index 0fd3cf0..f4c452e 100644 --- a/setup.py +++ b/setup.py @@ -18,6 +18,10 @@ if sys.version_info[0] == 2: requires = ['CherryPy==3.2.2' if 'cherrypy' in r.lower() else r for r in requires] +# We use a Python3-only library to set thread names +if sys.version_info[0] == 3: + requires.append('python-prctl==1.6.1') + if __name__ == '__main__': setup( name=pkg_name, diff --git a/sideboard/lib/_threads.py b/sideboard/lib/_threads.py index 614ce6c..18f7c49 100644 --- a/sideboard/lib/_threads.py +++ b/sideboard/lib/_threads.py @@ -1,7 +1,6 @@ from __future__ import unicode_literals import time import heapq -import prctl import threading from warnings import warn from threading import Thread, Timer, Event, Lock @@ -10,20 +9,24 @@ from sideboard.lib import log, on_startup, on_shutdown -# inject our own code at the start of every thread's start() method which sets the thread name via prctl(). -# This is an optional but nice thing. Python thread names will now be shown in -# external system tools like 'top', '/proc', etc. -def _thread_name_insert(self): - if self.name: - # linux doesn't allow thread names > 15 chars, and we ideally want to see the end of the name. - # attempt to shorten the name if we need to. - shorter_name = self.name if len(self.name) < 15 else self.name.replace('CP Server Thread', 'CPServ') - prctl.set_name(shorter_name) - threading.Thread._bootstrap_inner_original(self) -threading.Thread._bootstrap_inner_original = threading.Thread._bootstrap_inner -threading.Thread._bootstrap_inner = _thread_name_insert - -prctl.set_name("sideboard") +try: + import prctl # only runs on Python 3 +except ImportError: + pass +else: + # inject our own code at the start of every thread's start() method which sets the thread name via prctl(). + # Python thread names will now be shown in external system tools like 'top', '/proc', etc. + def _thread_name_insert(self): + if self.name: + # linux doesn't allow thread names > 15 chars, and we ideally want to see the end of the name. + # attempt to shorten the name if we need to. + shorter_name = self.name if len(self.name) < 15 else self.name.replace('CP Server Thread', 'CPServ') + prctl.set_name(shorter_name) + threading.Thread._bootstrap_inner_original(self) + threading.Thread._bootstrap_inner_original = threading.Thread._bootstrap_inner + threading.Thread._bootstrap_inner = _thread_name_insert + prctl.set_name('sideboard') + class DaemonTask(object): def __init__(self, func, interval=0.1, threads=1): From 51a6473434c5034baa0993dcdc3994817e2944ca Mon Sep 17 00:00:00 2001 From: Dominic Cerquetti Date: Sun, 21 Aug 2016 15:11:34 -0400 Subject: [PATCH 3/5] install libcap for travis builds - required for use in prctl module calls (thread naming setting) --- .travis.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.travis.yml b/.travis.yml index 9b35c7d..0860e96 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,6 +4,9 @@ env: - TOX_ENV=py27 - TOX_ENV=py33 - TOX_ENV=py34 +before_install: + - sudo apt-get -qq update + - sudo apt-get install -y libcap install: - pip install tox - pip install python-coveralls From da18ab6b7d69cf3c2a559ada75374b3af7ed0c78 Mon Sep 17 00:00:00 2001 From: Dominic Cerquetti Date: Sun, 21 Aug 2016 15:14:49 -0400 Subject: [PATCH 4/5] install libcap-dev for travis builds instead of just libcap - required for use in prctl module calls (thread naming setting) --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 0860e96..59d3f0a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,7 +6,7 @@ env: - TOX_ENV=py34 before_install: - sudo apt-get -qq update - - sudo apt-get install -y libcap + - sudo apt-get install -y build-essential libcap-dev install: - pip install tox - pip install python-coveralls From 0c3b3d0756e45bb190a02fa5f8e1395991324beb Mon Sep 17 00:00:00 2001 From: Dominic Cerquetti Date: Sun, 21 Aug 2016 15:47:39 -0400 Subject: [PATCH 5/5] fix python2 prctl dependencies / install / thread bootstrap function --- requirements.txt | 1 + setup.py | 4 ---- sideboard/lib/_threads.py | 34 +++++++++++++++++++--------------- 3 files changed, 20 insertions(+), 19 deletions(-) diff --git a/requirements.txt b/requirements.txt index ae3f855..d3df306 100644 --- a/requirements.txt +++ b/requirements.txt @@ -16,3 +16,4 @@ paver==1.2.2 wheel==0.24.0 pip==1.5.6 sh==1.09 +python-prctl==1.6.1 \ No newline at end of file diff --git a/setup.py b/setup.py index f4c452e..0fd3cf0 100644 --- a/setup.py +++ b/setup.py @@ -18,10 +18,6 @@ if sys.version_info[0] == 2: requires = ['CherryPy==3.2.2' if 'cherrypy' in r.lower() else r for r in requires] -# We use a Python3-only library to set thread names -if sys.version_info[0] == 3: - requires.append('python-prctl==1.6.1') - if __name__ == '__main__': setup( name=pkg_name, diff --git a/sideboard/lib/_threads.py b/sideboard/lib/_threads.py index 18f7c49..d493821 100644 --- a/sideboard/lib/_threads.py +++ b/sideboard/lib/_threads.py @@ -1,7 +1,9 @@ from __future__ import unicode_literals import time import heapq +import prctl import threading +import sys from warnings import warn from threading import Thread, Timer, Event, Lock @@ -9,23 +11,25 @@ from sideboard.lib import log, on_startup, on_shutdown -try: - import prctl # only runs on Python 3 -except ImportError: - pass -else: - # inject our own code at the start of every thread's start() method which sets the thread name via prctl(). - # Python thread names will now be shown in external system tools like 'top', '/proc', etc. - def _thread_name_insert(self): - if self.name: - # linux doesn't allow thread names > 15 chars, and we ideally want to see the end of the name. - # attempt to shorten the name if we need to. - shorter_name = self.name if len(self.name) < 15 else self.name.replace('CP Server Thread', 'CPServ') - prctl.set_name(shorter_name) - threading.Thread._bootstrap_inner_original(self) + +# inject our own code at the start of every thread's start() method which sets the thread name via prctl(). +# Python thread names will now be shown in external system tools like 'top', '/proc', etc. +def _thread_name_insert(self): + if self.name: + # linux doesn't allow thread names > 15 chars, and we ideally want to see the end of the name. + # attempt to shorten the name if we need to. + shorter_name = self.name if len(self.name) < 15 else self.name.replace('CP Server Thread', 'CPServ') + prctl.set_name(shorter_name) + threading.Thread._bootstrap_inner_original(self) +if sys.version_info[0] == 3: threading.Thread._bootstrap_inner_original = threading.Thread._bootstrap_inner threading.Thread._bootstrap_inner = _thread_name_insert - prctl.set_name('sideboard') +else: + threading.Thread._bootstrap_inner_original = threading.Thread._Thread__bootstrap + threading.Thread._Thread__bootstrap = _thread_name_insert + +# set the name of the main thread +prctl.set_name('sideboard_main') class DaemonTask(object):