Skip to content

Commit

Permalink
Manage hitory in priority threads
Browse files Browse the repository at this point in the history
Ref #235
  • Loading branch information
algorys committed Feb 28, 2018
1 parent 99da29c commit f60cfea
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 40 deletions.
29 changes: 7 additions & 22 deletions alignak_app/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ def start(self, username=None, password=None):
requests_interval = int(settings.get_config('Alignak-app', 'requests_interval')) * 1000
self.threadmanager_timer.setInterval(requests_interval)
self.threadmanager_timer.start()
self.threadmanager_timer.timeout.connect(self.launch_threads)
self.threadmanager_timer.timeout.connect(self.check_threads)

self.tray_icon = TrayIcon(QIcon(settings.get_image('icon')))
self.tray_icon.build_menu()
Expand Down Expand Up @@ -235,33 +235,18 @@ def quit_launched_threads(launched_threads):
return launched_threads

@staticmethod
def launch_threads():
def check_threads():
"""
Launch periodically threads
"""

# Cleaning threads who are finished
thread_manager.clean_threads()

# Launch or stop threads
if app_backend.connected:
if not thread_manager.threads_to_launch:
thread_manager.threads_to_launch = thread_manager.get_threads_to_launch()

# In case there is no thread running
if thread_manager.threads_to_launch and not thread_manager.current_thread:
cur_thread = thread_manager.threads_to_launch.pop(0)
backend_thread = BackendQThread(cur_thread)

if app_backend.connected:
backend_thread.start()
thread_manager.current_thread = backend_thread

# Cleaning threads who are finished
if thread_manager.current_thread:
if thread_manager.current_thread.isFinished():
logger.debug('Remove finished thread: %s',
thread_manager.current_thread.thread_name)
thread_manager.current_thread.quit()

thread_manager.current_thread = None
thread_manager.launch_threads()
else:
logger.info('Can\'t launch thread, App is not connected to backend !')
thread_manager.stop_threads()
5 changes: 4 additions & 1 deletion alignak_app/qobjects/panel/host.py
Original file line number Diff line number Diff line change
Expand Up @@ -386,7 +386,10 @@ def update_host(self, hostname=None):
self.history_btn.setEnabled(False)

if app_backend.connected:
thread_manager.add_thread(
thread_manager.add_priority_thread(
'history',
{'hostname': self.host_item.name, 'host_id': self.host_item.item_id}
)
else:
logger.info('Can\'t launch thread, App is not connected to backend !')
thread_manager.stop_threads()
2 changes: 1 addition & 1 deletion alignak_app/qthreads/thread.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ def run(self): # pragma: no cover
"""

if app_backend.connected:
logger.debug('THREAD: launch a new thread for %s', self.thread_name)
logger.debug('Launch a new thread request for backend: %s', self.thread_name)
if 'user' in self.thread_name:
app_backend.query_user_data()
elif 'host' in self.thread_name:
Expand Down
75 changes: 62 additions & 13 deletions alignak_app/qthreads/threadmanager.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@

from logging import getLogger

from PyQt5.Qt import QTimer, QObject
from PyQt5.Qt import QObject

from alignak_app.qthreads.thread import BackendQThread

Expand All @@ -42,8 +42,8 @@ class ThreadManager(QObject):
def __init__(self, parent=None):
super(ThreadManager, self).__init__(parent)
self.current_thread = None
self.priority_threads = []
self.threads_to_launch = self.get_threads_to_launch()
self.timer = QTimer()

def get_threads_to_launch(self):
"""
Expand All @@ -68,35 +68,84 @@ def get_threads_to_launch(self):

return threads_to_launch

def add_thread(self, thread_name, data):
def launch_threads(self):
"""
Add a thread, actually used for new history
Launch periodically threads
:param thread_name: name of thread
"""

if not thread_manager.threads_to_launch:
self.threads_to_launch = self.get_threads_to_launch()

# In case there is no thread running
if self.threads_to_launch and not self.current_thread:
cur_thread = self.threads_to_launch.pop(0)
backend_thread = BackendQThread(cur_thread)
backend_thread.start()

self.current_thread = backend_thread

def clean_threads(self):
"""
TODO
:return:
"""

if self.current_thread:
if self.current_thread.isFinished():
logger.debug('Remove finished thread: %s', self.current_thread.thread_name)
self.current_thread.quit()
self.current_thread = None

if self.priority_threads:
for thread in self.priority_threads:
if thread.isFinished():
thread.quit()
self.priority_threads.remove(thread)
logger.debug('Remove finished thread: %s', thread.thread_name)

def add_priority_thread(self, thread_name, data): # pragma: no cover
"""
Launch a thread with higher priority (doesn't wait launch_threads() function)
:param thread_name: name of priority thread
:type thread_name: str
:param data: data to give to thread for request
:type data: dict
"""

if not self.current_thread:
backend_thread = BackendQThread(thread_name, data)
backend_thread.start()
self.current_thread = backend_thread
backend_thread = BackendQThread(thread_name, data)
backend_thread.start()

self.priority_threads.append(backend_thread)

def stop_threads(self):
"""
Stop ThreadManager and close all running BackendQThreads
"""

self.timer.stop()

if self.current_thread:
logger.debug('Try to quit current thread: %s', self.current_thread.thread_name)
self.current_thread.quit()
# del self.current_thread
self.current_thread = None
logger.info("The backend threads were stopped !")

if self.priority_threads:
self.stop_priority_threads()

logger.debug("Finished backend threads have been stopped !")

def stop_priority_threads(self):
"""
Stop priority threads
"""

for thread in self.priority_threads:
logger.debug('Try to quit current priority thread: %s', thread.thread_name)
thread.quit()

self.priority_threads.remove(thread)


thread_manager = ThreadManager()
15 changes: 12 additions & 3 deletions test/test_thread_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
# along with (AlignakApp). If not, see <http://www.gnu.org/licenses/>.

import unittest2
from PyQt5.Qt import QTimer

from alignak_app.utils.config import settings
from alignak_app.locales.locales import init_localization
Expand All @@ -43,8 +42,7 @@ def test_initialize_thread_manager(self):
under_test = ThreadManager()

self.assertFalse(under_test.current_thread)
self.assertIsNotNone(under_test.timer)
self.assertIsInstance(under_test.timer, QTimer)
self.assertFalse(under_test.priority_threads)
for thread in ['livesynthesis', 'host', 'service', 'user',
'alignakdaemon', 'notifications', 'history']:
self.assertTrue(thread in under_test.threads_to_launch)
Expand All @@ -70,3 +68,14 @@ def test_get_threads_to_launch(self):
self.assertNotEqual([], thread_mgr_test.current_thread)
self.assertTrue('user' not in under_test)

def test_priority_threads(self):
"""Remove Priority Threads"""

under_test = ThreadManager()
under_test.priority_threads.append(BackendQThread('user'))

self.assertTrue(under_test.priority_threads)

under_test.stop_priority_threads()

self.assertFalse(under_test.priority_threads)

0 comments on commit f60cfea

Please sign in to comment.