From 42fbdd3d9fb019b05c5f62192f096f778d59ed77 Mon Sep 17 00:00:00 2001 From: Kelvin Muchiri Date: Thu, 15 Aug 2024 14:08:06 +0300 Subject: [PATCH] fix stale data sent to rest services when editing submission The data sent to rest services can be stale if the instance is not yet saved to the database when a submission is edited --- .../apps/restservice/services/generic_json.py | 4 +-- onadata/apps/restservice/services/textit.py | 4 +-- onadata/apps/restservice/signals.py | 25 ++++--------------- onadata/apps/restservice/tasks.py | 8 +++++- 4 files changed, 14 insertions(+), 27 deletions(-) diff --git a/onadata/apps/restservice/services/generic_json.py b/onadata/apps/restservice/services/generic_json.py index 7185a74836..76bb014b61 100644 --- a/onadata/apps/restservice/services/generic_json.py +++ b/onadata/apps/restservice/services/generic_json.py @@ -24,9 +24,7 @@ class ServiceDefinition(RestServiceInterface): # pylint: disable=too-few-public def send(self, url, data=None): """Post submisison JSON data to an external service that accepts a JSON post.""" if data: - # We use Instance.get_full_dict() instead of Instance.json because - # when asynchronous processing is enabled, the json may not be upto date - post_data = json.dumps(data.get_full_dict()) + post_data = json.dumps(data.json) headers = {"Content-Type": "application/json"} try: requests.post( diff --git a/onadata/apps/restservice/services/textit.py b/onadata/apps/restservice/services/textit.py index 945e40d1af..92eeed6ed0 100644 --- a/onadata/apps/restservice/services/textit.py +++ b/onadata/apps/restservice/services/textit.py @@ -33,9 +33,7 @@ def send(self, url, data=None): :param data: :return: """ - # We use Instance.get_full_dict() instead of Instance.json because - # when asynchronous processing is enabled, the json may not be upto date - extra_data = self.clean_keys_of_slashes(data.get_full_dict()) + extra_data = self.clean_keys_of_slashes(data.json) data_value = MetaData.textit(data.xform) if data_value: diff --git a/onadata/apps/restservice/signals.py b/onadata/apps/restservice/signals.py index c1e870cbe2..b9d7c94821 100644 --- a/onadata/apps/restservice/signals.py +++ b/onadata/apps/restservice/signals.py @@ -3,16 +3,9 @@ RestService signals module """ import django.dispatch -from django.conf import settings -from multidb.pinning import use_master from onadata.apps.restservice.tasks import call_service_async -from onadata.apps.restservice.utils import call_service -from onadata.apps.logger.models.instance import Instance -ASYNC_POST_SUBMISSION_PROCESSING_ENABLED = getattr( - settings, "ASYNC_POST_SUBMISSION_PROCESSING_ENABLED", False -) # pylint: disable=invalid-name trigger_webhook = django.dispatch.Signal() @@ -22,19 +15,11 @@ def call_webhooks(sender, **kwargs): # pylint: disable=unused-argument """ Call webhooks signal. """ - instance_id = kwargs["instance"].pk - if ASYNC_POST_SUBMISSION_PROCESSING_ENABLED: - call_service_async.apply_async(args=[instance_id], countdown=1) - else: - with use_master: - try: - instance = Instance.objects.get(pk=instance_id) - except Instance.DoesNotExist: - # if the instance has already been removed we do not send it to the - # service - pass - else: - call_service(instance) + instance = kwargs["instance"] + + call_service_async.apply_async( + args=[instance.pk, instance.get_full_dict()], countdown=1 + ) trigger_webhook.connect(call_webhooks, dispatch_uid="call_webhooks") diff --git a/onadata/apps/restservice/tasks.py b/onadata/apps/restservice/tasks.py index 1aeaaa4ac6..c76a8d00e6 100644 --- a/onadata/apps/restservice/tasks.py +++ b/onadata/apps/restservice/tasks.py @@ -8,7 +8,7 @@ @app.task() -def call_service_async(instance_pk): +def call_service_async(instance_pk, latest_json=None): """Async function that calls call_service().""" # load the parsed instance @@ -19,4 +19,10 @@ def call_service_async(instance_pk): # service pass else: + if latest_json is None: + instance.json = instance.get_full_dict() + + else: + instance.json = latest_json + call_service(instance)