Skip to content

Add notifications to graphql subscriptions #1576

@golanglemonade

Description

@golanglemonade

Now that we have notifications being added to the notification table, we want to update the graphql notifications to pull in this data.

This will mean updating the existing graph subscription manager:

// Subscribe adds a new subscriber for a user's task creations
func (sm *Manager) Subscribe(userID string, ch chan *generated.Task) {
sm.mu.Lock()
defer sm.mu.Unlock()
sm.subscribers[userID] = append(sm.subscribers[userID], ch)
}
// Unsubscribe removes a subscriber
func (sm *Manager) Unsubscribe(userID string, ch chan *generated.Task) {
sm.mu.Lock()
defer sm.mu.Unlock()
channels, ok := sm.subscribers[userID]
if !ok {
return
}
// Remove the channel from the list using slices.Delete
for i, c := range channels {
if c == ch {
sm.subscribers[userID] = slices.Delete(channels, i, i+1)
close(ch)
break
}
}
// Clean up empty lists
if len(sm.subscribers[userID]) == 0 {
delete(sm.subscribers, userID)
}
}
// Publish sends a task to all subscribers for that user
func (sm *Manager) Publish(userID string, task *generated.Task) error {
sm.mu.RLock()
defer sm.mu.RUnlock()
channels, ok := sm.subscribers[userID]
if !ok {
// No subscribers for this user, which is fine
return nil
}
// Send to all subscribers
for _, ch := range channels {
select {
case ch <- task:
// Successfully sent
log.Debug().Str("user_id", userID).Msg("task successfully sent to subscriber")
default:
// Channel is full or closed, skip
log.Warn().Str("user_id", userID).Msg("channel closed, unable to send task to subscriber for user")
}
}
return nil
}

We should be able to just update the existing subscription on generated.Task to the new generated.Notifciations since that also includes tasks notifications.

  1. Update the subscription resolver to be notifications instead of tasks:
    type Subscription {
    """
    Subscribe to task creation events for the authenticated user
    """
    taskCreated: Task!
    }
  2. Run task generate:gql after updating the schema, this should give you a note that the existing taskCreated resolver will be removed and it will add a new resolver for notifications that will need to be updated:
  3. On subscribe, it should first pull all notifications that:
read_at is NULL AND
channel contains IN_APP AND
(user_id == <current_user> OR  (user_id is NULL and owner_id in (<current_authorized_org(s)>)
  • The filter on user/org (third part of filter) should be an interceptor TraverseFunc that adds that to all queries to the notifications table
  • This can use the auth.GetAuthenticatedUserFromContext(ctx) to get the SubjectID and OrganizationIDs to filter the query
  1. Add any new notifications added to the table should be sent to the webhook
  2. Remove the code to add a notification to the subscription for task assigned - the new event based notifications will handle this now.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions