Skip to content

Commit

Permalink
Merge pull request #2333 from mkurek/async-transitions
Browse files Browse the repository at this point in the history
Asynchronous transitions - part 1
  • Loading branch information
szok committed Mar 31, 2016
2 parents 44e8bf8 + 726cc99 commit 165af3b
Show file tree
Hide file tree
Showing 35 changed files with 1,039 additions and 82 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -75,3 +75,5 @@ src/ralph/var/
debian/ralph-core*

.idea

!src/ralph/lib
2 changes: 2 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ before_install:
- pip install flake8 isort
- make flake
- export RALPH_VERSION=$(cat VERSION)
- export REDIS_PORT=6379
- docker run -d -p "$REDIS_PORT:6379" redis:3.0;
- export NEW_TAG=$RALPH_VERSION-snapshot-$(date "+%Y%m%d")-$TRAVIS_BUILD_NUMBER
- if [[ $TEST_DB_ENGINE == mysql ]]; then docker run -d -v $(pwd)/docker/mysql.cnf:/etc/mysql/conf.d/mysql.cnf -p "3306:3306" -e "MYSQL_ALLOW_EMPTY_PASSWORD=yes" -e "MYSQL_DATABASE=ralph_ng" -e "MYSQL_ROOT_PASSWORD=root" -e "MYSQL_USER=travis" -e "MYSQL_PASSWORD=travis" mysql:5.6; fi
- if [[ $TEST_DB_ENGINE == psql ]]; then
Expand Down
1 change: 1 addition & 0 deletions requirements/base.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ django-filter==0.11.0
django-import-export==0.4.2
django-mptt==0.7.4
django-reversion==1.8.6
django-rq==0.9.0
django-taggit==0.17.1
django-taggit-serializer==0.1.5
djangorestframework==3.2.2
Expand Down
1 change: 1 addition & 0 deletions src/ralph/admin/templates/admin/templatetags/tabs.html
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
<i class="fa fa-{{ view.icon }}"></i>
{% endif %}
<span class="tab-label">{{ view.label }}</span>
{# TODO: show some badge (ex. currently running transitions ) #}
</a>
</li>
{% endfor %}
Expand Down
2 changes: 1 addition & 1 deletion src/ralph/assets/models/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from ralph.lib.permissions import PermByFieldMixin
from ralph.lib.permissions.models import PermissionsBase
from ralph.lib.polymorphic.models import Polymorphic, PolymorphicBase
from ralph.lib.transitions import TransitionWorkflowBase
from ralph.lib.transitions.models import TransitionWorkflowBase

BaseObjectMeta = type(
'BaseObjectMeta', (
Expand Down
33 changes: 17 additions & 16 deletions src/ralph/back_office/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@
from ralph.lib.external_services import ExternalService, obj_to_dict
from ralph.lib.mixins.fields import NullableCharField
from ralph.lib.mixins.models import NamedMixin, TimeStampMixin
from ralph.lib.transitions import transition_action, TransitionField
from ralph.lib.transitions.decorators import transition_action
from ralph.lib.transitions.fields import TransitionField
from ralph.licences.models import BaseObjectLicence, Licence
from ralph.reports.models import Report, ReportLanguage

Expand Down Expand Up @@ -216,7 +217,7 @@ def get_autocomplete_queryset(cls):
}
},
)
def assign_user(cls, instances, request, **kwargs):
def assign_user(cls, instances, **kwargs):
user = get_user_model().objects.get(pk=int(kwargs['user']))
for instance in instances:
instance.user = user
Expand All @@ -234,7 +235,7 @@ def assign_user(cls, instances, request, **kwargs):
}
}
)
def assign_licence(cls, instances, request, **kwargs):
def assign_licence(cls, instances, **kwargs):
for instance in instances:
for obj in kwargs['licences']:
BaseObjectLicence.objects.get_or_create(
Expand All @@ -258,7 +259,7 @@ def assign_licence(cls, instances, request, **kwargs):
'categories and only if owner\'s country has changed)'
),
)
def assign_owner(cls, instances, request, **kwargs):
def assign_owner(cls, instances, **kwargs):
owner = get_user_model().objects.get(pk=int(kwargs['owner']))
for instance in instances:
instance.owner = owner
Expand All @@ -267,7 +268,7 @@ def assign_owner(cls, instances, request, **kwargs):
@transition_action(
run_after=['loan_report', 'return_report']
)
def unassign_owner(cls, instances, request, **kwargs):
def unassign_owner(cls, instances, **kwargs):
for instance in instances:
kwargs['history_kwargs'][instance.pk][
'affected_owner'
Expand All @@ -278,7 +279,7 @@ def unassign_owner(cls, instances, request, **kwargs):
@transition_action(
run_after=['loan_report', 'return_report']
)
def unassign_user(cls, instances, request, **kwargs):
def unassign_user(cls, instances, **kwargs):
for instance in instances:
kwargs['history_kwargs'][instance.pk][
'affected_user'
Expand All @@ -296,13 +297,13 @@ def unassign_user(cls, instances, request, **kwargs):
}
},
)
def assign_loan_end_date(cls, instances, request, **kwargs):
def assign_loan_end_date(cls, instances, **kwargs):
for instance in instances:
instance.loan_end_date = kwargs['loan_end_date']

@classmethod
@transition_action()
def unassign_loan_end_date(cls, instances, request, **kwargs):
def unassign_loan_end_date(cls, instances, **kwargs):
for instance in instances:
instance.loan_end_date = None

