|
@@ -17,7 +17,6 @@
|
|
from __future__ import absolute_import
|
|
from __future__ import absolute_import
|
|
from __future__ import with_statement
|
|
from __future__ import with_statement
|
|
|
|
|
|
-import os
|
|
|
|
import sys
|
|
import sys
|
|
import threading
|
|
import threading
|
|
import traceback
|
|
import traceback
|
|
@@ -25,13 +24,14 @@ import traceback
|
|
from time import sleep, time
|
|
from time import sleep, time
|
|
|
|
|
|
from . import state
|
|
from . import state
|
|
|
|
+from ..utils.threads import bgThread
|
|
|
|
|
|
|
|
|
|
-class Autoscaler(threading.Thread):
|
|
|
|
|
|
+class Autoscaler(bgThread):
|
|
|
|
|
|
def __init__(self, pool, max_concurrency, min_concurrency=0,
|
|
def __init__(self, pool, max_concurrency, min_concurrency=0,
|
|
keepalive=30, logger=None):
|
|
keepalive=30, logger=None):
|
|
- threading.Thread.__init__(self)
|
|
|
|
|
|
+ super(Autoscaler, self).__init__()
|
|
self.pool = pool
|
|
self.pool = pool
|
|
self.mutex = threading.Lock()
|
|
self.mutex = threading.Lock()
|
|
self.max_concurrency = max_concurrency
|
|
self.max_concurrency = max_concurrency
|
|
@@ -39,14 +39,10 @@ class Autoscaler(threading.Thread):
|
|
self.keepalive = keepalive
|
|
self.keepalive = keepalive
|
|
self.logger = logger
|
|
self.logger = logger
|
|
self._last_action = None
|
|
self._last_action = None
|
|
- self._is_shutdown = threading.Event()
|
|
|
|
- self._is_stopped = threading.Event()
|
|
|
|
- self.setDaemon(True)
|
|
|
|
- self.setName(self.__class__.__name__)
|
|
|
|
|
|
|
|
assert self.keepalive, "can't scale down too fast."
|
|
assert self.keepalive, "can't scale down too fast."
|
|
|
|
|
|
- def scale(self):
|
|
|
|
|
|
+ def next(self):
|
|
with self.mutex:
|
|
with self.mutex:
|
|
current = min(self.qty, self.max_concurrency)
|
|
current = min(self.qty, self.max_concurrency)
|
|
if current > self.processes:
|
|
if current > self.processes:
|
|
@@ -54,6 +50,8 @@ class Autoscaler(threading.Thread):
|
|
elif current < self.processes:
|
|
elif current < self.processes:
|
|
self.scale_down(
|
|
self.scale_down(
|
|
(self.processes - current) - self.min_concurrency)
|
|
(self.processes - current) - self.min_concurrency)
|
|
|
|
+ sleep(1.0)
|
|
|
|
+ scale = next # XXX compat
|
|
|
|
|
|
def update(self, max=None, min=None):
|
|
def update(self, max=None, min=None):
|
|
with self.mutex:
|
|
with self.mutex:
|
|
@@ -109,23 +107,6 @@ class Autoscaler(threading.Thread):
|
|
self._last_action = time()
|
|
self._last_action = time()
|
|
self._shrink(n)
|
|
self._shrink(n)
|
|
|
|
|
|
- def run(self):
|
|
|
|
- while not self._is_shutdown.isSet():
|
|
|
|
- try:
|
|
|
|
- self.scale()
|
|
|
|
- sleep(1.0)
|
|
|
|
- except Exception, exc:
|
|
|
|
- self.logger.error("Thread Autoscaler crashed: %r", exc,
|
|
|
|
- exc_info=sys.exc_info())
|
|
|
|
- os._exit(1)
|
|
|
|
- self._is_stopped.set()
|
|
|
|
-
|
|
|
|
- def stop(self):
|
|
|
|
- self._is_shutdown.set()
|
|
|
|
- self._is_stopped.wait()
|
|
|
|
- if self.isAlive():
|
|
|
|
- self.join(1e10)
|
|
|
|
-
|
|
|
|
def info(self):
|
|
def info(self):
|
|
return {"max": self.max_concurrency,
|
|
return {"max": self.max_concurrency,
|
|
"min": self.min_concurrency,
|
|
"min": self.min_concurrency,
|