mirror of
https://github.com/inventree/InvenTree.git
synced 2026-09-28 06:36:00 +00:00
Use one-shot tasks for label print batches (#12939)
* Disable retries for label print batch tasks * Remove label failure retry guard for one-shot jobs
This commit is contained in:
@@ -226,6 +226,7 @@ class LabelPrint(GenericAPIView):
|
||||
output.pk,
|
||||
user.pk if user else None,
|
||||
plugin.slug,
|
||||
retry=False,
|
||||
options=(plugin_serializer.data if plugin_serializer else {}),
|
||||
)
|
||||
|
||||
|
||||
@@ -118,13 +118,6 @@ def print_labels(
|
||||
)
|
||||
return
|
||||
|
||||
if output.errors:
|
||||
# A failed job may have printed some labels already - do not print them again
|
||||
logger.info(
|
||||
'DataOutput %s has already failed - skipping print_labels task', output_id
|
||||
)
|
||||
return
|
||||
|
||||
# Fetch user information
|
||||
user = None
|
||||
|
||||
|
||||
@@ -549,6 +549,38 @@ class LabelTest(InvenTreeAPITestCase):
|
||||
output = plugin.get_generated_file(**kwargs)
|
||||
self.assertEqual(output.name, expected)
|
||||
|
||||
def test_print_task_single_shot(self):
|
||||
"""API print jobs acknowledge failures without retrying the whole label batch."""
|
||||
from django_q.models import OrmQ
|
||||
|
||||
OrmQ.objects.all().delete()
|
||||
|
||||
template = LabelTemplate.objects.filter(enabled=True, model_type='part').first()
|
||||
part = Part.objects.first()
|
||||
|
||||
with patch('InvenTree.status.is_worker_running', return_value=True):
|
||||
response = self.post(
|
||||
reverse('api-label-print'),
|
||||
data={'template': template.pk, 'items': [part.pk]},
|
||||
expected_code=201,
|
||||
)
|
||||
|
||||
task = OrmQ.objects.get()
|
||||
self.assertEqual(task.func(), 'report.tasks.print_labels')
|
||||
self.assertTrue(task.q_options().get('ack_failure'))
|
||||
self.assertEqual(
|
||||
task.args(),
|
||||
(
|
||||
template.pk,
|
||||
[part.pk],
|
||||
response.data['pk'],
|
||||
self.user.pk,
|
||||
'inventreelabel',
|
||||
),
|
||||
)
|
||||
self.assertEqual(task.kwargs(), {'options': {}})
|
||||
self.assertFalse(response.data['complete'])
|
||||
|
||||
def test_print_failure(self):
|
||||
"""Printing failures retain their details and propagate to the caller."""
|
||||
template = LabelTemplate.objects.filter(enabled=True, model_type='part').first()
|
||||
@@ -604,35 +636,6 @@ class LabelTest(InvenTreeAPITestCase):
|
||||
'Error printing labels: printer unavailable',
|
||||
)
|
||||
|
||||
if worker:
|
||||
original = (
|
||||
report_models.DataOutput.objects
|
||||
.filter(pk=output.pk)
|
||||
.values()
|
||||
.get()
|
||||
)
|
||||
with patch.object(
|
||||
registry, 'get_plugin', return_value=plugin
|
||||
) as get_plugin:
|
||||
print_labels(
|
||||
template.pk,
|
||||
[part.pk for part in parts],
|
||||
output.pk,
|
||||
self.user.pk,
|
||||
plugin.slug,
|
||||
options={},
|
||||
)
|
||||
|
||||
get_plugin.assert_not_called()
|
||||
plugin.print_labels.assert_called_once()
|
||||
self.assertEqual(
|
||||
report_models.DataOutput.objects
|
||||
.filter(pk=output.pk)
|
||||
.values()
|
||||
.get(),
|
||||
original,
|
||||
)
|
||||
|
||||
def test_print_unavailable_plugin(self):
|
||||
"""An unavailable worker plugin records a failure instead of hanging."""
|
||||
template = LabelTemplate.objects.filter(enabled=True, model_type='part').first()
|
||||
@@ -660,23 +663,6 @@ class LabelTest(InvenTreeAPITestCase):
|
||||
{'error': "Label printing plugin 'unavailable-label' not found"},
|
||||
)
|
||||
|
||||
original = report_models.DataOutput.objects.filter(pk=output.pk).values().get()
|
||||
plugin = Mock(spec=['slug', 'print_labels'], slug=output.plugin)
|
||||
with (
|
||||
patch.object(registry, 'get_plugin', return_value=plugin) as get_plugin,
|
||||
patch.object(LabelTemplate, 'print') as print_template,
|
||||
):
|
||||
print_labels(
|
||||
template.pk, [], output.pk, self.user.pk, output.plugin, options={}
|
||||
)
|
||||
|
||||
get_plugin.assert_not_called()
|
||||
print_template.assert_not_called()
|
||||
self.assertEqual(
|
||||
report_models.DataOutput.objects.filter(pk=output.pk).values().get(),
|
||||
original,
|
||||
)
|
||||
|
||||
def test_print_task_duplicate(self):
|
||||
"""Duplicate tasks skip completed or deleted outputs before plugin lookup."""
|
||||
template = LabelTemplate.objects.filter(enabled=True, model_type='part').first()
|
||||
|
||||
Reference in New Issue
Block a user