Passed
Pull Request — master (#41)
by
unknown
05:30
created

common.tasks.BatchUpdateMixin.batch_update()   B

Complexity

Conditions 7

Size

Total Lines 20
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 17
dl 0
loc 20
rs 8
c 0
b 0
f 0
cc 7
nop 5
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
17
from submissions.helpers import send_message
18
from validation.helpers import construct_validation_message
19
from common.constants import NEED_REVISION
20
21
# Lock expires in 10 minutes
22
LOCK_EXPIRE = 60 * 10
23
24
25
class BatchUpdateMixin:
26
    """Mixin to do batch update of fields to fix validation"""
27
28
    def batch_update(self, submission_id, ids, attribute, item_type):
29
        for id, value in ids.items():
30
            if value == '' or value == 'None':
31
                value = None
32
            if item_type == 'sample':
33
                item_object = Sample.objects.get(pk=id)
34
            elif item_type == 'animal':
35
                item_object = Animal.objects.get(pk=id)
36
            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...
37
                setattr(item_object, attribute, value)
38
                item_object.save()
39
40
        # Update submission
41
        submission_obj = Submission.objects.get(pk=submission_id)
42
        submission_obj.status = NEED_REVISION
43
        submission_obj.message = "Data updated, try to rerun validation"
44
        submission_obj.save()
45
46
        send_message(
47
            submission_obj, construct_validation_message(submission_obj)
48
        )
49
50
51
@contextmanager
52
def redis_lock(lock_id, blocking=False):
53
    # read parameters from settings
54
    REDIS_CLIENT = redis.StrictRedis(
55
        host=settings.REDIS_HOST,
56
        port=settings.REDIS_PORT,
57
        db=settings.REDIS_DB)
58
59
    timeout_at = monotonic() + LOCK_EXPIRE - 3
60
61
    lock = REDIS_CLIENT.lock(lock_id, timeout=LOCK_EXPIRE)
62
    status = lock.acquire(blocking=blocking)
63
64
    try:
65
        yield status
66
67
    finally:
68
        # we take advantage of using add() for atomic locking
69
        if monotonic() < timeout_at and status:
70
            # don't release the lock if we exceeded the timeout
71
            # to lessen the chance of releasing an expired lock
72
            # owned by someone else
73
            # also don't release the lock if we didn't acquire it
74
            lock.release()
75