Revision ea1e5d9f

b/snf-astakos-app/astakos/im/functions.py
440 440

  
441 441
def get_project_for_update(project_id):
442 442
    try:
443
        return Project.objects.select_for_update().get(id=project_id)
443
        return Project.objects.get_for_update(id=project_id)
444 444
    except Project.DoesNotExist:
445 445
        raise IOError(
446 446
            _(astakos_messages.UNKNOWN_PROJECT_ID) % project_id)
447 447

  
448 448
def get_application_for_update(application_id):
449 449
    try:
450
        objects = ProjectApplication.objects.select_for_update()
451
        return objects.get(id=application_id)
450
        return ProjectApplication.objects.get_for_update(id=application_id)
452 451
    except ProjectApplication.DoesNotExist:
453 452
        m = _(astakos_messages.UNKNOWN_PROJECT_APPLICATION_ID) % application_id
454 453
        raise IOError(m)
......
488 487
    if isinstance(user, (int, long)):
489 488
        user = get_user_by_id(user)
490 489
    try:
491
        sfu = ProjectMembership.objects.select_for_update()
492
        m = sfu.get(project=project, person=user)
490
        objs = ProjectMembership.objects
491
        m = objs.get_for_update(project=project, person=user)
493 492
        if m.is_pending:
494 493
            raise PendingMembershipError()
495 494
        return m
......
684 683
    precursor = None
685 684
    precursor_id = kw.get('precursor_application', None)
686 685
    if precursor_id is not None:
687
        sfu = ProjectApplication.objects.select_for_update()
688
        precursor = sfu.get(id=precursor_id)
686
        objs = ProjectApplication.objects
687
        precursor = objs.get_for_update(id=precursor_id)
689 688
        kw['precursor_application'] = precursor
