Skip to content

Commit

Permalink
save extended properties only when asked for (#316)
Browse files Browse the repository at this point in the history
* save extended properties only when asked for

* lint

* bugfix: args and kwargs swapped

* update: conf value to make previous tests happy

* add: tests to verify result_extended flag works

* move: using attr from extended properties

* update: changelog
  • Loading branch information
AmitPhulera committed Jun 12, 2022
1 parent e174c99 commit ad508fe
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 41 deletions.
10 changes: 10 additions & 0 deletions Changelog
Expand Up @@ -4,6 +4,16 @@
Change history
================

.. _version-2.4.0:

2.4.0
=====
:release-date: NA
:release-by: NA

- Fix [#315](https://github.com/celery/django-celery-results/issues/315) Save args, kwargs and other extended props only when result_extended config is set to True


.. _version-2.3.1:

2.3.1
Expand Down
101 changes: 60 additions & 41 deletions django_celery_results/backends/database.py
Expand Up @@ -54,6 +54,51 @@ def exception_safe_to_retry(self, exc):
return True
return False

def _get_extended_properties(self, request, traceback):
extended_props = {
'periodic_task_name': None,
'task_args': None,
'task_kwargs': None,
'task_name': None,
'traceback': None,
'worker': None,
}
if request and self.app.conf.find_value_for_key('extended', 'result'):

if getattr(request, 'argsrepr', None) is not None:
# task protocol 2
task_args = request.argsrepr
else:
# task protocol 1
task_args = getattr(request, 'args', None)

if getattr(request, 'kwargsrepr', None) is not None:
# task protocol 2
task_kwargs = request.kwargsrepr
else:
# task protocol 1
task_kwargs = getattr(request, 'kwargs', None)

# Encode input arguments
if task_args is not None:
_, _, task_args = self.encode_content(task_args)

if task_kwargs is not None:
_, _, task_kwargs = self.encode_content(task_kwargs)

properties = getattr(request, 'properties', {}) or {}
periodic_task_name = properties.get('periodic_task_name', None)
extended_props.update({
'periodic_task_name': periodic_task_name,
'task_args': task_args,
'task_kwargs': task_kwargs,
'task_name': getattr(request, 'task', None),
'traceback': traceback,
'worker': getattr(request, 'hostname', None),
})

return extended_props

def _store_result(
self,
task_id,
Expand All @@ -69,48 +114,22 @@ def _store_result(
{'children': self.current_task_children(request)}
)

task_name = getattr(request, 'task', None)
properties = getattr(request, 'properties', {}) or {}
periodic_task_name = properties.get('periodic_task_name', None)
worker = getattr(request, 'hostname', None)

# Get input arguments
if getattr(request, 'argsrepr', None) is not None:
# task protocol 2
task_args = request.argsrepr
else:
# task protocol 1
task_args = getattr(request, 'args', None)

if getattr(request, 'kwargsrepr', None) is not None:
# task protocol 2
task_kwargs = request.kwargsrepr
else:
# task protocol 1
task_kwargs = getattr(request, 'kwargs', None)

# Encode input arguments
if task_args is not None:
_, _, task_args = self.encode_content(task_args)

if task_kwargs is not None:
_, _, task_kwargs = self.encode_content(task_kwargs)

self.TaskModel._default_manager.store_result(
content_type,
content_encoding,
task_id,
result,
status,
traceback=traceback,
meta=meta,
periodic_task_name=periodic_task_name,
task_name=task_name,
task_args=task_args,
task_kwargs=task_kwargs,
worker=worker,
using=using,
task_props = {
'content_encoding': content_encoding,
'content_type': content_type,
'meta': meta,
'result': result,
'status': status,
'task_id': task_id,
'traceback': traceback,
'using': using,
}

task_props.update(
self._get_extended_properties(request, traceback)
)

self.TaskModel._default_manager.store_result(**task_props)
return result

def _get_task_meta_for(self, task_id):
Expand Down
28 changes: 28 additions & 0 deletions t/unit/backends/test_database.py
Expand Up @@ -31,6 +31,7 @@ def setup_backend(self):
self.app.conf.result_serializer = 'json'
self.app.conf.result_backend = (
'django_celery_results.backends:DatabaseBackend')
self.app.conf.result_extended = True
self.b = DatabaseBackend(app=self.app)

def _create_request(self, task_id, name, args, kwargs,
Expand Down Expand Up @@ -859,3 +860,30 @@ def test_groupresult_save_restore_nested(self):
restored_group = self.b.restore_group(group_id=group_id)

assert restored_group == group

def test_backend_result_extended_is_false(self):
self.app.conf.result_extended = False
self.b = DatabaseBackend(app=self.app)
tid2 = uuid()
request = self._create_request(
task_id=tid2,
name='my_task',
args=['a', 1, True],
kwargs={'c': 6, 'd': 'e', 'f': False},
)
result = 'foo'

self.b.mark_as_done(tid2, result, request=request)

mindb = self.b.get_task_meta(tid2)

# check meta data
assert mindb.get('result') == 'foo'
assert mindb.get('task_name') is None
assert mindb.get('task_args') is None
assert mindb.get('task_kwargs') is None

# check task_result object
tr = TaskResult.objects.get(task_id=tid2)
assert tr.task_args is None
assert tr.task_kwargs is None

1 comment on commit ad508fe

@auvipy
Copy link
Member

@auvipy auvipy commented on ad508fe Jul 6, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

might need to revert this commit as it possibly creates a regression, can you check please?

Please sign in to comment.