fix: move sealing to a background job (#1287)

When signing a document the final signer is often
greeted with a super long completing spinner since
we are synchronously signing the document and sending
emails to all recipients. This is frustrating and
has caused issues for customers and self-hosters.

Moving sealing to a background job resolves this
and improves the overall snappiness of the app while
also supporting retrying the sealing if it were to
fail in the future.

This has the implication of a document no longer
immediately being in a "completed" state once all
signers have signed. To assist with this we now
refetch the page every 5 seconds upon signing
completion until the document status as shifted to
completed.
This commit is contained in:
Lucas Smith
2024-08-14 13:12:32 +10:00
committed by GitHub
parent 20ec2dde3d
commit ab8701526c
9 changed files with 326 additions and 23 deletions

View File

@ -26,6 +26,7 @@ import { truncateTitle } from '~/helpers/truncate-title';
import { SigningAuthPageView } from '../signing-auth-page';
import { ClaimAccount } from './claim-account';
import { DocumentPreviewButton } from './document-preview-button';
import { PollUntilDocumentCompleted } from './poll-until-document-completed';
export type CompletedSigningPageProps = {
params: {
@ -205,6 +206,8 @@ export default async function CompletedSigningPage({
</Link>
)}
</div>
<PollUntilDocumentCompleted document={document} />
</div>
);
}

View File

@ -0,0 +1,32 @@
'use client';
import { useEffect } from 'react';
import { useRouter } from 'next/navigation';
import type { Document } from '@documenso/prisma/client';
import { DocumentStatus } from '@documenso/prisma/client';
export type PollUntilDocumentCompletedProps = {
document: Pick<Document, 'id' | 'status' | 'deletedAt'>;
};
export const PollUntilDocumentCompleted = ({ document }: PollUntilDocumentCompletedProps) => {
const router = useRouter();
useEffect(() => {
if (document.status === DocumentStatus.COMPLETED) {
return;
}
const interval = setInterval(() => {
if (window.document.hasFocus()) {
router.refresh();
}
}, 5000);
return () => clearInterval(interval);
}, [router, document.status]);
return <></>;
};