Yet another MAM logic rewrite: assume request order by RSM before/after, do not consider RSM limitation themselves as incompleteness

This commit is contained in:
Bohdan Horbeshko 2025-09-19 12:44:35 -04:00
parent 15f62b619d
commit 89d368abbb
2 changed files with 28 additions and 26 deletions

View file

@ -2478,13 +2478,14 @@ func (c *Client) GetMessagesBetween(chatID, fromMessageId, lastMessageId int64,
if firstMessage.Id > fromMessageId { if firstMessage.Id > fromMessageId {
complete = false complete = false
} }
} else { } else if fromMessageId == 1 {
// try to fetch one more message to check if there are any other before // try to fetch one more message to check if there are any other before
previousMessage, previousMessageErr := c.GetPreviousMessage(chatID, firstMessage.Id) previousMessage, previousMessageErr := c.GetPreviousMessage(chatID, firstMessage.Id)
if previousMessageErr == nil && previousMessage != nil { if previousMessageErr == nil && previousMessage != nil {
complete = false complete = false
} }
} }
// for 0 one last message is already fetched as there is at least one, right?
} }
} else { } else {
for _, message := range fetchedMessages { for _, message := range fetchedMessages {

View file

@ -2344,18 +2344,10 @@ func handleSetQueryMAM(s xmpp.Sender, iq *stanza.IQ, query extensions.MAMQuery)
} }
} }
if rsmBefore != 0 && rsmAfter == 0 {
rsmLastPage = true
}
if rsmLimit == 0 && !justCount { if rsmLimit == 0 && !justCount {
rsmLimit = 100 rsmLimit = 100
} }
if rsmLastPage {
rsmLimit = -rsmLimit // hacky, I know, and? :P
}
// check for mutual parameter compatibility, there's a lot of them, nah? // check for mutual parameter compatibility, there's a lot of them, nah?
if ((!startTime.IsZero() || !endTime.IsZero()) && (beforeId != 0 || afterId != 0 || ids != nil)) || if ((!startTime.IsZero() || !endTime.IsZero()) && (beforeId != 0 || afterId != 0 || ids != nil)) ||
((beforeId != 0 || afterId != 0) && (!startTime.IsZero() || !endTime.IsZero() || ids != nil)) || ((beforeId != 0 || afterId != 0) && (!startTime.IsZero() || !endTime.IsZero() || ids != nil)) ||
@ -2368,11 +2360,32 @@ func handleSetQueryMAM(s xmpp.Sender, iq *stanza.IQ, query extensions.MAMQuery)
// dummy call to circumvent unexported type // dummy call to circumvent unexported type
messages, _, err := session.GetMessagesBetween(toID, 0, 0, 0, false) messages, _, err := session.GetMessagesBetween(toID, 0, 0, 0, false)
var order bool // false from start, true from end
// lower priority
if !endTime.IsZero() {
order = true
}
// higher priority
if beforeId != 0 {
order = false
}
if afterId != 0 {
order = true
}
if rsmAfter != 0 {
order = false
}
if rsmBefore != 0 || rsmLastPage {
order = true
}
if order {
rsmLimit = -rsmLimit // hacky, I know, and? :P
}
quotaTs := time.Now().AddDate(0, 0, -int(gateway.MAMThreshold)) quotaTs := time.Now().AddDate(0, 0, -int(gateway.MAMThreshold))
var beyond, complete bool var beyond, complete bool
canBeComplete := true fromStart := !order
fromStart := !rsmLastPage toEnd := order
toEnd := rsmLastPage
var overallyFirstMessageId, overallyLastMessageId int64 var overallyFirstMessageId, overallyLastMessageId int64
reverse := query.GetFlipPage() != nil reverse := query.GetFlipPage() != nil
@ -2454,7 +2467,6 @@ func handleSetQueryMAM(s xmpp.Sender, iq *stanza.IQ, query extensions.MAMQuery)
} }
if rsmAfter != afterId { if rsmAfter != afterId {
fromStart = false fromStart = false
canBeComplete = false
overallyFirstMessage, overallyFirstMessageErr := session.GetNextMessage(toID, afterId) overallyFirstMessage, overallyFirstMessageErr := session.GetNextMessage(toID, afterId)
if overallyFirstMessageErr == nil && overallyFirstMessage != nil { if overallyFirstMessageErr == nil && overallyFirstMessage != nil {
overallyFirstMessageId = overallyFirstMessage.Id overallyFirstMessageId = overallyFirstMessage.Id
@ -2471,7 +2483,6 @@ func handleSetQueryMAM(s xmpp.Sender, iq *stanza.IQ, query extensions.MAMQuery)
} }
if rsmBefore < beforeId { if rsmBefore < beforeId {
toEnd = false toEnd = false
canBeComplete = false
} }
beforeId = rsmBefore beforeId = rsmBefore
} }
@ -2486,11 +2497,7 @@ func handleSetQueryMAM(s xmpp.Sender, iq *stanza.IQ, query extensions.MAMQuery)
} }
if !beyond { if !beyond {
var newComplete bool messages, complete, err = session.GetMessagesBetween(toID, afterId, lastMessageId, rsmLimit, reverse)
messages, newComplete, err = session.GetMessagesBetween(toID, afterId, lastMessageId, rsmLimit, reverse)
if canBeComplete {
complete = newComplete
}
} }
} else { // time limit or no limits at all } else { // time limit or no limits at all
// don't allow to fetch far beyond the quota // don't allow to fetch far beyond the quota
@ -2540,7 +2547,6 @@ func handleSetQueryMAM(s xmpp.Sender, iq *stanza.IQ, query extensions.MAMQuery)
if rsmAfterMessage.Id > fromMessageId && int64(rsmAfterMessage.Date) >= startTime.Unix() { if rsmAfterMessage.Id > fromMessageId && int64(rsmAfterMessage.Date) >= startTime.Unix() {
fromStart = false fromStart = false
canBeComplete = false
overallyFirstMessage, overallyFirstMessageErr := session.GetNextMessage(toID, fromMessageId) overallyFirstMessage, overallyFirstMessageErr := session.GetNextMessage(toID, fromMessageId)
if overallyFirstMessageErr == nil && overallyFirstMessage != nil { if overallyFirstMessageErr == nil && overallyFirstMessage != nil {
overallyFirstMessageId = overallyFirstMessage.Id overallyFirstMessageId = overallyFirstMessage.Id
@ -2567,7 +2573,6 @@ func handleSetQueryMAM(s xmpp.Sender, iq *stanza.IQ, query extensions.MAMQuery)
newLastMessage, newLastMessageErr := session.GetPreviousMessage(toID, rsmBeforeMessage.Id) newLastMessage, newLastMessageErr := session.GetPreviousMessage(toID, rsmBeforeMessage.Id)
if newLastMessageErr == nil && newLastMessage != nil { if newLastMessageErr == nil && newLastMessage != nil {
if lastMessageId == 0 || lastMessageId != newLastMessage.Id { if lastMessageId == 0 || lastMessageId != newLastMessage.Id {
canBeComplete = false
toEnd = false toEnd = false
lastMessageId = newLastMessage.Id lastMessageId = newLastMessage.Id
} }
@ -2584,11 +2589,7 @@ func handleSetQueryMAM(s xmpp.Sender, iq *stanza.IQ, query extensions.MAMQuery)
} }
if !beyond { // yes🗿, twice if !beyond { // yes🗿, twice
var newComplete bool messages, complete, err = session.GetMessagesBetween(toID, fromMessageId, lastMessageId, rsmLimit, reverse)
messages, newComplete, err = session.GetMessagesBetween(toID, fromMessageId, lastMessageId, rsmLimit, reverse)
if canBeComplete {
complete = newComplete
}
} }
} }
} }