/manager/slang/maintainer.py

https://github.com/SLANG-foundation/SLANG
Python | 138 lines | 101 code | 16 blank | 21 comment | 1 complexity | ad71d71b81626f6b58772ac227eba65b MD5 | raw file
  1. #! /usr/bin/python
  2. #
  3. # maintainer.py
  4. #
  5. # A Maintainer taking care of periodic maintenance. Run in a separate thread.
  6. #
  7. import threading
  8. from time import time, sleep
  9. import logging
  10. import resource
  11. import config
  12. class Maintainer(threading.Thread):
  13. """ Performs maintenance operations at regular intervals.
  14. """
  15. flush_interval = 1
  16. delete_interval = 600
  17. reload_interval = 3600
  18. logger = None
  19. pstore = None
  20. manager = None
  21. thread_stop = False
  22. last_flush = None
  23. last_delete = None
  24. last_reload = None
  25. def __init__(self, pstore, manager):
  26. """ Constructor.
  27. Creates an instance of the Maintainer-object.
  28. """
  29. threading.Thread.__init__(self, name=self.__class__.__name__)
  30. self.logger = logging.getLogger(self.__class__.__name__)
  31. self.config = config.Config()
  32. self.manager = manager
  33. # save ProbeStorage instance
  34. self.pstore = pstore
  35. # initialize time tracking instance variables
  36. self.last_flush = time()
  37. self.last_delete = time()
  38. self.last_reload = time()
  39. self.last_pstore_aggr = (
  40. (int(time() * 1000000000) / self.pstore.AGGR_DB_LOWRES) *
  41. self.pstore.AGGR_DB_LOWRES + 2*self.pstore.AGGR_DB_LOWRES)
  42. def run(self):
  43. """ Starts thread.
  44. Start the Maintainer's infinite loop.
  45. """
  46. self.logger.debug("Starting thread")
  47. while True:
  48. if self.thread_stop:
  49. break
  50. t_s = time()
  51. # flush lowres aggregates to highres aggregates
  52. # If we are behind, run many times!
  53. while (t_s - self.last_flush) >= self.flush_interval:
  54. ctime = self.last_flush + 1
  55. self.pstore.flush(ctime)
  56. self.last_flush = ctime
  57. # remove old data from database, 30min HIGHRES and 24h LOWRES
  58. if (t_s - self.last_delete) >= self.delete_interval:
  59. self.pstore.delete(1800, 3600*24)
  60. self.last_delete = t_s
  61. # reload every hour
  62. if (t_s - self.last_reload) >= self.reload_interval:
  63. try:
  64. self.manager.reload()
  65. except Exception, e:
  66. self.logger.error("Maintenace reload operation failed: %s"
  67. % str(e))
  68. self.last_reload = t_s
  69. # save precalculated aggregates to database
  70. #
  71. # run when we are certain that we have all data for previous
  72. # aggr_db_lowres
  73. if (t_s * 1000000000 > (
  74. self.last_pstore_aggr +
  75. self.pstore.AGGR_DB_LOWRES +
  76. self.pstore.HIGHRES_INTERVAL +
  77. self.pstore.TIMEOUT + 2*1000000000)):
  78. t_start = t_s
  79. # the previous lowres interval
  80. age = self.last_pstore_aggr
  81. self.logger.debug("Aggregating; current lowres interval: %d will aggregate: %d current time: %d" % (((int(t_start * 1000000000) / self.pstore.AGGR_DB_LOWRES) * self.pstore.AGGR_DB_LOWRES) / 1000000000, age/1000000000, int(t_start) ))
  82. try:
  83. self.pstore.aggregate(age)
  84. except Exception, e:
  85. self.logger.error("aggregation failed with %s: %s. Missing valid measurement data?" % (str(type(e)), str(e)))
  86. self.last_pstore_aggr = ((int(t_start * 1000000000) / self.pstore.AGGR_DB_LOWRES) * self.pstore.AGGR_DB_LOWRES)
  87. t_stop = time()
  88. self.logger.debug("Aggregation performed in %.3f seconds" % (t_stop - t_start))
  89. self.logger.debug("thread %d run time: %f s" %
  90. (self.ident, resource.getrusage(1)[0]))
  91. self.manager.run_stats()
  92. sleep(1)
  93. def stop(self):
  94. """ Stop thread.
  95. Sets the stop-flag which will make the Maintainer thread stop
  96. during its next iteration.
  97. """
  98. self.thread_stop = True