690 689

  
691 690
        if (request_user and
......
702 701
    else:
703 702
        chain = precursor.chain
704 703
        application.chain = chain
705
        sfu = ProjectApplication.objects.select_for_update()
706
        pending = sfu.filter(chain=chain, state=ProjectApplication.PENDING)
704
        objs = ProjectApplication.objects
705
        q = objs.filter(chain=chain, state=ProjectApplication.PENDING)
706
        pending = q.select_for_update()
707 707
        for app in pending:
708 708
            app.state = ProjectApplication.REPLACED
709 709
            app.save()
......
749 749
def approve_application(app_id):
750 750

  
751 751
    try:
752
        objects = ProjectApplication.objects.select_for_update()
753
        application = objects.get(id=app_id)
752
        objects = ProjectApplication.objects
753
        application = objects.get_for_update(id=app_id)
754 754
    except ProjectApplication.DoesNotExist:
755 755
        m = _(astakos_messages.UNKNOWN_PROJECT_APPLICATION_ID % (app_id,))
756 756
        raise PermissionDenied(m)
b/snf-astakos-app/astakos/im/managers.py
1
# Copyright 2012 GRNET S.A. All rights reserved.
1
# Copyright 2012, 2013 GRNET S.A. All rights reserved.
2 2
#
3 3
# Redistribution and use in source and binary forms, with or without
4 4
# modification, are permitted provided that the following conditions
......
45 45
        transactions that abort due to deadlocks.
46 46

  
47 47
        Example:
48
            networks = Network.objects.select_for_update().filter(public=True)
48
            networks = Network.objects.filter(public=True).select_for_update()
49 49

  
50 50
    """
51 51

  
52
    def __init__(self, *args, **kwargs):
53
        super(ForUpdateManager, self).__init__(*args, **kwargs)
54
        self._select_for_update = False
55

  
56
    def filter(self, *args, **kwargs):
57
        query = self.get_query_set().filter(*args, **kwargs)
58
        if self._select_for_update:
59
            self._select_for_update = False
60
            return for_update(query)
61
        else:
62
            return query
63

  
64
    def get(self, *args, **kwargs):
65
        if not self._select_for_update:
66
            return self.get_query_set().get(*args, **kwargs)
52
    def get_query_set(self):
53
        return ForUpdateQuerySet(self.model, using=self._db)
67 54

  
68
        query = self.filter(*args, **kwargs)
55
    def get_for_update(self, *args, **kwargs):
56
        query = for_update(self.filter(*args, **kwargs))
69 57
        query = list(query)
70 58
        num = len(query)
71 59
        if num == 1:
......
80 68
            "Lookup parameters were %s" %
81 69
            (self.model._meta.object_name, num, kwargs))
82 70

  
83
    def select_for_update(self, *args, **kwargs):
84
        self._select_for_update = True
85
        return self
71

  
72
class ForUpdateQuerySet(QuerySet):
73

  
74
    def select_for_update(self):
75
        return for_update(self)
86 76

  
87 77

  
88 78
def for_update(query):
......
95 85
    sql, params = query.query.get_compiler(query.db).as_sql()
96 86
    return query.model._default_manager.raw(sql.rstrip() + ' FOR UPDATE',
97 87
                                            params)
98

  
99

  
100
class ProtectedDeleteManager(ForUpdateManager):
101
    """ Manager for protecting Backend deletion.
102

  
103
        Call Backend delete() method in order to prevent deletion
104
        of Backends that host non-deleted VirtualMachines.
105

  
106
    """
107

  
108
    def get_query_set(self):
109
        return BackendQuerySet(self.model, using=self._db)
110

  
111

  
112
class BackendQuerySet(QuerySet):
113
    def delete(self):
114
        for backend in self._clone():
115
            backend.delete()
b/snf-astakos-app/astakos/im/models.py
1656 1656

  
1657 1657
    def _get_project_for_update(self):
1658 1658
        try:
1659
            objects = Project.objects.select_for_update()
1660
            project = objects.get(id=self.chain)
1659
            objects = Project.objects
1660
            project = objects.get_for_update(id=self.chain)
1661 1661
            return project
1662 1662
        except Project.DoesNotExist:
1663 1663
            return None
......
2459 2459
    pass
2460 2460

  
2461 2461
def reset_serials(serials):
2462
    sfu = ProjectMembership.objects.select_for_update()
2463
    memberships = list(sfu.filter(pending_serial__in=serials))
2462
    objs = ProjectMembership.objects
2463
    q = objs.filter(pending_serial__in=serials).select_for_update()
2464
    memberships = list(q)
2464 2465

  
2465 2466
    if memberships:
2466 2467
        for membership in memberships:
......
2473 2474
        serials_to_ack = qh_query_serials([])
2474 2475

  
2475 2476
    serials_to_ack = set(serials_to_ack)
2476
    sfu = ProjectMembership.objects.select_for_update()
2477
    memberships = list(sfu.filter(pending_serial__isnull=False))
2477
    objs = ProjectMembership.objects
2478
    q = objs.filter(pending_serial__isnull=False).select_for_update()
2479
    memberships = list(q)
2478 2480

  
2479 2481
    if memberships:
2480 2482
        for membership in memberships:
......
2493 2495
    ACCEPTED = ProjectMembership.ACCEPTED
2494 2496
    LEAVE_REQUESTED = ProjectMembership.LEAVE_REQUESTED
2495 2497
    PROJECT_DEACTIVATED = ProjectMembership.PROJECT_DEACTIVATED
2496
    psfu = Project.objects.select_for_update()
2498
    objs = Project.objects
2497 2499

  
2498
    modified = list(psfu.modified_projects())
2500
    modified = list(objs.modified_projects().select_for_update())
2499 2501
    if sync:
2500 2502
        for project in modified:
2501
            objects = project.projectmembership_set.select_for_update()
2503
            objects = project.projectmembership_set
2502 2504

  
2503
            memberships = objects.actually_accepted()
2505
            memberships = objects.actually_accepted().select_for_update()
2504 2506
            for membership in memberships:
2505 2507
                membership.is_pending = True
2506 2508
                membership.save()
2507 2509

  
2508
    reactivating = list(psfu.reactivating_projects())
2510
    reactivating = list(objs.reactivating_projects().select_for_update())
2509 2511
    if sync:
2510 2512
        for project in reactivating:
2511
            objects = project.projectmembership_set.select_for_update()
2513
            objects = project.projectmembership_set
2512 2514

  
2513
            memberships = objects.filter(state=PROJECT_DEACTIVATED)
2515
            q = objects.filter(state=PROJECT_DEACTIVATED)
2516
            memberships = q.select_for_update()
2514 2517
            for membership in memberships:
2515 2518
                membership.is_pending = True
2516 2519
                if membership.leave_request_date is None:
......
2519 2522
                    membership.state = LEAVE_REQUESTED
2520 2523
                membership.save()
2521 2524

  
2522
    deactivating = list(psfu.deactivating_projects())
2525
    deactivating = list(objs.deactivating_projects().select_for_update())
2523 2526
    if sync:
2524 2527
        for project in deactivating:
2525
            objects = project.projectmembership_set.select_for_update()
2528
            objects = project.projectmembership_set
2526 2529

  
2527 2530
            # Note: we keep a user-level deactivation
2528 2531
            # (e.g. USER_SUSPENDED) intact
2529
            memberships = objects.actually_accepted()
2532
            memberships = objects.actually_accepted().select_for_update()
2530 2533
            for membership in memberships:
2531 2534
                membership.is_pending = True
2532 2535
                membership.state = PROJECT_DEACTIVATED
2533 2536
                membership.save()
2534 2537

  
2538
#    transaction.commit()
2535 2539
    return (modified, reactivating, deactivating)
2536 2540

  
2537 2541
def set_sync_projects(exclude=None):
2538 2542

  
2539 2543
    ACTUALLY_ACCEPTED = ProjectMembership.ACTUALLY_ACCEPTED
2540
    objects = ProjectMembership.objects.select_for_update()
2544
    objects = ProjectMembership.objects
2541 2545

  
2542 2546
    sub_quota, add_quota = [], []
2543 2547

  
2544 2548
    serial = new_serial()
2545 2549

  
2546
    pending = objects.filter(is_pending=True)
2550
    pending = objects.filter(is_pending=True).select_for_update()
2547 2551
    for membership in pending:
2548 2552

  
2549 2553
        if membership.pending_application:
......
2596 2600
def post_sync_projects():
2597 2601
    PROJECT_DEACTIVATED = ProjectMembership.PROJECT_DEACTIVATED
2598 2602
    Q_ACTUALLY_ACCEPTED = ProjectMembership.Q_ACTUALLY_ACCEPTED
2599
    psfu = Project.objects.select_for_update()
2603
    objs = Project.objects
2600 2604

  
2601
    modified = psfu.modified_projects()
2605
    modified = objs.modified_projects().select_for_update()
2602 2606
    for project in modified:
2603
        objects = project.projectmembership_set.select_for_update()
2604

  
2605
        memberships = list(objects.filter(Q_ACTUALLY_ACCEPTED &
2606
                                          Q(is_pending=True)))
2607
        objects = project.projectmembership_set
2608
        q = objects.filter(Q_ACTUALLY_ACCEPTED & Q(is_pending=True))
2609
        memberships = list(q.select_for_update())
2607 2610
        if not memberships:
2608 2611
            project.is_modified = False
2609 2612
            project.save()
2610 2613

  
2611
    reactivating = psfu.reactivating_projects()
2614
    reactivating = objs.reactivating_projects().select_for_update()
2612 2615
    for project in reactivating:
2613
        objects = project.projectmembership_set.select_for_update()
2614
        memberships = list(objects.filter(Q(state=PROJECT_DEACTIVATED) |
2615
                                          Q(is_pending=True)))
2616
        objects = project.projectmembership_set
2617
        q = objects.filter(Q(state=PROJECT_DEACTIVATED) | Q(is_pending=True))
2618
        memberships = list(q.select_for_update())
2616 2619
        if not memberships:
2617 2620
            project.reactivate()
2618 2621
            project.save()
2619 2622

  
2620
    deactivating = psfu.deactivating_projects()
2623
    deactivating = objs.deactivating_projects().select_for_update()
2621 2624
    for project in deactivating:
2622
        objects = project.projectmembership_set.select_for_update()
2623

  
2624
        memberships = list(objects.filter(Q_ACTUALLY_ACCEPTED |
2625
                                          Q(is_pending=True)))
2625
        objects = project.projectmembership_set
2626
        q = objects.filter(Q_ACTUALLY_ACCEPTED | Q(is_pending=True))
2627
        memberships = list(q.select_for_update())
2626 2628
        if not memberships:
2627 2629
            project.deactivate()
2628 2630
            project.save()
b/snf-quotaholder-app/quotaholder_django/quotaholder_app/managers.py
1
# Copyright 2012 GRNET S.A. All rights reserved.
1
# Copyright 2012, 2013 GRNET S.A. All rights reserved.
2 2
#
3 3
# Redistribution and use in source and binary forms, with or without
4 4
# modification, are permitted provided that the following conditions
......
45 45
        transactions that abort due to deadlocks.
46 46

  
47 47
        Example:
48
            networks = Network.objects.select_for_update().filter(public=True)
48
            networks = Network.objects.filter(public=True).select_for_update()
49 49

  
50 50
    """
51 51

  
52
    def __init__(self, *args, **kwargs):
53
        super(ForUpdateManager, self).__init__(*args, **kwargs)
54
        self._select_for_update = False
55

  
56
    def filter(self, *args, **kwargs):
57
        query = self.get_query_set().filter(*args, **kwargs)
58
        if self._select_for_update:
59
            self._select_for_update = False
60
            return for_update(query)
61
        else:
62
            return query
63

  
64
    def get(self, *args, **kwargs):
65
        if not self._select_for_update:
66
            return self.get_query_set().get(*args, **kwargs)
52
    def get_query_set(self):
53
        return ForUpdateQuerySet(self.model, using=self._db)
67 54

  
68
        query = self.filter(*args, **kwargs)
55
    def get_for_update(self, *args, **kwargs):
56
        query = for_update(self.filter(*args, **kwargs))
69 57
        query = list(query)
70 58
        num = len(query)
71 59
        if num == 1:
......
80 68
            "Lookup parameters were %s" %
81 69
            (self.model._meta.object_name, num, kwargs))
