mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
feat: add single tailnet support to pgcoord (#9351)
This commit is contained in:
@@ -0,0 +1,39 @@
|
||||
BEGIN;
|
||||
|
||||
ALTER TABLE
|
||||
tailnet_clients
|
||||
ADD COLUMN
|
||||
agent_id uuid;
|
||||
|
||||
UPDATE
|
||||
tailnet_clients
|
||||
SET
|
||||
-- there's no reason for us to try and preserve data since coordinators will
|
||||
-- have to restart anyways, which will create all of the client mappings.
|
||||
agent_id = '00000000-0000-0000-0000-000000000000'::uuid;
|
||||
|
||||
ALTER TABLE
|
||||
tailnet_clients
|
||||
ALTER COLUMN
|
||||
agent_id SET NOT NULL;
|
||||
|
||||
DROP TABLE tailnet_client_subscriptions;
|
||||
DROP FUNCTION tailnet_notify_client_subscription_change;
|
||||
|
||||
-- update the tailnet_clients trigger to the old version.
|
||||
CREATE OR REPLACE FUNCTION tailnet_notify_client_change() RETURNS trigger
|
||||
LANGUAGE plpgsql
|
||||
AS $$
|
||||
BEGIN
|
||||
IF (OLD IS NOT NULL) THEN
|
||||
PERFORM pg_notify('tailnet_client_update', OLD.id || ',' || OLD.agent_id);
|
||||
RETURN NULL;
|
||||
END IF;
|
||||
IF (NEW IS NOT NULL) THEN
|
||||
PERFORM pg_notify('tailnet_client_update', NEW.id || ',' || NEW.agent_id);
|
||||
RETURN NULL;
|
||||
END IF;
|
||||
END;
|
||||
$$;
|
||||
|
||||
COMMIT;
|
||||
@@ -0,0 +1,88 @@
|
||||
BEGIN;
|
||||
|
||||
CREATE TABLE tailnet_client_subscriptions (
|
||||
client_id uuid NOT NULL,
|
||||
coordinator_id uuid NOT NULL,
|
||||
-- this isn't a foreign key since it's more of a list of agents the client
|
||||
-- *wants* to connect to, and they don't necessarily have to currently
|
||||
-- exist in the db.
|
||||
agent_id uuid NOT NULL,
|
||||
updated_at timestamp with time zone NOT NULL,
|
||||
PRIMARY KEY (client_id, coordinator_id, agent_id),
|
||||
FOREIGN KEY (coordinator_id) REFERENCES tailnet_coordinators (id) ON DELETE CASCADE
|
||||
-- we don't keep a foreign key to the tailnet_clients table since there's
|
||||
-- not a great way to guarantee that a subscription is always added after
|
||||
-- the client is inserted. clients are only created after the client sends
|
||||
-- its first node update, which can take an undetermined amount of time.
|
||||
);
|
||||
|
||||
CREATE FUNCTION tailnet_notify_client_subscription_change() RETURNS trigger
|
||||
LANGUAGE plpgsql
|
||||
AS $$
|
||||
BEGIN
|
||||
IF (NEW IS NOT NULL) THEN
|
||||
PERFORM pg_notify('tailnet_client_update', NEW.client_id || ',' || NEW.agent_id);
|
||||
RETURN NULL;
|
||||
ELSIF (OLD IS NOT NULL) THEN
|
||||
PERFORM pg_notify('tailnet_client_update', OLD.client_id || ',' || OLD.agent_id);
|
||||
RETURN NULL;
|
||||
END IF;
|
||||
END;
|
||||
$$;
|
||||
|
||||
CREATE TRIGGER tailnet_notify_client_subscription_change
|
||||
AFTER INSERT OR UPDATE OR DELETE ON tailnet_client_subscriptions
|
||||
FOR EACH ROW
|
||||
EXECUTE PROCEDURE tailnet_notify_client_subscription_change();
|
||||
|
||||
CREATE OR REPLACE FUNCTION tailnet_notify_client_change() RETURNS trigger
|
||||
LANGUAGE plpgsql
|
||||
AS $$
|
||||
DECLARE
|
||||
var_client_id uuid;
|
||||
var_coordinator_id uuid;
|
||||
var_agent_ids uuid[];
|
||||
var_agent_id uuid;
|
||||
BEGIN
|
||||
IF (NEW.id IS NOT NULL) THEN
|
||||
var_client_id = NEW.id;
|
||||
var_coordinator_id = NEW.coordinator_id;
|
||||
ELSIF (OLD.id IS NOT NULL) THEN
|
||||
var_client_id = OLD.id;
|
||||
var_coordinator_id = OLD.coordinator_id;
|
||||
END IF;
|
||||
|
||||
-- Read all agents the client is subscribed to, so we can notify them.
|
||||
SELECT
|
||||
array_agg(agent_id)
|
||||
INTO
|
||||
var_agent_ids
|
||||
FROM
|
||||
tailnet_client_subscriptions subs
|
||||
WHERE
|
||||
subs.client_id = NEW.id AND
|
||||
subs.coordinator_id = NEW.coordinator_id;
|
||||
|
||||
-- No agents to notify
|
||||
if (var_agent_ids IS NULL) THEN
|
||||
return NULL;
|
||||
END IF;
|
||||
|
||||
-- pg_notify is limited to 8k bytes, which is approximately 221 UUIDs.
|
||||
-- Instead of sending all agent ids in a single update, send one for each
|
||||
-- agent id to prevent overflow.
|
||||
FOREACH var_agent_id IN ARRAY var_agent_ids
|
||||
LOOP
|
||||
PERFORM pg_notify('tailnet_client_update', var_client_id || ',' || var_agent_id);
|
||||
END LOOP;
|
||||
|
||||
return NULL;
|
||||
END;
|
||||
$$;
|
||||
|
||||
ALTER TABLE
|
||||
tailnet_clients
|
||||
DROP COLUMN
|
||||
agent_id;
|
||||
|
||||
COMMIT;
|
||||
@@ -18,7 +18,7 @@ VALUES
|
||||
);
|
||||
|
||||
INSERT INTO tailnet_agents
|
||||
(id, coordinator_id, updated_at, node)
|
||||
(id, coordinator_id, updated_at, node)
|
||||
VALUES
|
||||
(
|
||||
'c0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11',
|
||||
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
INSERT INTO tailnet_client_subscriptions
|
||||
(client_id, agent_id, coordinator_id, updated_at)
|
||||
VALUES
|
||||
(
|
||||
'b0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11',
|
||||
'c0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11',
|
||||
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11',
|
||||
'2023-06-15 10:23:54+00'
|
||||
);
|
||||
Reference in New Issue
Block a user