Expand All @@ -315,7 +316,7 @@ def unassign_loan_end_date(cls, instances, request, **kwargs):
}
}
)
def assign_warehouse(cls, instances, request, **kwargs):
def assign_warehouse(cls, instances, **kwargs):
warehouse = Warehouse.objects.get(pk=int(kwargs['warehouse']))
for instance in instances:
instance.warehouse = warehouse
Expand All @@ -329,7 +330,7 @@ def assign_warehouse(cls, instances, request, **kwargs):
}
},
)
def assign_office_infrastructure(cls, instances, request, **kwargs):
def assign_office_infrastructure(cls, instances, **kwargs):
office_inf = OfficeInfrastructure.objects.get(
pk=int(kwargs['office_infrastructure'])
)
Expand All @@ -344,7 +345,7 @@ def assign_office_infrastructure(cls, instances, request, **kwargs):
}
}
)
def add_remarks(cls, instances, request, **kwargs):
def add_remarks(cls, instances, **kwargs):
for instance in instances:
instance.remarks = '{}\n{}'.format(
instance.remarks, kwargs['remarks']
Expand All @@ -358,13 +359,13 @@ def add_remarks(cls, instances, request, **kwargs):
}
}
)
def assign_task_url(cls, instances, request, **kwargs):
def assign_task_url(cls, instances, **kwargs):
for instance in instances:
instance.task_url = kwargs['task_url']

@classmethod
@transition_action()
def unassign_licences(cls, instances, request, **kwargs):
def unassign_licences(cls, instances, **kwargs):
BaseObjectLicence.objects.filter(base_object__in=instances).delete()

@classmethod
Expand All @@ -378,7 +379,7 @@ def unassign_licences(cls, instances, request, **kwargs):
}
},
)
def change_hostname(cls, instances, request, **kwargs):
def change_hostname(cls, instances, request=None, **kwargs):
country_id = kwargs['country']
country_name = Country.name_from_id(int(country_id)).upper()
iso3_country_name = iso2_to_iso3(country_name)
Expand All @@ -401,7 +402,7 @@ def change_hostname(cls, instances, request, **kwargs):
}
}
)
def change_user_and_owner(cls, instances, request, **kwargs):
def change_user_and_owner(cls, instances, **kwargs):
UserModel = get_user_model() # noqa
user_id = kwargs.get('user', None)
user = UserModel.objects.get(id=user_id)
Expand Down Expand Up @@ -548,7 +549,7 @@ def loan_report(cls, instances, request, **kwargs):
}
}
)
def convert_to_data_center_asset(cls, instances, request, **kwargs):
def convert_to_data_center_asset(cls, instances, **kwargs):
from ralph.data_center.models.physical import DataCenterAsset, Rack # noqa
with transaction.atomic():
for i, instance in enumerate(instances):
Expand Down
4 changes: 2 additions & 2 deletions src/ralph/lib/external_services/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from .base import ExternalService
from .base import ExternalService, InternalService
from .helpers import obj_to_dict


__all__ = ['ExternalService', 'obj_to_dict']
__all__ = ['ExternalService', 'InternalService', 'obj_to_dict']
29 changes: 16 additions & 13 deletions src/ralph/lib/external_services/base.py
Original file line number Diff line number Diff line change
@@ -1,31 +1,23 @@
import time

import django_rq
from django.conf import settings
from redis import Redis
from rq import Queue

from .conf import get_redis_connection_params

redis_conn = Redis(**get_redis_connection_params())


RALPH_EXTERNAL_SERVICES = getattr(settings, 'RALPH_EXTERNAL_SERVICES', {})


class QueuedServiceError(Exception):
pass


class ExternalService(object):
services = settings.RALPH_EXTERNAL_SERVICES

def __init__(self, service_name):
"""Initializing queue and check existence of service."""
service = RALPH_EXTERNAL_SERVICES.get(service_name.upper())
service = self.services.get(service_name.upper())
if not service:
raise ValueError('The {} service doesn\'t exist'.format(service))
self.method = service['method']
self.queue = Queue(
name=service['name'], connection=redis_conn, async=True
)
self.queue = django_rq.get_queue(service['queue_name'])

def run(self, **kwargs):
"""Run function with params on external service.
Expand All @@ -50,3 +42,14 @@ def run(self, **kwargs):
while job and not any([job.is_finished, job.is_failed]):
time.sleep(0.1)
return job.result

def run_async(self, **kwargs):
job = self.queue.enqueue(self.method, kwargs=kwargs)
return job


class InternalService(ExternalService):
"""
Service with DB (and Ralph-code) access
"""
services = settings.RALPH_INTERNAL_SERVICES
6 changes: 0 additions & 6 deletions src/ralph/lib/external_services/conf.py

This file was deleted.

28 changes: 28 additions & 0 deletions src/ralph/lib/external_services/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import migrations, models
import uuid
import django_extensions.db.fields.json
import ralph.lib.mixins.fields


class Migration(migrations.Migration):

dependencies = [
]

operations = [
migrations.CreateModel(
name='Job',
fields=[
('created', models.DateTimeField(verbose_name='date created', auto_now_add=True)),
('modified', models.DateTimeField(verbose_name='last modified', auto_now=True)),
('id', models.UUIDField(serialize=False, default=uuid.uuid4, primary_key=True, editable=False)),
('user', ralph.lib.mixins.fields.NullableCharField(max_length=200, blank=True, null=True)),
('service_name', models.CharField(max_length=200)),
('params', django_extensions.db.fields.json.JSONField()),
('status', models.PositiveIntegerField(choices=[(1, 'queued'), (2, 'finished'), (3, 'failed'), (4, 'started')], default=1, verbose_name='job status')),
],
),
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('external_services', '0001_initial'),
]

operations = [
migrations.RenameField(
model_name='job',
old_name='params',
new_name='_dumped_params',
),
]
Empty file.
Loading

0 comments on commit 165af3b

Please sign in to comment.