Projet

Général

Profil

0001-atos-genesys-do-not-use-threads-29320.patch

Benjamin Dauvergne, 22 décembre 2018 01:15

Télécharger (4,46 ko)

Voir les différences:

Subject: [PATCH] atos-genesys: do not use threads (#29320)

As threads were hiding errors from asynchronous requests, we now still
hide errors when cache is full, but log them.
 passerelle/apps/atos_genesys/models.py |  6 ++++--
 passerelle/apps/atos_genesys/utils.py  | 23 ++++++++++-------------
 tests/test_atos_genesys.py             |  2 +-
 3 files changed, 15 insertions(+), 16 deletions(-)
passerelle/apps/atos_genesys/models.py
97 97
        cache = utils.RowLockedCache(
98 98
            function=self.call_select_codifications,
99 99
            row=self,
100
            key_prefix='atos-genesys-codifications')
100
            key_prefix='atos-genesys-codifications',
101
            logger=self.logger)
101 102
        return cache()
102 103

  
103 104
    @endpoint(name='codifications',
......
274 275
            cache = utils.RowLockedCache(
275 276
                function=self.call_select_usager,
276 277
                row=link,
277
                key_prefix='atos-genesys-usager')
278
                key_prefix='atos-genesys-usager',
279
                logger=self.logger)
278 280
            dossier = cache(link.id_per)
279 281
            # build text as "id_per - prenom - no
280 282
            text_parts = [str(link.id_per), '-']
passerelle/apps/atos_genesys/utils.py
1 1
import time
2 2
import six
3
import threading
4 3
from contextlib import contextmanager
5 4

  
6 5
from django.db import transaction
7 6
from django.core.cache import cache
8 7

  
8
from passerelle.utils.jsonresponse import APIError
9

  
9 10
DEFAULT_DURATION = 5 * 60  # 5 minutes
10 11

  
11 12
# keep data in cache for 1 day, i.e. we can answer a request from cache for 1 day
......
29 30
       a thread, prevent multiple update using row locks on database models and
30 31
       an update cache key.
31 32
    '''
32
    def __init__(self, function, row=None, duration=DEFAULT_DURATION, key_prefix=None):
33
    def __init__(self, function, logger=None, row=None, duration=DEFAULT_DURATION, key_prefix=None):
33 34
        self.function = function
34 35
        self.row = row
35 36
        self.duration = duration
36 37
        self.key_prefix = key_prefix or function.__name__
38
        self.logger = logger
37 39

  
38 40
    def _key(self, *args, **kwargs):
39 41
        keys = []
......
59 61
                    cacheline = cache.get(key)
60 62
                    if now - timestamp < self.duration:
61 63
                        return cacheline['value']
62
                    updatekey = 'update-' + key
63
                    update = cache.get(updatekey)
64
                    if not update or (update['timestamp'] - now >= self.duration):
65
                        cache.set(updatekey, {'timestamp': now}, CACHE_DURATION)
66

  
67
                        def update():
68
                            value = self.function(*args, **kwargs)
69
                            cache.set(key, {'value': value, 'timestamp': now}, CACHE_DURATION)
70
                            cache.delete(updatekey)
71

  
72
                        threading.Thread(target=update).start()
64
                    try:
65
                        value = self.function(*args, **kwargs)
66
                        cache.set(key, {'value': value, 'timestamp': now}, CACHE_DURATION)
67
                    except APIError as e:
68
                        if self.logger:
69
                            self.logger.error('failure to update cache %s', e)
73 70
            return cacheline['value']
74 71
        else:
75 72
            value = self.function(*args, **kwargs)
tests/test_atos_genesys.py
215 215
        assert rlc() == 1
216 216
        assert f.calls == 1
217 217

  
218
    # Check that cache update only launch one thread and f() is called only once again
218
    # Check that with cache update f() is called only once again
219 219
    freezer.move_to('2018-01-01 00:02:00')
220 220
    F.value = 2
221 221
    counter = 0
222
-