perf(ChatLoadingTime): Separate get chat messages and get pinned messages in different tasks
This commit is contained in:
parent
d5e5ba2796
commit
d1ffa2e3b3
|
@ -58,8 +58,8 @@ proc delete*(self: Controller) =
|
|||
self.events.disconnect()
|
||||
|
||||
proc init*(self: Controller) =
|
||||
self.events.on(SIGNAL_MESSAGES_LOADED) do(e:Args):
|
||||
let args = MessagesLoadedArgs(e)
|
||||
self.events.on(SIGNAL_PINNED_MESSAGES_LOADED) do(e:Args):
|
||||
let args = PinnedMessagesLoadedArgs(e)
|
||||
if(self.chatId != args.chatId or args.pinnedMessages.len == 0):
|
||||
return
|
||||
self.delegate.newPinnedMessagesLoaded(args.pinnedMessages)
|
||||
|
|
|
@ -58,7 +58,13 @@ proc init*(self: Controller) =
|
|||
let args = MessagesLoadedArgs(e)
|
||||
if(self.chatId != args.chatId):
|
||||
return
|
||||
self.delegate.newMessagesLoaded(args.messages, args.reactions, args.pinnedMessages)
|
||||
self.delegate.newMessagesLoaded(args.messages, args.reactions)
|
||||
|
||||
self.events.on(SIGNAL_PINNED_MESSAGES_LOADED) do(e:Args):
|
||||
let args = PinnedMessagesLoadedArgs(e)
|
||||
if(self.chatId != args.chatId):
|
||||
return
|
||||
self.delegate.newPinnedMessagesLoaded(args.pinnedMessages)
|
||||
|
||||
self.events.on(SIGNAL_NEW_MESSAGE_RECEIVED) do(e: Args):
|
||||
var args = MessagesArgs(e)
|
||||
|
|
|
@ -25,8 +25,10 @@ method updateChatIdentifier*(self: AccessInterface) {.base.} =
|
|||
method updateChatFetchMoreMessages*(self: AccessInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method newMessagesLoaded*(self: AccessInterface, messages: seq[MessageDto], reactions: seq[ReactionDto],
|
||||
pinnedMessages: seq[PinnedMessageDto]) {.base.} =
|
||||
method newMessagesLoaded*(self: AccessInterface, messages: seq[MessageDto], reactions: seq[ReactionDto]) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method newPinnedMessagesLoaded*(self: AccessInterface, pinnedMessages: seq[PinnedMessageDto]) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method onReactionAdded*(self: AccessInterface, messageId: string, emojiId: int, reactionId: string) {.base.} =
|
||||
|
|
|
@ -221,8 +221,7 @@ method reevaluateViewLoadingState*(self: Module) =
|
|||
not self.firstUnseenMessageState.initialized or
|
||||
self.firstUnseenMessageState.fetching)
|
||||
|
||||
method newMessagesLoaded*(self: Module, messages: seq[MessageDto], reactions: seq[ReactionDto],
|
||||
pinnedMessages: seq[PinnedMessageDto]) =
|
||||
method newMessagesLoaded*(self: Module, messages: seq[MessageDto], reactions: seq[ReactionDto]) =
|
||||
var viewItems: seq[Item]
|
||||
|
||||
if(messages.len > 0):
|
||||
|
@ -327,11 +326,6 @@ method newMessagesLoaded*(self: Module, messages: seq[MessageDto], reactions: se
|
|||
else:
|
||||
error "wrong emoji id found when loading messages", methodName="newMessagesLoaded"
|
||||
|
||||
for p in pinnedMessages:
|
||||
if(p.message.id == message.id):
|
||||
item.pinned = true
|
||||
item.pinnedBy = p.pinnedBy
|
||||
|
||||
if message.editedAt != 0:
|
||||
item.isEdited = true
|
||||
|
||||
|
@ -357,6 +351,10 @@ method newMessagesLoaded*(self: Module, messages: seq[MessageDto], reactions: se
|
|||
self.initialMessagesLoaded = true
|
||||
self.reevaluateViewLoadingState()
|
||||
|
||||
method newPinnedMessagesLoaded*(self: Module, pinnedMessages: seq[PinnedMessageDto]) =
|
||||
for p in pinnedMessages:
|
||||
self.onPinMessage(p.message.id, p.pinnedBy)
|
||||
|
||||
method messagesAdded*(self: Module, messages: seq[MessageDto]) =
|
||||
var items: seq[Item]
|
||||
|
||||
|
|
|
@ -12,7 +12,6 @@ type
|
|||
AsyncFetchChatMessagesTaskArg = ref object of QObjectTaskArg
|
||||
chatId: string
|
||||
msgCursor: string
|
||||
pinnedMsgCursor: string
|
||||
limit: int
|
||||
|
||||
const asyncFetchChatMessagesTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
|
||||
|
@ -32,16 +31,6 @@ const asyncFetchChatMessagesTask: Task = proc(argEncoded: string) {.gcsafe, nimc
|
|||
responseJson["messages"] = messagesArr
|
||||
responseJson["messagesCursor"] = messagesCursor
|
||||
|
||||
# handle pinned messages
|
||||
if(arg.pinnedMsgCursor != CURSOR_VALUE_IGNORE):
|
||||
var pinnedMsgArr: JsonNode
|
||||
var pinnedMsgCursor: JsonNode
|
||||
let pinnedMsgsResponse = status_go.fetchPinnedMessages(arg.chatId, arg.pinnedMsgCursor, arg.limit)
|
||||
discard pinnedMsgsResponse.result.getProp("cursor", pinnedMsgCursor)
|
||||
discard pinnedMsgsResponse.result.getProp("pinnedMessages", pinnedMsgArr)
|
||||
responseJson["pinnedMessages"] = pinnedMsgArr
|
||||
responseJson["pinnedMessagesCursor"] = pinnedMsgCursor
|
||||
|
||||
# handle reactions
|
||||
if(arg.msgCursor != CURSOR_VALUE_IGNORE):
|
||||
# messages and reactions are using the same cursor
|
||||
|
@ -52,6 +41,28 @@ const asyncFetchChatMessagesTask: Task = proc(argEncoded: string) {.gcsafe, nimc
|
|||
|
||||
arg.finish(responseJson)
|
||||
|
||||
#################################################
|
||||
# Async load pinned messages
|
||||
#################################################
|
||||
const asyncFetchPinnedChatMessagesTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
|
||||
let arg = decode[AsyncFetchChatMessagesTaskArg](argEncoded)
|
||||
|
||||
var responseJson = %*{
|
||||
"chatId": arg.chatId
|
||||
}
|
||||
#handle pinned messages
|
||||
if(arg.msgCursor != CURSOR_VALUE_IGNORE):
|
||||
var pinnedMsgArr: JsonNode
|
||||
var msgCursor: JsonNode
|
||||
let pinnedMsgsResponse = status_go.fetchPinnedMessages(arg.chatId, arg.msgCursor, arg.limit)
|
||||
discard pinnedMsgsResponse.result.getProp("cursor", msgCursor)
|
||||
discard pinnedMsgsResponse.result.getProp("pinnedMessages", pinnedMsgArr)
|
||||
responseJson["pinnedMessages"] = pinnedMsgArr
|
||||
responseJson["pinnedMessagesCursor"] = msgCursor
|
||||
|
||||
arg.finish(responseJson)
|
||||
|
||||
|
||||
#################################################
|
||||
# Async search messages
|
||||
#################################################
|
||||
|
|
|
@ -40,6 +40,7 @@ const WEEK_AS_MILLISECONDS = initDuration(seconds = 60*60*24*7).inMilliSeconds
|
|||
|
||||
# Signals which may be emitted by this service:
|
||||
const SIGNAL_MESSAGES_LOADED* = "messagesLoaded"
|
||||
const SIGNAL_PINNED_MESSAGES_LOADED* = "pinnedMessagesLoaded"
|
||||
const SIGNAL_FIRST_UNSEEN_MESSAGE_LOADED* = "firstUnseenMessageLoaded"
|
||||
const SIGNAL_NEW_MESSAGE_RECEIVED* = "newMessageReceived"
|
||||
const SIGNAL_MESSAGE_PINNED* = "messagePinned"
|
||||
|
@ -72,9 +73,12 @@ type
|
|||
MessagesLoadedArgs* = ref object of Args
|
||||
chatId*: string
|
||||
messages*: seq[MessageDto]
|
||||
pinnedMessages*: seq[PinnedMessageDto]
|
||||
reactions*: seq[ReactionDto]
|
||||
|
||||
PinnedMessagesLoadedArgs* = ref object of Args
|
||||
chatId*: string
|
||||
pinnedMessages*: seq[PinnedMessageDto]
|
||||
|
||||
MessagePinUnpinArgs* = ref object of Args
|
||||
chatId*: string
|
||||
messageId*: string
|
||||
|
@ -188,16 +192,11 @@ QtObject:
|
|||
let msgCursor = self.initOrGetMessageCursor(chatId)
|
||||
let msgCursorValue = if (msgCursor.isFetchable()): msgCursor.getValue() else: CURSOR_VALUE_IGNORE
|
||||
|
||||
let pinnedMsgCursor = self.initOrGetPinnedMessageCursor(chatId)
|
||||
let pinnedMsgCursorValue = if (pinnedMsgCursor.isFetchable()): pinnedMsgCursor.getValue() else: CURSOR_VALUE_IGNORE
|
||||
|
||||
if(msgCursorValue == CURSOR_VALUE_IGNORE and pinnedMsgCursorValue == CURSOR_VALUE_IGNORE):
|
||||
if(msgCursorValue == CURSOR_VALUE_IGNORE):
|
||||
return
|
||||
|
||||
if(msgCursorValue != CURSOR_VALUE_IGNORE):
|
||||
msgCursor.setPending()
|
||||
if (pinnedMsgCursorValue != CURSOR_VALUE_IGNORE):
|
||||
pinnedMsgCursor.setPending()
|
||||
|
||||
let arg = AsyncFetchChatMessagesTaskArg(
|
||||
tptr: cast[ByteAddress](asyncFetchChatMessagesTask),
|
||||
|
@ -205,17 +204,39 @@ QtObject:
|
|||
slot: "onAsyncLoadMoreMessagesForChat",
|
||||
chatId: chatId,
|
||||
msgCursor: msgCursorValue,
|
||||
pinnedMsgCursor: pinnedMsgCursorValue,
|
||||
limit: if(limit <= MESSAGES_PER_PAGE_MAX): limit else: MESSAGES_PER_PAGE_MAX
|
||||
)
|
||||
|
||||
self.threadpool.start(arg)
|
||||
|
||||
proc asyncLoadPinnedMessagesForChat*(self: Service, chatId: string) =
|
||||
if (chatId.len == 0):
|
||||
error "empty chat id", procName="asyncLoadPinnedMessagesForChat"
|
||||
return
|
||||
|
||||
let pinnedMsgCursor = self.initOrGetPinnedMessageCursor(chatId)
|
||||
let pinnedMsgCursorValue = if (pinnedMsgCursor.isFetchable()): pinnedMsgCursor.getValue() else: CURSOR_VALUE_IGNORE
|
||||
|
||||
if(pinnedMsgCursorValue == CURSOR_VALUE_IGNORE):
|
||||
return
|
||||
|
||||
pinnedMsgCursor.setPending()
|
||||
|
||||
let arg = AsyncFetchChatMessagesTaskArg(
|
||||
tptr: cast[ByteAddress](asyncFetchPinnedChatMessagesTask),
|
||||
vptr: cast[ByteAddress](self.vptr),
|
||||
slot: "onAsyncLoadPinnedMessagesForChat",
|
||||
chatId: chatId,
|
||||
msgCursor: pinnedMsgCursorValue,
|
||||
limit: MESSAGES_PER_PAGE_MAX
|
||||
)
|
||||
|
||||
self.threadpool.start(arg)
|
||||
|
||||
proc asyncLoadInitialMessagesForChat*(self: Service, chatId: string) =
|
||||
if(self.isChatCursorInitialized(chatId)):
|
||||
let data = MessagesLoadedArgs(chatId: chatId,
|
||||
messages: @[],
|
||||
pinnedMessages: @[],
|
||||
reactions: @[])
|
||||
|
||||
self.events.emit(SIGNAL_MESSAGES_LOADED, data)
|
||||
|
@ -389,30 +410,17 @@ QtObject:
|
|||
weiStr.trimZeros()
|
||||
return (tokenStr, weiStr)
|
||||
|
||||
proc onAsyncLoadMoreMessagesForChat*(self: Service, response: string) {.slot.} =
|
||||
proc onAsyncLoadPinnedMessagesForChat*(self: Service, response: string) {.slot.} =
|
||||
let responseObj = response.parseJson
|
||||
if (responseObj.kind != JObject):
|
||||
info "load more messages response is not a json object"
|
||||
# notify view, this is important
|
||||
self.events.emit(SIGNAL_MESSAGES_LOADED, MessagesLoadedArgs())
|
||||
info "load pinned messages response is not a json object"
|
||||
self.events.emit(SIGNAL_PINNED_MESSAGES_LOADED, PinnedMessagesLoadedArgs())
|
||||
return
|
||||
|
||||
var chatId: string
|
||||
discard responseObj.getProp("chatId", chatId)
|
||||
|
||||
let msgCursor = self.initOrGetMessageCursor(chatId)
|
||||
let pinnedMsgCursor = self.initOrGetPinnedMessageCursor(chatId)
|
||||
|
||||
# handling messages
|
||||
var msgCursorValue: string
|
||||
if(responseObj.getProp("messagesCursor", msgCursorValue)):
|
||||
msgCursor.setValue(msgCursorValue)
|
||||
|
||||
var messagesArr: JsonNode
|
||||
var messages: seq[MessageDto]
|
||||
if(responseObj.getProp("messages", messagesArr)):
|
||||
messages = map(messagesArr.getElems(), proc(x: JsonNode): MessageDto = x.toMessageDto())
|
||||
|
||||
# handling pinned messages
|
||||
var pinnedMsgCursorValue: string
|
||||
if(responseObj.getProp("pinnedMessagesCursor", pinnedMsgCursorValue)):
|
||||
|
@ -426,6 +434,38 @@ QtObject:
|
|||
# set initial number of pinned messages
|
||||
self.numOfPinnedMessagesPerChat[chatId] = pinnedMessages.len
|
||||
|
||||
let data = PinnedMessagesLoadedArgs(chatId: chatId,
|
||||
pinnedMessages: pinnedMessages)
|
||||
|
||||
self.events.emit(SIGNAL_PINNED_MESSAGES_LOADED, data)
|
||||
|
||||
proc onAsyncLoadMoreMessagesForChat*(self: Service, response: string) {.slot.} =
|
||||
let responseObj = response.parseJson
|
||||
if (responseObj.kind != JObject):
|
||||
info "load more messages response is not a json object"
|
||||
# notify view, this is important
|
||||
self.events.emit(SIGNAL_MESSAGES_LOADED, MessagesLoadedArgs())
|
||||
return
|
||||
|
||||
var chatId: string
|
||||
discard responseObj.getProp("chatId", chatId)
|
||||
|
||||
let msgCursor = self.initOrGetMessageCursor(chatId)
|
||||
if(msgCursor.getValue() == ""):
|
||||
# this is the first time we load messages for this chat
|
||||
# we need to load pinned messages as well
|
||||
self.asyncLoadPinnedMessagesForChat(chatId)
|
||||
|
||||
# handling messages
|
||||
var msgCursorValue: string
|
||||
if(responseObj.getProp("messagesCursor", msgCursorValue)):
|
||||
msgCursor.setValue(msgCursorValue)
|
||||
|
||||
var messagesArr: JsonNode
|
||||
var messages: seq[MessageDto]
|
||||
if(responseObj.getProp("messages", messagesArr)):
|
||||
messages = map(messagesArr.getElems(), proc(x: JsonNode): MessageDto = x.toMessageDto())
|
||||
|
||||
# handling reactions
|
||||
var reactionsArr: JsonNode
|
||||
var reactions: seq[ReactionDto]
|
||||
|
@ -434,7 +474,6 @@ QtObject:
|
|||
|
||||
let data = MessagesLoadedArgs(chatId: chatId,
|
||||
messages: messages,
|
||||
pinnedMessages: pinnedMessages,
|
||||
reactions: reactions)
|
||||
|
||||
self.events.emit(SIGNAL_MESSAGES_LOADED, data)
|
||||
|
|
Loading…
Reference in New Issue