From 5fdcc5ae0f3eb3849bd4beea3e3d416449b835e0 Mon Sep 17 00:00:00 2001 From: Shane Walker Date: Tue, 7 Jan 2025 13:46:21 -0300 Subject: [PATCH] trigger observation edit on itc and digest updates --- .../migration/V0939__trigger_on_obs_cache.sql | 27 ++++++ .../observationEditOnCachedResultUpdate.scala | 97 +++++++++++++++++++ 2 files changed, 124 insertions(+) create mode 100644 modules/service/src/main/resources/db/migration/V0939__trigger_on_obs_cache.sql create mode 100644 modules/service/src/test/scala/lucuma/odb/graphql/subscription/observationEditOnCachedResultUpdate.scala diff --git a/modules/service/src/main/resources/db/migration/V0939__trigger_on_obs_cache.sql b/modules/service/src/main/resources/db/migration/V0939__trigger_on_obs_cache.sql new file mode 100644 index 000000000..7a80a6d02 --- /dev/null +++ b/modules/service/src/main/resources/db/migration/V0939__trigger_on_obs_cache.sql @@ -0,0 +1,27 @@ +-- A trigger function which sends a 'ch_observation_edit' notify. Can be used +-- for any table associated with an observation that has c_program_id and +-- c_observation_id columns. +CREATE OR REPLACE FUNCTION ch_observation_edit_associated_table_update() + RETURNS trigger AS $$ +DECLARE + rec record; +BEGIN + rec := COALESCE(NEW, OLD); + PERFORM pg_notify('ch_observation_edit', rec.c_observation_id || ',' || rec.c_program_id || ',' || 'UPDATE'); + RETURN rec; +END; +$$ LANGUAGE plpgsql; + +-- Use the function for updates on ITC results and execution digest. + +CREATE CONSTRAINT TRIGGER ch_observation_edit_itc_result_trigger + AFTER INSERT OR UPDATE OR DELETE ON t_itc_result + DEFERRABLE + FOR EACH ROW + EXECUTE PROCEDURE ch_observation_edit_associated_table_update(); + +CREATE CONSTRAINT TRIGGER ch_observation_edit_execution_digest_trigger + AFTER INSERT OR UPDATE OR DELETE ON t_execution_digest + DEFERRABLE + FOR EACH ROW + EXECUTE PROCEDURE ch_observation_edit_associated_table_update(); \ No newline at end of file diff --git a/modules/service/src/test/scala/lucuma/odb/graphql/subscription/observationEditOnCachedResultUpdate.scala b/modules/service/src/test/scala/lucuma/odb/graphql/subscription/observationEditOnCachedResultUpdate.scala new file mode 100644 index 000000000..36af5498a --- /dev/null +++ b/modules/service/src/test/scala/lucuma/odb/graphql/subscription/observationEditOnCachedResultUpdate.scala @@ -0,0 +1,97 @@ +// Copyright (c) 2016-2023 Association of Universities for Research in Astronomy, Inc. (AURA) +// For license information see LICENSE or https://opensource.org/licenses/BSD-3-Clause + +package lucuma.odb.graphql +package subscription + +import io.circe.Json +import io.circe.literal.* +import lucuma.core.model.Observation +import lucuma.core.model.User +import lucuma.odb.graphql.query.ExecutionTestSupport + +class observationEditOnCachedResultUpdate extends ExecutionTestSupport with SubscriptionUtils: + + def updateSubscription(oid: Observation.Id): String = + s""" + subscription { + observationEdit(input: { observationId: "$oid" }) { + editType + } + } + """ + + val updateResponse: Json = + json""" + { + "observationEdit": { + "editType": "UPDATED" + } + } + """ + + def requestItcResult(user: User, oid: Observation.Id) = + sleep >> + query( + user = user, + query = s""" + query { + observation(observationId: "$oid") { + itc { + science { + selected { + exposureCount + } + } + } + } + } + """ + ).void + + def requestSequenceDigest(user: User, oid: Observation.Id) = + sleep >> + query( + user = user, + query = s""" + query { + observation(observationId: "$oid") { + execution { + digest { + science { + atomCount + } + } + } + } + } + """ + ) + + test("triggers when caching an ITC result"): + for + pid <- createProgram(pi, "foo") + tid <- createTargetWithProfileAs(pi, pid) + oid <- createGmosNorthLongSlitObservationAs(pi, pid, List(tid)) + + _ <- subscriptionExpect( + user = pi, + query = updateSubscription(oid), + mutations = Right(requestItcResult(pi, oid)), + expected = List(updateResponse) + ) + yield () + + test("triggers when caching sequence digest"): + for + pid <- createProgram(pi, "foo") + tid <- createTargetWithProfileAs(pi, pid) + oid <- createGmosNorthLongSlitObservationAs(pi, pid, List(tid)) + + _ <- subscriptionExpect( + user = pi, + query = updateSubscription(oid), + mutations = Right(requestSequenceDigest(pi, oid)), + expected = List(updateResponse, updateResponse) // caches ITC and then sequence digest + ) + yield () \ No newline at end of file