fix(sync): let the server own updated_at on insert for cursor-pulled tables
This commit is contained in:
parent
2251fe2da1
commit
f517eedffc
2 changed files with 265 additions and 0 deletions
|
|
@ -0,0 +1,68 @@
|
|||
-- Server-owned sync timestamps.
|
||||
--
|
||||
-- The desktop mirror (SyncEngine.pullEntity) and the audio sync read every
|
||||
-- synced table with a (updated_at, id) keyset cursor and rewind it by only a
|
||||
-- minute. That cursor is only sound when updated_at is a server clock value
|
||||
-- for every write. moddatetime already owns it on UPDATE, but an INSERT kept
|
||||
-- whatever updated_at the client sent:
|
||||
--
|
||||
-- a) a row recorded offline at T0 and pushed a day later landed behind every
|
||||
-- other desktop's cursor and was never pulled there;
|
||||
-- b) a desktop whose clock ran ahead inserted rows in the future, pushed the
|
||||
-- other desktops' cursors ahead with them, and every server-stamped edit in
|
||||
-- that window was then skipped for good;
|
||||
-- c) restore_account_portability re-inserted archived updated_at values, so a
|
||||
-- desktop that already applied the delete tombstones never got the rows
|
||||
-- back.
|
||||
--
|
||||
-- From here on the server stamps updated_at on INSERT as well. user_templates
|
||||
-- had no UPDATE stamp at all (only its RPC set it), so it gets one too. The
|
||||
-- value is now(), the same clock moddatetime uses, so INSERT and UPDATE share
|
||||
-- one cursor timeline and the existing overlap window still covers late
|
||||
-- commits.
|
||||
|
||||
BEGIN;
|
||||
|
||||
CREATE OR REPLACE FUNCTION public.stamp_sync_timestamp_v1()
|
||||
RETURNS trigger
|
||||
LANGUAGE plpgsql
|
||||
SET search_path = ''
|
||||
AS $$
|
||||
BEGIN
|
||||
NEW.updated_at := pg_catalog.now();
|
||||
RETURN NEW;
|
||||
END;
|
||||
$$;
|
||||
|
||||
REVOKE ALL ON FUNCTION public.stamp_sync_timestamp_v1() FROM PUBLIC, anon, authenticated;
|
||||
|
||||
DO $$
|
||||
DECLARE
|
||||
t text;
|
||||
BEGIN
|
||||
FOREACH t IN ARRAY ARRAY[
|
||||
'history',
|
||||
'dictionary',
|
||||
'meetings',
|
||||
'meeting_memos',
|
||||
'meeting_documents',
|
||||
'custom_instructions',
|
||||
'user_templates',
|
||||
'knowledge_documents'
|
||||
]
|
||||
LOOP
|
||||
EXECUTE format('DROP TRIGGER IF EXISTS stamp_sync_insert_v1 ON public.%I', t);
|
||||
EXECUTE format(
|
||||
'CREATE TRIGGER stamp_sync_insert_v1 BEFORE INSERT ON public.%I '
|
||||
'FOR EACH ROW EXECUTE FUNCTION public.stamp_sync_timestamp_v1()',
|
||||
t
|
||||
);
|
||||
END LOOP;
|
||||
END $$;
|
||||
|
||||
DROP TRIGGER IF EXISTS stamp_sync_update_v1 ON public.user_templates;
|
||||
CREATE TRIGGER stamp_sync_update_v1
|
||||
BEFORE UPDATE ON public.user_templates
|
||||
FOR EACH ROW EXECUTE FUNCTION public.stamp_sync_timestamp_v1();
|
||||
|
||||
COMMIT;
|
||||
Loading…
Add table
Add a link
Reference in a new issue