82 70

  
83
    def select_for_update(self, *args, **kwargs):
84
        self._select_for_update = True
85
        return self
71

  
72
class ForUpdateQuerySet(QuerySet):
73

  
74
    def select_for_update(self):
75
        return for_update(self)
86 76

  
87 77

  
88 78
def for_update(query):
......
95 85
    sql, params = query.query.get_compiler(query.db).as_sql()
96 86
    return query.model._default_manager.raw(sql.rstrip() + ' FOR UPDATE',
97 87
                                            params)
98

  
99

  
100
class ProtectedDeleteManager(ForUpdateManager):
101
    """ Manager for protecting Backend deletion.
102

  
103
        Call Backend delete() method in order to prevent deletion
104
        of Backends that host non-deleted VirtualMachines.
105

  
106
    """
107

  
108
    def get_query_set(self):
109
        return BackendQuerySet(self.model, using=self._db)
110

  
111

  
112
class BackendQuerySet(QuerySet):
113
    def delete(self):
114
        for backend in self._clone():
115
            backend.delete()
b/snf-quotaholder-app/quotaholder_django/quotaholder_app/models.py
1
# Copyright 2012 GRNET S.A. All rights reserved.
1
# Copyright 2012, 2013 GRNET S.A. All rights reserved.
2 2
#
3 3
# Redistribution and use in source and binary forms, with or
4 4
# without modification, are permitted provided that the following
......
199 199
        unique_together = (('serial', 'clientkey'),)
200 200

  
201 201

  
202
def _access(*args, **kwargs):
203
    method = args[0]
204
    model = args[1]
205
    args = args[2:]
202
def _get(*args, **kwargs):
203
    model = args[0]
204
    args = args[1:]
206 205
    o = model.objects
207
    try:
208
        if kwargs['for_update']:
209
            del kwargs['for_update']
210
            o = o.select_for_update()
211
    except KeyError:
212
        pass
213
    f = getattr(o, method)
206

  
207
    for_update = kwargs.pop('for_update', False)
208
    f = o.get_for_update if for_update else o.get
214 209
    return f(*args, **kwargs)
215 210

  
216
def _get(*args, **kwargs):
217
    return _access('get', *args, **kwargs)
218 211

  
219 212
def _filter(*args, **kwargs):
220
    return _access('filter', *args, **kwargs)
213
    model = args[0]
214
    args = args[1:]
215
    o = model.objects
216

  
217
    for_update = kwargs.pop('for_update', False)
218
    q = o.filter(*args, **kwargs)
219
    q = q.select_for_update() if for_update else q
220
    return q
221

  
221 222

  
222 223
def db_get_holding(*args, **kwargs):
223 224
    return _get(Holding, *args, **kwargs)

Also available in: Unified diff