Completed
Pull Request — master (#41)
by
unknown
05:38
created

common.tasks.redis_lock()   A

Complexity

Conditions 3

Size

Total Lines 24
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 13
dl 0
loc 24
rs 9.75
c 0
b 0
f 0
cc 3
nop 2
1
#!/usr/bin/env python3
2
# -*- coding: utf-8 -*-
3
"""
4
Created on Tue Jan 15 16:42:24 2019
5
6
@author: Paolo Cozzi <[email protected]>
7
"""
8
9
import redis
10
11
from contextlib import contextmanager
12
from celery.five import monotonic
13
14
from django.conf import settings
15
16
from image_app.models import Submission, Sample, Animal, DictUberon, \
17
    DictDevelStage, DictPhysioStage, DictSex
18
from submissions.helpers import send_message
19
from validation.helpers import construct_validation_message
20
from common.constants import NEED_REVISION
21
22
# Lock expires in 10 minutes
23
LOCK_EXPIRE = 60 * 10
24
25
26
class BatchUpdateMixin:
27
    """Mixin to do batch update of fields to fix validation"""
28
29
    def batch_update(self, submission_id, ids, attribute, item_type):
30
        for id, value in ids.items():
31
            if value == '' or value == 'None':
32
                value = None
33
            if item_type == 'sample':
34
                item_object = Sample.objects.get(pk=id)
35
            elif item_type == 'animal':
36
                item_object = Animal.objects.get(pk=id)
37
            elif item_type == 'dictuberon':
38
                item_object = DictUberon.objects.get(pk=id)
39
            elif item_type == 'dictdevelstage':
40
                item_object = DictDevelStage.objects.get(pk=id)
41
            elif item_type == 'dictphysiostage':
42
                item_object = DictPhysioStage.objects.get(pk=id)
43
            elif item_type == 'dictsex':
44
                item_object = DictSex.objects.get(pk=id)
45
            if getattr(item_object, attribute) != value:
0 ignored issues
show
introduced by
The variable item_object does not seem to be defined for all execution paths.
Loading history...
46
                setattr(item_object, attribute, value)
47
                item_object.save()
48
49
        # Update submission
50
        submission_obj = Submission.objects.get(pk=submission_id)
51
        submission_obj.status = NEED_REVISION
52
        submission_obj.message = "Data updated, try to rerun validation"
53
        submission_obj.save()
54
55
        send_message(
56
            submission_obj, construct_validation_message(submission_obj)
57
        )
58
59
60
@contextmanager
61
def redis_lock(lock_id, blocking=False):
62
    # read parameters from settings
63
    REDIS_CLIENT = redis.StrictRedis(
64
        host=settings.REDIS_HOST,
65
        port=settings.REDIS_PORT,
66
        db=settings.REDIS_DB)
67
68
    timeout_at = monotonic() + LOCK_EXPIRE - 3
69
70
    lock = REDIS_CLIENT.lock(lock_id, timeout=LOCK_EXPIRE)
71
    status = lock.acquire(blocking=blocking)
72
73
    try:
74
        yield status
75
76
    finally:
77
        # we take advantage of using add() for atomic locking
78
        if monotonic() < timeout_at and status:
79
            # don't release the lock if we exceeded the timeout
80
            # to lessen the chance of releasing an expired lock
81
            # owned by someone else
82
            # also don't release the lock if we didn't acquire it
83
            lock.release()
84