Projet

Général

Profil

0001-use-pg_advisory_lock-to-prevent-running-cronjobs-dur.patch

Benjamin Dauvergne, 27 avril 2018 19:27

Télécharger (4,12 ko)

Voir les différences:

Subject: [PATCH] use pg_advisory_lock to prevent running cronjobs during
 migrations and on different servers (fixes #15470)

 .../management/commands/migrate_schemas.py    |  5 ++++
 .../management/commands/tenant_command.py     |  4 ++++
 tests_multitenant/test_tenant_command.py      | 23 +++++++++++++++++++
 3 files changed, 32 insertions(+)
hobo/multitenant/management/commands/migrate_schemas.py
4 4
if django.VERSION >= (1, 7, 0):
5 5
    from django.core.management.commands.migrate import Command as MigrateCommand
6 6
    from django.db.migrations.recorder import MigrationRecorder
7
from django.core.management.base import CommandError
7 8
from django.db import connection
8 9
from django.conf import settings
9 10

  
10 11
from tenant_schemas.utils import get_public_schema_name, schema_exists
11 12
from hobo.multitenant.middleware import TenantMiddleware, TenantNotFound
12 13
from hobo.multitenant.management.commands import SyncCommon
14
from hobo.multitenant.locking import take_global_lock
13 15

  
14 16

  
15 17
class MigrateSchemasCommand(SyncCommon):
......
34 36

  
35 37
    def handle(self, *args, **options):
36 38
        super(MigrateSchemasCommand, self).handle(*args, **options)
39
        # migration job can wait for finishing cron jobs
40
        if not take_global_lock(wait=3600):
41
            raise CommandError('global lock is taken, migration or another cron job is running')
37 42
        self.PUBLIC_SCHEMA_NAME = get_public_schema_name()
38 43

  
39 44
        if self.sync_public and not self.schema_name:
hobo/multitenant/management/commands/tenant_command.py
10 10

  
11 11
from hobo.multitenant.management.commands import InteractiveTenantOption
12 12
from hobo.multitenant.middleware import TenantMiddleware
13
from hobo.multitenant.locking import take_global_lock
14

  
13 15

  
14 16
class Command(InteractiveTenantOption, BaseCommand):
15 17
    help = "Wrapper around django commands for use with an individual tenant"
......
43 45
        args_namespace, args = args_parser.parse_known_args(argv)
44 46

  
45 47
        if args_namespace.all_tenants:
48
            if not take_global_lock():
49
                raise CommandError('global lock is taken, migration or another cron job is running')
46 50
            for tenant in TenantMiddleware.get_tenants():
47 51
                connection.set_tenant(tenant)
48 52
                klass.run_from_argv(args)
tests_multitenant/test_tenant_command.py
1 1
import pytest
2 2
import mock
3 3
import os
4
import threading
4 5

  
5 6
pytestmark = pytest.mark.django_db
6 7

  
......
53 54
        assert False 
54 55
    all_tenants = list(TenantMiddleware.get_tenants())
55 56
    assert len(all_tenants) == 1
57

  
58

  
59
@mock.patch('django.contrib.sessions.management.commands.clearsessions.Command.handle')
60
def test_all_tenants_global_lock(handle, tenants):
61
    from django.core.management import execute_from_command_line
62
    from hobo.multitenant.locking import take_global_lock
63

  
64
    handle.side_effect = RecordTenant()
65
    assert take_global_lock()
66

  
67
    l = [0]
68

  
69
    def thread_run():
70
        execute_from_command_line(['manage.py', 'tenant_command', 'clearsessions', '--all-tenants'])
71
        l[0] = 1
72

  
73
    t = threading.Thread(target=thread_run)
74
    t.start()
75
    t.join()
76

  
77
    assert l[0] == 0
78
    assert handle.call_count == 0
56
-