server/utils.py
branchstable
changeset 8463 a964c40adbe3
parent 8446 cae198371548
child 8546 3d2038d6f20d
equal deleted inserted replaced
8461:8af7c6d86efb 8463:a964c40adbe3
    50     # passlib 1.5 wants calc_checksum, 1.6 wants _calc_checksum
    50     # passlib 1.5 wants calc_checksum, 1.6 wants _calc_checksum
    51     def calc_checksum(self, secret):
    51     def calc_checksum(self, secret):
    52         return md5crypt(secret, self.salt.encode('ascii')).decode('utf-8')
    52         return md5crypt(secret, self.salt.encode('ascii')).decode('utf-8')
    53     _calc_checksum = calc_checksum
    53     _calc_checksum = calc_checksum
    54 
    54 
    55 _CRYPTO_CTX = CryptContext(['sha512_crypt', CustomMD5Crypt, 'des_crypt'])
    55 _CRYPTO_CTX = CryptContext(['sha512_crypt', CustomMD5Crypt, 'des_crypt', 'ldap_salted_sha1'])
    56 
    56 
    57 def crypt_password(passwd, salt=None):
    57 def crypt_password(passwd, salt=None):
    58     """return the encrypted password using the given salt or a generated one
    58     """return the encrypted password using the given salt or a generated one
    59     """
    59     """
    60     if salt is None:
    60     if salt is None:
   137         name = repr(func)
   137         name = repr(func)
   138     return name
   138     return name
   139 
   139 
   140 class LoopTask(object):
   140 class LoopTask(object):
   141     """threaded task restarting itself once executed"""
   141     """threaded task restarting itself once executed"""
   142     def __init__(self, repo, interval, func, args):
   142     def __init__(self, tasks_manager, interval, func, args):
   143         if interval <= 0:
   143         if interval <= 0:
   144             raise ValueError('Loop task interval must be > 0 '
   144             raise ValueError('Loop task interval must be > 0 '
   145                              '(current value: %f for %s)' % \
   145                              '(current value: %f for %s)' % \
   146                              (interval, func_name(func)))
   146                              (interval, func_name(func)))
   147         self.repo = repo
   147         self._tasks_manager = tasks_manager
   148         self.interval = interval
   148         self.interval = interval
   149         def auto_restart_func(self=self, func=func, args=args):
   149         def auto_restart_func(self=self, func=func, args=args):
   150             restart = True
   150             restart = True
   151             try:
   151             try:
   152                 func(*args)
   152                 func(*args)
   155                 logger.exception('Unhandled exception in LoopTask %s', self.name)
   155                 logger.exception('Unhandled exception in LoopTask %s', self.name)
   156                 raise
   156                 raise
   157             except BaseException:
   157             except BaseException:
   158                 restart = False
   158                 restart = False
   159             finally:
   159             finally:
   160                 if restart and not self.repo.shutting_down:
   160                 if restart and tasks_manager.running:
   161                     self.start()
   161                     self.start()
   162         self.func = auto_restart_func
   162         self.func = auto_restart_func
   163         self.name = func_name(func)
   163         self.name = func_name(func)
   164 
   164 
   165     def __str__(self):
   165     def __str__(self):
   201         self.daemon = True
   201         self.daemon = True
   202         Thread.start(self)
   202         Thread.start(self)
   203 
   203 
   204     def getName(self):
   204     def getName(self):
   205         return '%s(%s)' % (self._name, Thread.getName(self))
   205         return '%s(%s)' % (self._name, Thread.getName(self))
       
   206 
       
   207 class TasksManager(object):
       
   208     """Object dedicated manage background task"""
       
   209 
       
   210     def __init__(self):
       
   211         self.running = False
       
   212         self._tasks = []
       
   213         self._looping_tasks = []
       
   214 
       
   215     def add_looping_task(self, interval, func, *args):
       
   216         """register a function to be called every `interval` seconds.
       
   217 
       
   218         looping tasks can only be registered during repository initialization,
       
   219         once done this method will fail.
       
   220         """
       
   221         task = LoopTask(self, interval, func, args)
       
   222         if self.running:
       
   223             self._start_task(task)
       
   224         else:
       
   225             self._tasks.append(task)
       
   226 
       
   227     def _start_task(self, task):
       
   228         self._looping_tasks.append(task)
       
   229         self.info('starting task %s with interval %.2fs', task.name,
       
   230                   task.interval)
       
   231         task.start()
       
   232 
       
   233     def start(self):
       
   234         """Start running looping task"""
       
   235         assert self.running == False # bw compat purpose maintly
       
   236         while self._tasks:
       
   237             task = self._tasks.pop()
       
   238             self._start_task(task)
       
   239         self.running = True
       
   240 
       
   241     def stop(self):
       
   242         """Stop all running task.
       
   243 
       
   244         returns when all task have been cancel and none are running anymore"""
       
   245         if self.running:
       
   246             while self._looping_tasks:
       
   247                 looptask = self._looping_tasks.pop()
       
   248                 self.info('canceling task %s...', looptask.name)
       
   249                 looptask.cancel()
       
   250                 looptask.join()
       
   251                 self.info('task %s finished', looptask.name)
       
   252 
       
   253 from logging import getLogger
       
   254 from cubicweb import set_log_methods
       
   255 set_log_methods(TasksManager, getLogger('cubicweb.repository'))
       
   256