Created
October 31, 2020 08:14
-
-
Save zzerjae/35645da527f2651621d296edac66cde9 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package worker | |
type NewArticleEvent struct { | |
RegionId int64 | |
PublishRange int | |
WriterId int64 | |
ArticleId int64 | |
Title string | |
} | |
type Matched struct { | |
UserId int64 | |
Keyword string | |
} | |
type Worker struct { | |
RegionSvc RegionService | |
NotificationSvc NotificationService | |
UserSvc UserService | |
DB DB | |
} | |
type RegionService interface { | |
GetRegionIdsByRange(regionId int64, publishRange int) ([]int64, error) | |
} | |
type NotificationService interface { | |
Send(userId int64, keyword string, articleId int64, Title string) | |
} | |
type UserService interface { | |
BatchGetBlockingUsers(userIds []int64, userId int64) (map[int64]bool, error) | |
} | |
type DB interface { | |
FindMatchedUsers(title string, regionIdsByRange [][]int64) ([][]Matched, error) | |
} | |
// 내가 작성해야할 서비스 | |
func (w *Worker) Work(e NewArticleEvent) { | |
// 게시글의 인접지역을 조회하여, 노출 범위별로 지역을 나눈다. | |
targetRegions, err := w.listRegionIdsByPublishRange(e.RegionId, e.PublishRange) | |
if err != nil { | |
return | |
} | |
// Title에 매칭되는 키워드를 구독하고 있는 유저를 각 지역별로 찾는다. | |
MatchedByRange, err := w.DB.FindMatchedUsers(e.Title, targetRegions) | |
if err != nil { | |
return | |
} | |
// 대상 유저들이 작성자를 차단하는지 찾는다. | |
isUserBockWriterMap, err := w.batchGetBlockingUsers(MatchedByRange, e.WriterId) | |
if err != nil { | |
return | |
} | |
// 알림을 전송한다. | |
for _, matched := range MatchedByRange { | |
for _, m := range matched { | |
if isUserBockWriterMap[m.UserId] { | |
continue | |
} | |
w.NotificationSvc.Send(m.UserId, m.Keyword, e.ArticleId, e.Title) | |
} | |
} | |
} | |
// 지역의 인접범위를 조회하여, 노출 범위별로 나눈다. | |
func (w *Worker) listRegionIdsByPublishRange(regionId int64, publishRange int) ([][]int64, error) { | |
resultRegions := make([][]int64, publishRange+1) | |
resultRegions[0] = []int64{regionId} | |
for i := 1; i <= publishRange; i++ { | |
regionIds, err := w.RegionSvc.GetRegionIdsByRange(regionId, i) | |
if err != nil { | |
return nil, err | |
} | |
for _, id := range regionIds { | |
already := false | |
alreadyExist: | |
for j := 0; j < i; j++ { | |
for _, alreadExistId := range resultRegions[j] { | |
if id == alreadExistId { | |
already = true | |
break alreadyExist | |
} | |
} | |
} | |
if !already { | |
resultRegions[i] = append(resultRegions[i], id) | |
} | |
} | |
} | |
return resultRegions, nil | |
} | |
// 지역별로 존재하는 대상 유저들이 작성자를 차단하는지 확인한다. | |
func (w *Worker) batchGetBlockingUsers(matchedByRange [][]Matched, writerId int64) (map[int64]bool, error) { | |
var userIds []int64 | |
for _, matched := range matchedByRange { | |
for _, m := range matched { | |
userIds = append(userIds, m.UserId) | |
} | |
} | |
userBlockMap, err := w.UserSvc.BatchGetBlockingUsers(userIds, writerId) | |
if err != nil { | |
return nil, err | |
} | |
return userBlockMap, nil | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment