๊ฐ์
์ฑํ ๋ฐฉ ๋ฉ์ธ์ง ์ฝ์ ์ฒ๋ฆฌ ๊ธฐ๋ฅ์ ์ฌ์ฉ์๊ฐ ๋ง์ง๋ง์ผ๋ก ์ฝ์ ๋ฉ์ธ์ง๋ฅผ ์ถ์ ํ์ฌ, ์ฝ์ง ์์ ๋ฉ์ธ์ง์ ๊ฐ์๋ฅผ ํ์ธํ๊ณ ๊ฐ ๋ฉ์ธ์ง์ ๋ํด '์ฝ์ง ์์ ๊ฐ์ (Unread Count)'๋ฅผ ํ์ํฉ๋๋ค.
๊ธฐ์กด์ ๋ฉ์ธ์ง ์ฝ์ ์ฒ๋ฆฌ ๊ตฌ์กฐ๋ ๊ฐ ๋ฉ์ธ์ง๋ง๋ค ํด๋น ๋ฉ์ธ์ง๋ฅผ ์ฝ์ ์ ์ ์ ID ๋ฆฌ์คํธ๋ฅผ ๊ธฐ๋กํ๊ณ , ์ฝ์ ์ ์ ID ๋ฐฐ์ด์ ๊ธธ์ด๋ฅผ ํตํด '์ฝ์ง ์์ ๊ฐ์ (Unread Count)'๋ฅผ ๊ณ์ฐํ์ต๋๋ค. ํ์ง๋ง ์ฌ์ฉ์๊ฐ ๋ง์ ์ฑํ ๋ฐฉ์ ์ฌ์ฉ์๊ฐ ์ ์ ์ฑํ ๋ฐฉ์ ๋นํด ๋ ๋ง์ ๋ฉ์ธ์ง๊ฐ ์ค๊ฐ๋ฏ๋ก, ์์ ํด์ผํ ๋ฐ์ดํฐ์ ๊ฐ์๊ฐ ๊ธฐํ๊ธ์์ ์ผ๋ก ๋์ด๋๊ฒ ๋ฉ๋๋ค. ์ด๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ๋ฉ์ธ์ง ์ฝ์ ์ฒ๋ฆฌ ๋ก์ง์ ๊ฐ์ ํด๋ณด๊ฒ ์ต๋๋ค.
๊ธฐ์กด์ ๋ฉ์ธ์ง ์ฝ์ ์ฒ๋ฆฌ ๋ก์ง
๋จผ์ , ๊ธฐ์กด์ ์ฑํ ์์คํ ์ ๋ฉ์ธ์ง ์ฝ์ ์ฒ๋ฆฌ ๋ก์ง์ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
์์ ์ค๋ช ํ ๊ฒ์ฒ๋ผ, ๊ธฐ์กด ์์คํ ์ ๊ฐ ๋ฉ์ธ์ง๋ง๋ค ์ฝ์ ์ฌ์ฉ์๋ค์ ์ ๋ณด๋ฅผ ๊ฐ๋ณ์ ์ผ๋ก ์ ์ฅํ๊ณ , ์ด๋ฅผ ๋ฐํ์ผ๋ก ๋ฉ์ธ์ง์ '์ฝ์ ๋ฉ์ธ์ง์ ๊ฐ์ (Unread Count)'๋ฅผ ๊ณ์ฐํ์ต๋๋ค.
'์ค์ฌ์นด ๋จน๋ฐฉ ํฌ์ด๋ฐฉ' ์ด๋ผ๋ ์ฑํ ๋ฐฉ์ 10๋ช ์ ์ฌ์ฉ์๊ฐ ์๋ค๊ณ ๊ฐ์ ํด๋ณด๊ฒ ์ต๋๋ค.
์ด๋ ๋๊ตฐ๊ฐ๊ฐ '์๋ ํ์ธ์'๋ผ๋ ๋ฉ์ธ์ง๋ฅผ ๋ณด๋ ๋๋ค. ๊ทธ๋ฌ๋ฉด '์๋ ํ์ธ์' ๋ฉ์ธ์ง๋ฅผ ์ฝ์ ์ฌ์ฉ์์ ์ฝ์ง ์์ ์ฌ์ฉ์๊ฐ ๋๋๊ฒ ๋ฉ๋๋ค. ๋ฉ์ธ์ง๋ฅผ ์ฝ์ ์ฌ์ฉ์ ์ ๋ณด๋ ๊ฐ๋ณ์ ์ผ๋ก ์ ์ฅ๋๋ฉฐ, ์ด๋ฅผ ๋ฐํ์ผ๋ก '์ฝ์ง ์์ ๊ฐ์ (Unread Count)'๊ฐ ๊ณ์ฐ๋ฉ๋๋ค.
์ด ๊ตฌ์กฐ๋ ์ ์ด๋ฏธ์ง์ฒ๋ผ ๊ฐ ๋ฉ์ธ์ง๋ง๋ค ์ฝ์ ์ ์ ์ ๋ณด๋ฅผ ์ ์ฅํ๊ธฐ ๋๋ฌธ์, ๋ฉ์ธ์ง๊ฐ ์์ผ์๋ก ๋ฐ์ดํฐ ์์ด ์ฆ๊ฐํ๊ฒ ๋ฉ๋๋ค. ์ด๋ก์ธํด ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋์ด ๋์ด๋๊ณ , ๋ฉ์ธ์ง ์ฒ๋ฆฌ ์๋๊ฐ ๋๋ ค์ง ์ ์์ต๋๋ค.
๋ ํ๋์ ๋ฌธ์ ๋ ๊ณผ๋ํ ์์ ์ด ๋ฐ์ํ๋ค๋ ์ ์ ๋๋ค. ์ฌ์ฉ์๊ฐ ์ฑํ ๋ฐฉ์ ๋ณด์ง ์๋ ๋์์ ์๋ก์ด ๋ฉ์ธ์ง๊ฐ 100๊ฐ๊ฐ ์๋ค๊ณ ๊ฐ์ ํด๋ณด๊ฒ ์ต๋๋ค.
๋ฉ์ธ์ง ํ๋ํ๋์ ์ ๋ณด๋ฅผ ๊ธฐ๋กํ๋ ๊ธฐ์กด์ ๋ฐฉ์์ ๋ฐ๋ฅด๋ฉด, 100๊ฐ์ ๋ฉ์ธ์ง ์ฝ์ ์ฒ๋ฆฌ๋ฅผ ์ํด์๋ 100๊ฐ์ ์ฑํ ๋ฐ์ดํฐ๋ฅผ ์์ ํด์ผ ํ๋ ์ํฉ์ด ๋ฐ์ํฉ๋๋ค. ์ฌ์ฉ์๊ฐ 1๋ช ์ผ ๊ฒฝ์ฐ์๋ ๊ณผ๋ํ ์์ ์ด ์ผ์ด๋๋ฉฐ, ์ฌ๋ฌ ์ฌ์ฉ์๊ฐ ๋์์ ๋ฉ์ธ์ง๋ฅผ ์ฝ์ ๋๋ ๋ ๋ง์ ์์ ์ด ์ด๋ฃจ์ด์ง๋๋ค. ์๋ฅผ ๋ค์ด, 10๋ช ์ ์ฌ์ฉ์๊ฐ 100๊ฐ์ ๋ฉ์ธ์ง๋ฅผ ์ฝ์ ์ฒ๋ฆฌํ๋ฉด, DB๋ 100๊ฐ์ ์ฑํ ๋ฐ์ดํฐ์ 10๋ฒ ์์ ํด์ผํฉ๋๋ค. ์ด ๊ณผ์ ์ ์ถํ DB์ ํฐ ๋ถ๋ด์ ์ฃผ๋ ๋ฌด๊ฑฐ์ด ์์ ์ด ๋ ์ ์์ต๋๋ค.
๊ฐ์ ๋ ๋ฉ์ธ์ง ์ฝ์ ์ฒ๋ฆฌ ๋ก์ง
๊ฐ์ ๋ ๋ฉ์ธ์ง ์ฝ์ ์ฒ๋ฆฌ ๋ก์ง์์๋ ๊ฐ ์ฑํ ๋ฐฉ๋ง๋ค ๋ณ๋์ '๋ง์ง๋ง ์ฝ์ ๋ฉ์ธ์ง (LastReadMessage)'๋ฅผ ์ ์ฅํ๋๋ก ํ์์ต๋๋ค.
์ด์ ๊ฐ๋ณ ๋ฉ์ธ์ง์ ์ ๋ณด๋ฅผ ๊ธฐ๋กํ๋ ๋์ , ๊ฐ ์ฑํ ๋ฐฉ์ ์ฌ์ฉ์๋ณ ๋ง์ง๋ง ์ฝ์ ๋ฉ์ธ์ง ID๋ฅผ ์ ์ฅํฉ๋๋ค.
๊ฐ์ ๋ ๋ฉ์ธ์ง ์ฝ์ ์ฒ๋ฆฌ๊ณผ์ ์ ์๋์ ๊ฐ์ต๋๋ค.
- ํด๋น ์ฑํ ๋ฐฉ์ LastMessage ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ด
- ๊ฐ์ ธ์จ ๋ฐ์ดํฐ๋ฅผ ํตํด ๊ฐ ๋ฉ์ธ์ง์ Unread Count๋ฅผ ๊ณ์ฐ
- ์ฌ์ฉ์๊ฐ ์ฑํ ๋ฐฉ์์ ์ดํํ ๊ฒฝ์ฐ ํ์ฌ ์ฑํ ๋ฐฉ์์ ๊ฐ์ฅ ๋ง์ง๋ง์ ๋์ฐฉํ ๋ฉ์ธ์ง ID๋ก ํด๋น ์ฌ์ฉ์์ Last Read Message ID ์ ๋ฐ์ดํธ
- ์ดํ ์ฌ์ฉ์๊ฐ ์ฑํ ๋ฐฉ์ ์ฌ์ ์ํ๋ ๊ฒฝ์ฐ, Last Read Mesage ID ์ ๋ฐ์ดํธ
์ฌ์ฉ์๊ฐ ์ฑํ ๋ฐฉ์ ๋ค์ด์์ ๋ฉ์ธ์ง๋ฅผ ํ์ธํ๋ ๋์, ๊ทธ ์ฌ์ฉ์์ '๋ง์ง๋ง ์ฝ์ ๋ฉ์ธ์ง (Last Read Message)'๋ '-1'๋ก ์ ๋ฐ์ดํธ๋ฉ๋๋ค. ์ด๋ก ์ธํด ์ฌ์ฉ์๊ฐ ์ฑํ ๋ฐฉ์ ์๋ ๋์์๋ ๊ทธ ์ฌ๋์ด ๋ชจ๋ ๋ฉ์ธ์ง๋ฅผ ์ฝ์๋ค๊ณ ๊ฐ์ฃผํ์ฌ, ๋ฉ์ธ์ง๋ฅผ ๋ชจ๋ ์ฝ์ ์ํ๋ก ์ฒ๋ฆฌํฉ๋๋ค. ์ด๋ ๊ฒ ์ฒ๋ฆฌ๋๋ฉด, ์๋ก์ด ๋ฉ์ธ์ง๊ฐ ๋์ฐฉํด๋ ๊ทธ ๋ฉ์ธ์ง๋ ์ด๋ฏธ ์ฝ์ ๊ฒ์ผ๋ก ์๋ ์ฒ๋ฆฌ๋ฉ๋๋ค.
์ด ์ํ์์๋ ์ฌ์ฉ์๊ฐ ๋ ์ด์ ์๋ก์ด ๋ฉ์ธ์ง๋ฅผ ์ฝ์๋ค๋ ์ ๋ฐ์ดํธ๋ฅผ ํ์ง ์์๋, ์์คํ ์ ๊ทธ ์ฌ๋์ ๋ชจ๋ ๋ฉ์ธ์ง๋ฅผ ์ฝ์๋ค๊ณ ํ๋จํ๊ฒ ๋์ด ๋ถํ์ํ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ ๋ฐ์ดํธ๋ฅผ ๋ง์ ์ ์์ต๋๋ค.
๋ฉ์ธ์ง ์ฝ์ ์ฒ๋ฆฌ ๋ก์ง ์์
์ ๊ทธ๋ฆผ์ ์ ์ ๋ณ ๋ง์ง๋ง์ผ๋ก ์ฝ์ ๋ฉ์ธ์ง ID๋ฅผ ๊ด๋ฆฌํ๋ ํ ์ด๋ธ์ด๋ฉฐ, ํด๋น ํ ์ด๋ธ์์๋ ๊ฐ๋ก๋ ์ฌ์ฉ์, ์ธ๋ก๋ ๊ฐ ์ฑํ ์ ์๋ฏธํฉ๋๋ค.
ํด๋น ์ฑํ ๋ฐฉ์ ์ฌ์ฉ์๋ ์ด 6๋ช , ๋ฉ์ธ์ง๋ ์ด 9๊ฐ์ด๋ฉฐ ์ด ์ค ๋ณด๋ผ์์ผ๋ก ์น ํด์ง ์ฌ์ฉ์๋ ํ์ฌ ์ฑํ ๋ฐฉ์ ์ค์๊ฐ์ผ๋ก ํ์ธํ๊ณ ์๋ ์ฌ์ฉ์๋ฅผ ์๋ฏธํฉ๋๋ค. ๊ฐ ์ฌ์ฉ์๊ฐ ๋ง์ง๋ง์ผ๋ก ์ฝ์ ๋ฉ์ธ์ง๋ 'O'๋ก ๋ํ๋ด๊ณ ์ค์๊ฐ์ผ๋ก ํ์ธํ๊ณ ์๋ ์ฌ์ฉ์๋ '-1'๋ก ๋ํ๋์ต๋๋ค.
์ด๋ฅผ ๋ฐํ์ผ๋ก Unread Count๋ฅผ ๊ณ์ฐํด๋ณด๊ฒ ์ต๋๋ค.
์ฑํ ID | ์ฝ์ ์ฌ์ฉ์ ID | Unread Count |
1 | [1, 2, 3, 4, 5, 6] | 0 |
2 | [1, 2, 3, 4, 5] | 1 |
3 | [1, 2, 3, 4, 5] | 1 |
4 | [1, 2, 3, 4] | 2 |
5 | [1, 2, 3] | 3 |
6 | [1, 2, 3] | 3 |
7 | [1, 2] | 4 |
8 | [1, 2] | 4 |
9 | [1, 2] | 4 |
์ด๋ฐ์์ผ๋ก ๊ฐ ๋ฉ์ธ์ง์ Unread Count๋ฅผ ๊ตฌํ ์ ์์ต๋๋ค.
์ ์ํ ์ ์ Last Read Message๋ฅผ ํ์ฉํ๊ธฐ ์ํด์๋ ๊ณ์ฐ์ ์ ํ์ฑ์ ์ํด ์ ์ ํ ์ํฉ์ ์ ๋ ์ ๋ฐ์ดํธ๊ฐ ๋์ด์ผ ํ๋ค๋ ๊ฒ์ ๋๋ค.
๋ง์ง๋ง ์ฝ์ ๋ฉ์ธ์ง ์ ๋ฐ์ดํธ
๋ง์ง๋ง ์ฝ์ ๋ฉ์ธ์ง๋ฅผ ์ ๋ฐ์ดํธํด์ผ ํ๋ ์ํฉ์ 2๊ฐ์ง์ ๊ฒฝ์ฐ๊ฐ ์์ต๋๋ค.
- ์ฌ์ฉ์๊ฐ ํน์ ์ฑํ ๋ฐฉ์ ์ ์ํ ๊ฒฝ์ฐ
- ์ฑํ ๋ฐฉ์ ์ ์ํด์๋ ์ฌ์ฉ์๊ฐ ์ ์์ ํด์ ํ ๊ฒฝ์ฐ
์ฒซ ๋ฒ์งธ ๊ฒฝ์ฐ๋ ํด๋น ์ฌ์ฉ์์ ๋ง์ง๋ง ์ฝ์ ์ฑํ ID๋ฅผ '-1'๋ก ์์ ํ๊ณ ์์ ๋ ๊ฒ์ ํด๋น ์ฑํ ๋ฐฉ์ ์ฐธ์ฌํ๊ณ ์๋ ์ฌ์ฉ์๋ค์๊ฒ ์ด๋ฒคํธ๋ฅผ ์ ๋ฌํ๋ ๊ฒ์ผ๋ก ํด๊ฒฐํ ์ ์์ต๋๋ค.
๋ ๋ฒ์งธ ๊ฒฝ์ฐ๋ ํด๋น ์ฌ์ฉ์๊ฐ ์ฐ๊ฒฐ์ ํด์ ํ ์๊ฐ์ ๊ธฐ์ค์ผ๋ก ๋ง์ง๋ง ์ฑํ ID๋ฅผ ์์ ํ๊ณ ํด๋น ์ฑํ ID์ ์ฌ์ฉ์ ID๋ฅผ ํด๋น ์ฑํ ๋ฐฉ์ ์ฐธ์ฌํ๊ณ ์๋ ์ฌ์ฉ์๋ค์๊ฒ ์ด๋ฒคํธ๋ฅผ ์ ๋ฌํ๋ ๊ฒ์ผ๋ก ํด๊ฒฐํ ์ ์์ต๋๋ค.
์ด๋ ๊ฒ ๊ตฌ์ฑํ๋ฉด ๊ฐ ํด๋ผ์ด์ธํธ๋ ์ฒ์์ผ๋ก ํด๋น ์ฑํ ๋ฐฉ์ ๋ง์ง๋ง ์ฝ์ ๋ฉ์ธ์ง ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์จ ํ, ์ดํ๋ถํฐ๋ ์ฌ์ฉ์๊ฐ ์ ์/ํด์ ๋ ๋๋ง๋ค ๋ฐ์ํ๋ ์ด๋ฒคํธ ๋ฉ์ธ์ง๋ฅผ ํตํด ์ค์๊ฐ์ผ๋ก ์ ๋ฐ์ดํธ ํฉ๋๋ค. ์ฆ, ํ๋ฒ์ ์กฐํํ์๋ DB์์ ์ ๋ฐ์ดํธ๋ ๋ฐ์ดํฐ๋ง ๊ฐ ํด๋ผ์ด์ธํธ์ ๋ฐ์ํด ์ต์ ์ํ๋ฅผ ์ ์งํ๋ ๊ฒ์ ๋๋ค.
์ฑํ ์์คํ ๋ฉ์ธ์ง ์ฝ์ ๊ธฐ๋ฅ ๊ฐ์ ํจ๊ณผ
๊ฐ์ ์ ๊ณผ ๊ฐ์ ํ์ ์ฐจ์ด๋ฅผ ์์๋ณด๊ธฐ ์ํด ํ ์คํธ๋ฅผ ์งํํ์์ต๋๋ค.
๊ฐ์ ์
@Test
@DisplayName("์ฌ์ฉ์ B๊ฐ 10000๊ฐ์ ์ฑํ
์ ์ฝ์ง ์์ ์ํ์์ ์ ์ํ๋ ๊ฒฝ์ฐ - ๊ฐ์ ์ ")
public void addOnlineUserWhenUserBConnectsWithUnreadMessagesBefore() {
// given
Long userAId = 1L;
Long userBId = 2L;
Long chatRoomId = 100L;
onlineChatRoomRepository.save(chatRoomId, userAId);
// when
chatUserStatusService.addOnlineUser(userBId, chatRoomId);
// then
Optional<Chat> findLastChat = chatRepository.findLastChatByChatRoomId(chatRoomId, LocalDateTime.now());
assertThat(findLastChat).isPresent().get()
.extracting(Chat::getReadUserIds)
.isEqualTo(Set.of(userAId, userBId));
}
๊ฐ์ ํ
@Test
@DisplayName("์ฌ์ฉ๊ฐ B๊ฐ 10000๊ฐ์ ์ฑํ
์ ์ฝ์ง ์์ ์ํ์์ ์ ์ํ๋ ๊ฒฝ์ฐ - ๊ฐ์ ")
public void addOnlineUserWhenUserBConnectsWithUnreadMessages() {
// given
Long userAId = 1L;
Long userBId = 2L;
Long chatRoomId = 100L;
Chat lastChat = chatRepository.findChatByChatRoomId(chatRoomId, LocalDateTime.now())
.orElseThrow(() -> new IllegalArgumentException("ํด๋น ์ฑํ
์ด ์กด์ฌํ์ง ์์ต๋๋ค."));
LastReadMessage lastReadMessageByA = LastReadMessage.of(userAId, lastChat.getId());
LastReadMessage lastReadMessageByB = LastReadMessage.of(userBId, null);
ChatRoomStatus chatRoomStatus = chatRoomStatusRepository.save(
ChatRoomStatus.create(
LastReads.of(Last.of(lastReadMessageByA, lastReadMessageByB))
)
);
// when
chatUserStatusService.addOnlineUser(userBId, chatRoomStatus.getChatRoomId());
// then
Optional<OnlineUser> findOnlineUserB = onlineUserRepository.findById(userBId);
Optional<ChatRoomStatus> findChatRoomStatus = chatRoomStatusRepository.findById(chatRoomId);
assertThat(findOnlineUserB).isNotEmpty();
assertThat(findChatRoomStatus).isNotEmpty();
assertThat(findChatRoomStatus.get().getLastReadMessages())
.extracting("userId", "chatId")
.containsExactly(
tuple(userAId, lastChat.getId()),
tuple(userBId, "-1")
);
}
์ด๋ฒ ์์คํ ๊ฐ์ ์ ํตํด, ๋ฉ์ธ์ง ์ฝ์ ์ฒ๋ฆฌ์ ์ฑ๋ฅ์ด 36.8% ํฅ์ ๋์๊ณ , ๋์์ DB ๋ถํ๋ฅผ ํฌ๊ฒ ์ค์ด๋ ์ฑ๊ณผ๋ฅผ ์ป์์ต๋๋ค. ์ด๋ฅผ ํตํด ์ฑํ ์์คํ ์ ์ฒ๋ฆฌ ์๋์ ํจ์จ์ฑ์ ๊ฐ์ ํ ์ ์์์ต๋๋ค.
๊ฒฐ๋ก
๊ฐ์ ์ ์๋ ์ฌ์ฉ์๊ฐ 100๊ฐ์ ์ฑํ ์ ์ฝ์ ์ฒ๋ฆฌํ๊ธฐ ์ํด, ์์คํ ์ 100๊ฐ์ ์ฑํ ๋ฐ์ดํฐ๋ฅผ ๊ฐ๊ฐ ์ ๋ฐ์ดํธํด์ผ ํ์ต๋๋ค. ์ด๋ DB์ ํฐ ๋ถํ๋ฅผ ์ฃผ๊ณ , ์ฒ๋ฆฌ ์๋์ ์ํฅ์ ๋ฏธ์น ์ ์์ต๋๋ค. ํ์ง๋ง ์ด๋ฒ ๊ฐ์ ์ ํตํด, ๋จ 1๊ฐ์ ํ๋ง ์ ๋ฐ์ดํธํ๋ฉด ์ ์ฒด ๋ฉ์ธ์ง ์ฝ์ ์ฒ๋ฆฌ๊ฐ ๊ฐ๋ฅํด์ก์ต๋๋ค.
'Project' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
Embedded Mongo/Redis ์ ์ฉํ๊ธฐ (0) | 2024.11.26 |
---|---|
๋ณ์ ์ค๋ณต ์์ฑ ๋์์ฑ ์ด์ ํด๊ฒฐ (0) | 2024.10.27 |
CompletableFuture๋ฅผ ํ์ฉํ ์ฑ๋ฅ ๊ฐ์ ๊ธฐ (0) | 2024.08.01 |