Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add error column to notifications table #287

Merged
merged 4 commits into from
Sep 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions models/notifications.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ type Notification struct {
UpdatedAt time.Time `json:"updated_at" time_format:"postgres_timestamp" gorm:"<-:false"`
CreatedAt time.Time `json:"created_at" time_format:"postgres_timestamp" gorm:"<-:false"`
DeletedAt *time.Time `json:"deleted_at,omitempty"`

// Error stores errors in notification filters (if any)
Error *string `json:"error,omitempty"`
}

func (n *Notification) HasRecipients() bool {
Expand Down
4 changes: 4 additions & 0 deletions schema/notifications.hcl
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ table "notifications" {
type = sql("text[]")
comment = "a list of events this notification is for."
}
column "error" {
null = true
type = text
}
column "title" {
null = true
type = text
Expand Down
42 changes: 0 additions & 42 deletions views/007_events.sql
Original file line number Diff line number Diff line change
Expand Up @@ -218,48 +218,6 @@ WHERE
GROUP BY
name;

-- Insert team updates in event_queue
CREATE
OR REPLACE FUNCTION insert_team_in_event_queue () RETURNS TRIGGER AS $$
Copy link
Member Author

@adityathebe adityathebe Sep 26, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed this event because the event consumer in IC were simply clearing the teams & responder cache. https://github.com/flanksource/incident-commander/blob/1265484533b60bfb1196c017e9769dfc9151a617/events/teams.go#L34-L70

Instead now we have PG Notify on the teams table which is better suited for our needs.

BEGIN
IF TG_OP = 'DELETE' THEN
INSERT INTO event_queue(name, properties) VALUES ('team.delete', jsonb_build_object('team_id', OLD.id))
ON CONFLICT (name, properties) DO UPDATE SET created_at = NOW(), last_attempt = NULL, attempts = 0;
ELSE
INSERT INTO event_queue(name, properties) VALUES ('team.update', jsonb_build_object('team_id', NEW.id))
ON CONFLICT (name, properties) DO UPDATE SET created_at = NOW(), last_attempt = NULL, attempts = 0;
END IF;

RETURN NULL;
END
$$ LANGUAGE plpgsql;

CREATE
OR REPLACE TRIGGER team_enqueue
AFTER INSERT OR UPDATE OR DELETE ON teams FOR EACH ROW
EXECUTE PROCEDURE insert_team_in_event_queue ();

-- Create new event on any updates on the notifications table
CREATE OR REPLACE FUNCTION notifications_trigger_function()
RETURNS TRIGGER AS $$
BEGIN
IF TG_OP = 'DELETE' THEN
INSERT INTO event_queue(name, properties) VALUES ('notification.delete', jsonb_build_object('id', OLD.id))
ON CONFLICT (name, properties) DO UPDATE SET created_at = NOW(), last_attempt = NULL, attempts = 0;
ELSE
INSERT INTO event_queue(name, properties) VALUES ('notification.update', jsonb_build_object('id', NEW.id))
ON CONFLICT (name, properties) DO UPDATE SET created_at = NOW(), last_attempt = NULL, attempts = 0;
END IF;

RETURN NULL;
END
$$ LANGUAGE plpgsql;

CREATE OR REPLACE TRIGGER notification_update_enqueue
AFTER INSERT OR UPDATE OR DELETE ON notifications
FOR EACH ROW
EXECUTE PROCEDURE notifications_trigger_function ();

Comment on lines -243 to -262
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed this event for the same reason. The consumer was simply clearing notification cache.
It's now moved to PG Notify listener.

-- Publish Notify on new events
CREATE OR REPLACE FUNCTION notify_new_events_function()
RETURNS TRIGGER AS $$
Expand Down
16 changes: 14 additions & 2 deletions views/020_teams_triggers.sql
Original file line number Diff line number Diff line change
@@ -1,14 +1,26 @@
-- Notify on any updates on the teams table
CREATE OR REPLACE FUNCTION handle_team_updates()
RETURNS TRIGGER AS $$
BEGIN
IF TG_OP = 'DELETE' THEN
PERFORM pg_notify('table_activity', TG_TABLE_NAME || ' ' || OLD.id);
Copy link
Member Author

@adityathebe adityathebe Sep 26, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Created a new NOTIFY channel table_activity which should be used to publish any updates on a table (Insert, update, delete) instead of having multiple notify channels like teams_updated or notifications_updated.

This way we can use the notify router and have one listener on the NOTIFY channel and then distribute to multiple consumers based on the table name.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The payload should be in the format <route> <an optional payload>. The route is used by the pg notify router and the remaining payload is sent to the consumers.

RETURN NULL;
END IF;

IF OLD.deleted_at IS NULL AND NEW.deleted_at IS NOT NULL THEN
DELETE FROM team_components WHERE team_id = OLD.id;
END IF;

IF OLD.spec != NEW.spec THEN
UPDATE notifications SET error = NULL WHERE team_id = NEW.id;
END IF;

PERFORM pg_notify('table_activity', TG_TABLE_NAME || ' ' || NEW.id);

RETURN NEW;
RETURN NULL;
END
$$ LANGUAGE plpgsql;

CREATE OR REPLACE TRIGGER team_updates
AFTER UPDATE ON teams
AFTER UPDATE OR DELETE ON teams
FOR EACH ROW EXECUTE PROCEDURE handle_team_updates();
35 changes: 35 additions & 0 deletions views/021_notification.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
-- Notify on any updates/deletes on the notifications table
CREATE OR REPLACE FUNCTION handle_notifications_updates_deletes()
RETURNS TRIGGER AS $$
BEGIN
IF TG_OP = 'DELETE' THEN
PERFORM pg_notify('table_activity', TG_TABLE_NAME || ' ' || OLD.id);
ELSE
PERFORM pg_notify('table_activity', TG_TABLE_NAME || ' ' || NEW.id);
END IF;

RETURN NULL;
END
$$ LANGUAGE plpgsql;

CREATE OR REPLACE TRIGGER handle_notifications_updates_deletes_trigger
AFTER UPDATE OR DELETE ON notifications
FOR EACH ROW
EXECUTE PROCEDURE handle_notifications_updates_deletes();

-- Handle before updates for notifications
CREATE OR REPLACE FUNCTION reset_notification_error_before_update()
RETURNS TRIGGER AS $$
BEGIN
IF OLD.filter != NEW.filter OR OLD.custom_services != NEW.custom_services OR OLD.team_id != NEW.team_id THEN
NEW.error = NULL;
END IF;

RETURN NEW;
END
$$ LANGUAGE plpgsql;

CREATE OR REPLACE TRIGGER reset_notification_error_before_update_trigger
BEFORE UPDATE ON notifications
FOR EACH ROW
EXECUTE PROCEDURE reset_notification_error_before_update();
Loading