mirror of
https://github.com/coder/coder.git
synced 2026-10-31 02:43:21 +08:00
Before refreshing, the caller has to put a lease on the row to prevent any other replicas from trying to refresh using the same token. Callers unable to get a lease enter a holding pattern waiting for the results. Also use this same lease query to re-read the link. This more or less functions the same as the re-read we used to have after a refresh failure, except it also allows us to avoid making the failed request in the first place. The downside is that we have to refetch the link every time even if the caller just fetched it, but since we have to make a database call to set the lease anyway...
33 lines
1.4 KiB
PL/PgSQL
33 lines
1.4 KiB
PL/PgSQL
ALTER TABLE external_auth_links ADD COLUMN IF NOT EXISTS refresh_lease_expires_at timestamp WITH time zone DEFAULT NULL;
|
|
COMMENT ON COLUMN external_auth_links.refresh_lease_expires_at IS 'Indicates a replica is refreshing the token; prevents concurrent refreshes.';
|
|
|
|
CREATE OR REPLACE FUNCTION acquire_external_auth_link_refresh_lease(arg_provider_id text, arg_user_id uuid, timeout_ms bigint)
|
|
RETURNS SETOF external_auth_links AS $$
|
|
DECLARE r external_auth_links;
|
|
BEGIN
|
|
UPDATE external_auth_links
|
|
SET
|
|
refresh_lease_expires_at = NOW() + (timeout_ms || ' ms')::interval
|
|
WHERE
|
|
provider_id = arg_provider_id
|
|
AND user_id = arg_user_id
|
|
AND (refresh_lease_expires_at IS NULL OR refresh_lease_expires_at < NOW())
|
|
RETURNING * INTO r;
|
|
-- Got the lease, return the one row.
|
|
IF FOUND THEN
|
|
RETURN NEXT r;
|
|
RETURN;
|
|
END IF;
|
|
-- Differentiate between unable to get the lease and the row being gone.
|
|
IF EXISTS (SELECT 1 FROM external_auth_links WHERE provider_id = arg_provider_id AND user_id = arg_user_id) THEN
|
|
RAISE EXCEPTION 'row is currently leased by another replica'
|
|
USING ERRCODE = 'check_violation',
|
|
CONSTRAINT = 'external_auth_link_active_lease';
|
|
END IF;
|
|
-- Row is gone, return nothing.
|
|
RETURN;
|
|
END;
|
|
$$ LANGUAGE plpgsql;
|
|
|
|
COMMENT ON FUNCTION acquire_external_auth_link_refresh_lease IS 'Acquire a lease on the external auth link and return the row. If there is already an active lease, an exception is raised.';
|