From 399c7287aa0dbc5876a0c182ddafddd7a2980ac9 Mon Sep 17 00:00:00 2001 From: Valentijn Scholten Date: Fri, 15 May 2026 21:44:32 +0200 Subject: [PATCH] refactor: rename dispatch kwarg sync= to force_sync= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The `sync=True` kwarg on dojo_dispatch_task / dojo_async_task forces the target task to run in the foreground. The bare name `sync` collides with unrelated `sync` parameters elsewhere in the codebase (e.g. JIRA Instance's `finding_jira_sync`, `is_keep_in_sync`) and is asymmetric with the recently-introduced `force_async=True` knob. Rename to `force_sync=` for clarity and symmetry. Hard rename — no alias. Callers updated: - dojo/decorators.py — we_want_async reads `force_sync` instead of `sync`. - dojo/celery_dispatch.py — docstring. - dojo/celery.py — DojoAsyncTask.apply_async pops `force_sync` from kwargs. - dojo/importers/default_importer.py, default_reimporter.py — propagate `force_sync` from importer kwargs to post_process_findings_batch. - dojo/finding/helper.py — post_process_findings_batch signature + nested dojo_dispatch_task(calculate_grade, ..., force_sync=force_sync). - dojo/api_v2/serializers.py, dojo/finding_group/views.py — JIRA push call sites that want foreground execution. - unittests/test_async_delete.py, test_reimport_prefetch.py, test_update_import_history.py — updated kwargs + docstrings. --- dojo/api_v2/serializers.py | 2 +- dojo/celery.py | 2 +- dojo/celery_dispatch.py | 2 +- dojo/decorators.py | 6 +++--- dojo/finding/helper.py | 4 ++-- dojo/finding_group/views.py | 4 ++-- dojo/importers/default_importer.py | 2 +- dojo/importers/default_reimporter.py | 2 +- unittests/test_async_delete.py | 12 ++++++------ unittests/test_reimport_prefetch.py | 2 +- unittests/test_update_import_history.py | 2 +- 11 files changed, 20 insertions(+), 20 deletions(-) diff --git a/dojo/api_v2/serializers.py b/dojo/api_v2/serializers.py index db2b0bd4280..dc15ac6c2dc 100644 --- a/dojo/api_v2/serializers.py +++ b/dojo/api_v2/serializers.py @@ -1474,7 +1474,7 @@ def update(self, instance, validated_data): if push_to_jira or jira_services.is_keep_in_sync(instance): # Push synchronously so that we can see jira errors in real time - success, message = jira_services.push(instance, sync=True) + success, message = jira_services.push(instance, force_sync=True) if not success: raise serializers.ValidationError(message) diff --git a/dojo/celery.py b/dojo/celery.py index 83d2e5d1e08..81dd44095d3 100644 --- a/dojo/celery.py +++ b/dojo/celery.py @@ -67,7 +67,7 @@ def apply_async(self, args=None, kwargs=None, **options): kwargs["async_user_id"] = user.id if user else None # Control flag used for sync/async decision; never pass into the task itself - kwargs.pop("sync", None) + kwargs.pop("force_sync", None) # Track dispatch dojo_async_task_counter.incr( diff --git a/dojo/celery_dispatch.py b/dojo/celery_dispatch.py index fde94336ec4..f5891c98ccd 100644 --- a/dojo/celery_dispatch.py +++ b/dojo/celery_dispatch.py @@ -61,7 +61,7 @@ def dojo_dispatch_task(task_or_sig: _SupportsSi | _SupportsApplyAsync | Signatur - Inject `async_user_id` if missing. - Capture and inject pghistory context if available. - - Respect `sync=True` (foreground execution) and user `block_execution`. + - Respect `force_sync=True` (foreground execution) and user `block_execution`. - Support `countdown=` for async dispatch. Returns: diff --git a/dojo/decorators.py b/dojo/decorators.py index bc3b898a3e1..27fc1a7b8e5 100644 --- a/dojo/decorators.py +++ b/dojo/decorators.py @@ -58,9 +58,9 @@ def get_tasks(self): def we_want_async(*args, func=None, **kwargs): from dojo.utils import get_current_user # noqa: PLC0415 circular import - sync = kwargs.get("sync", False) - if sync: - logger.debug("dojo_async_task %s: running task in the foreground as sync=True has been found as kwarg", func) + force_sync = kwargs.get("force_sync", False) + if force_sync: + logger.debug("dojo_async_task %s: running task in the foreground as force_sync=True has been found as kwarg", func) return False user = get_current_user() diff --git a/dojo/finding/helper.py b/dojo/finding/helper.py index 0a7eb0bcdfe..5eadcf0d18e 100644 --- a/dojo/finding/helper.py +++ b/dojo/finding/helper.py @@ -467,7 +467,7 @@ def post_process_findings_batch( push_to_jira=False, jira_instance_id=None, user=None, - sync=False, + force_sync=False, **kwargs, ): @@ -510,7 +510,7 @@ def post_process_findings_batch( if product_grading_option and system_settings.enable_product_grade: from dojo.celery_dispatch import dojo_dispatch_task # noqa: PLC0415 circular import - dojo_dispatch_task(calculate_grade, findings[0].test.engagement.product.id, sync=sync) + dojo_dispatch_task(calculate_grade, findings[0].test.engagement.product.id, force_sync=force_sync) # If we received the ID of a jira instance, then we need to determine the keep in sync behavior jira_instance = None diff --git a/dojo/finding_group/views.py b/dojo/finding_group/views.py index 5c5c78842f9..c77ddefccd5 100644 --- a/dojo/finding_group/views.py +++ b/dojo/finding_group/views.py @@ -97,7 +97,7 @@ def view_finding_group(request, fgid): elif not finding_group.has_jira_issue: jira_services.link_finding_group(request, finding_group, jira_issue) elif push_to_jira: - jira_services.push(finding_group, sync=True) + jira_services.push(finding_group, force_sync=True) finding_group.save() return HttpResponseRedirect(reverse("view_test", args=(finding_group.test.id,))) @@ -194,7 +194,7 @@ def push_to_jira(request, fgid): # it may look like success here, but the push_to_jira are swallowing exceptions # but cant't change too much now without having a test suite, so leave as is for now with the addition warning message to check alerts for background errors. - if jira_services.push(group, sync=True): + if jira_services.push(group, force_sync=True): messages.add_message( request, messages.SUCCESS, diff --git a/dojo/importers/default_importer.py b/dojo/importers/default_importer.py index 428b8ad01a7..8179d4b53d6 100644 --- a/dojo/importers/default_importer.py +++ b/dojo/importers/default_importer.py @@ -279,7 +279,7 @@ def process_findings( product_grading_option=True, issue_updater_option=True, push_to_jira=push_to_jira, - sync=kwargs.get("sync", False), + force_sync=kwargs.get("force_sync", False), ) # No chord: tasks are dispatched immediately above per batch diff --git a/dojo/importers/default_reimporter.py b/dojo/importers/default_reimporter.py index 3df3c0bd4cc..6fee56a257d 100644 --- a/dojo/importers/default_reimporter.py +++ b/dojo/importers/default_reimporter.py @@ -434,7 +434,7 @@ def process_findings( issue_updater_option=True, push_to_jira=push_to_jira, jira_instance_id=getattr(self.jira_instance, "id", None), - sync=kwargs.get("sync", False), + force_sync=kwargs.get("force_sync", False), ) # No chord: tasks are dispatched immediately above per batch diff --git a/unittests/test_async_delete.py b/unittests/test_async_delete.py index 1554432ef50..7aa8f0769a1 100644 --- a/unittests/test_async_delete.py +++ b/unittests/test_async_delete.py @@ -252,11 +252,11 @@ def test_async_delete_product_with_hierarchy(self): ) @override_settings(ASYNC_OBJECT_DELETE=True) - def test_async_delete_accepts_sync_kwarg(self): + def test_async_delete_accepts_force_sync_kwarg(self): """ - Test that async_delete passes through the sync kwarg properly. + Test that async_delete passes through the force_sync kwarg properly. - The sync=True kwarg forces synchronous execution for the top-level task. + The force_sync=True kwarg forces synchronous execution for the top-level task. However, nested task dispatches still need user context to run synchronously, so we use impersonate here as well. """ @@ -265,14 +265,14 @@ def test_async_delete_accepts_sync_kwarg(self): # Use impersonate to ensure nested tasks also run synchronously with impersonate(self.testuser): - # Explicitly pass sync=True + # Explicitly pass force_sync=True async_del = async_delete() - async_del.delete(product, sync=True) + async_del.delete(product, force_sync=True) # Verify the product was deleted self.assertFalse( Product.objects.filter(pk=product_pk).exists(), - "Product should be deleted with sync=True", + "Product should be deleted with force_sync=True", ) def test_async_delete_helper_methods(self): diff --git a/unittests/test_reimport_prefetch.py b/unittests/test_reimport_prefetch.py index d421b0129dc..cc5b2f40e1e 100644 --- a/unittests/test_reimport_prefetch.py +++ b/unittests/test_reimport_prefetch.py @@ -118,7 +118,7 @@ def _reimport_with_overridden_hashcode(self): minimum_severity="Info", active=True, verified=True, - sync=True, + force_sync=True, scan_type=SCAN_TYPE, ) return reimporter.process_scan(scan) diff --git a/unittests/test_update_import_history.py b/unittests/test_update_import_history.py index 346458052b0..6b88e30837a 100644 --- a/unittests/test_update_import_history.py +++ b/unittests/test_update_import_history.py @@ -72,7 +72,7 @@ def setUp(self): minimum_severity="Info", active=True, verified=True, - sync=True, + force_sync=True, scan_type="StackHawk HawkScan", ) # Explicitly create the Test similar to Engagement creation