이 코드에 대해 살펴보기 시작했는데, 큰 문제가 “기대(expectations)” 주변에 있다는 느낌을 받습니다.
- 이것이 푸시 알림에 관한 것인가요? (그렇다면 PWA를 사용 중인지, 아니면 Discourse Hub 앱을 사용 중인지요)
- 사람들이 "알림을 받지 못한다"고 할 때, "푸시 알림으로 멘션에 대한 알림을 받지 못한다"는 의미인가요?
- 이미 온라인 상태일 때 @멘션에 대해 푸시 알림을 받는 것이 기대되는 동작인가요?
개선할 수 있다고 생각하는, 잘 알려진 문제들의 큰 범주가 있습니다.
- PWA에서 24시간 내에 3회 푸시 시도 후 실패할 경우(메시지 분배기 연결 문제 등), 구독을 종료하고 사용자에게 아무 알림도 보내지 않습니다.
- Hub에서는 푸시 알림이 Discourse 호스팅 고객에게만 제공됩니다.
- 채팅 메시지 수정 시 트랜잭션 내에서 푸시 알림을 발생시키기 때문에 알림이 사라지는 시퀀싱 문제가 있습니다.
- 1분 "디바운스(Debounce)"가 있습니다. 설정은 가능하지만 혼란스럽습니다. 방금 멘션을 받았는데 PN을 받지 못했습니다.
push notification time window. 이로 인해: @멘션을 받았는데, 60초 이내에 앱을 방문하면 @멘션 알림이 없습니다. - 사용자가 팔로우하지 않는 채널에서 @멘션을 하면, 해당 사용자는 멘션을 받지 못합니다. (설계상如此)
솔직히 @lindsey / @j.jaffeux / @pmusaraj, “강력하게(goes loud)” 대응하면(즉, 기본적으로 알림을 보내는 쪽으로) 사람들이 겪는 문제들과 지난 몇 년간 채팅 알림에 대해 제기된 불만의 대부분이 사라질 것 같습니다.
- @멘션 알림을 즉시 푸시 (사이트 기본값). 지연을 원하는 사이트는 설정할 수 있습니다.
- 모든 채널의 @멘션 알림을 항상 푸시하되, 사용자가 명시적으로 음소거한 채널(또는 보지 못하도록 권한이 없는 채널)만 제외합니다. 이는 포럼의 동작과 일치합니다.
update_message.rb에 트랜잭션 내에서 메시지를 게시하는 이상한 부분이 있습니다. (멀티스레드 환경에서 이는 메시지가 사라질 수 있습니다)- PWA에서 구독을 종료하게 된 경우, PWA에 "푸시 알림이 설정되어 있지 않습니다. 설정하시겠습니까?"라는 작은 배너를 표시하는 것이 좋습니다. 1일 대신 1주/2주 후에 종료하는 것도 고려해볼 만합니다.
- 푸시 태그는 채널별로 중복 제거됩니다(hostname-chat-mention-general …). 이는 멘션에 이상적입니다. 채널별로 압축되므로, 채널에서 서로 다른 시간에 4명의 다른 사람이 멘션한 경우 혼란스러울 수 있습니다.
- 사용자가 온라인 상태여도 항상 푸시 알림을 보냅니다(기본값) - 사용자가 원할 경우 이 동작을 오버라이드할 수 있도록 허용합니다.
- 이 모든 것의 아이싱은 Discourse ID가 설정된 사용자에게 모든 사이트에서 1급(First class) 푸시 알림을 지원하는 것입니다 (Discourse ID를 통해) - 이렇게 하면 Hub가 모든 것에서 일관된 느낌을 줄 수 있습니다.
기본적으로 "아니, 당신에게 알림을 보내서는 안 됐는데"라는 로직을 많이 제거하는 것입니다.
Discourse 업그레이드 시 완전히 꺼지는 것, 셀프 호스터의 경우 푸시 게이트웨이 연결 문제로 인해 분명히 발생할 수 있습니다. 일부 서버에서는 업그레이드가 며칠 걸릴 수 있고, 어떤 이유로 24시간 동안 인트라넷에 있을 수도 있습니다.
관련 코드 (Gemini 3 pro를 통해)
PWA 구독 종료
24시간 내에 3회 실패 후 구독을 종료하는 로직은 handle_generic_error 메서드에 위치합니다.
푸시 알림 디바운스 / 온라인 체크
사용자가 온라인 상태인지(“디바운스”) 확인하고 푸시 알림을 건너뛰는 로직은 여기 중앙에 위치합니다. 이는 SiteSetting.push_notification_time_window_mins에 의존합니다.
채팅: 트랜잭션 시퀀싱 문제
UpdateMessage 서비스는 publish 단계를 데이터베이스 트랜잭션으로 감쌉니다. 이는 트랜잭션이 커밋되기 전에 알림 작업이 메시지를 읽으려 할 때 레이스 컨디션(race condition)을 일으킬 수 있습니다.
- plugins/chat/app/services/chat/update_message.rb (트랜잭션 블록)
- plugins/chat/app/services/chat/update_message.rb (게시 단계)
채팅: 팔로우하지 않는 채널에서의 멘션
이 코드는 공개 채널의 멘션을 처리할 때 following: true를 명시적으로 필터링하여, 채널을 팔로우하지 않는 사용자의 알림을 방지합니다.
채팅: 푸시 알림 태그
알림을 채널별로 중복 제거(압축)하는 태그 생성 로직은 여기에 정의되어 있습니다: