http.py 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. ########################################################################
  2. # Searx-Qt - Lightweight desktop application for Searx.
  3. # Copyright (C) 2020-2024 CYBERDEViL
  4. #
  5. # This file is part of Searx-Qt.
  6. #
  7. # Searx-Qt is free software: you can redistribute it and/or modify
  8. # it under the terms of the GNU General Public License as published by
  9. # the Free Software Foundation, either version 3 of the License, or
  10. # (at your option) any later version.
  11. #
  12. # Searx-Qt is distributed in the hope that it will be useful,
  13. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. # GNU General Public License for more details.
  16. #
  17. # You should have received a copy of the GNU General Public License
  18. # along with this program. If not, see <https://www.gnu.org/licenses/>.
  19. #
  20. ########################################################################
  21. from PyQt5.QtCore import QTimer
  22. from searxqt.core import log
  23. from searxqt.core.http import HttpThread
  24. class _ThreadManager:
  25. Tick = 200
  26. MaxIdleTicks = 20 # 4 seconds with 200ms tick rate
  27. def __init__(self):
  28. self._thread = None
  29. self._openCount = 0
  30. self._idleTicks = 0
  31. self._timer = QTimer()
  32. self._timer.timeout.connect(self.updateState)
  33. @property
  34. def thread(self):
  35. return self._thread
  36. def get(self, response):
  37. if self.thread is None:
  38. self.start()
  39. self._openCount += 1
  40. self.thread.get(response)
  41. def cancelAll(self):
  42. if self.thread is not None:
  43. self.thread.cancelAll()
  44. self._openCount = 0
  45. def start(self):
  46. if self.thread is not None:
  47. log.error("start() 'self.thread is not None'.", self)
  48. return
  49. self._thread = HttpThread()
  50. self._openCount = 0
  51. self._idleTicks = 0
  52. self.thread.start()
  53. self._timer.start(self.Tick)
  54. log.debug("Http.Thread started")
  55. def stop(self):
  56. self.thread.cancelAll()
  57. self.thread.exit()
  58. self._timer.stop()
  59. self._openCount = 0
  60. self._idleTicks = 0
  61. self._thread = None
  62. log.debug("Http.Thread stopped")
  63. def updateState(self):
  64. if not self.thread:
  65. return
  66. n = self.thread.processCallbacks()
  67. self._openCount -= n
  68. if self._openCount == 0:
  69. if self._idleTicks == self.MaxIdleTicks:
  70. self.stop()
  71. return
  72. self._idleTicks += 1
  73. else:
  74. self._idleTicks = 0
  75. def exitAndJoin(self):
  76. if not self.thread:
  77. return
  78. self.thread.cancelAll()
  79. self.thread.exit()
  80. self.thread.join()
  81. self._thread = None
  82. Thread = _ThreadManager()