Skip to content

Fix missing update of start_token while backfill prev messages - #284

Open
mattthias wants to merge 1 commit into
matrix-org:masterfrom
mattthias:fix_repeated_history
Open

Fix missing update of start_token while backfill prev messages#284
mattthias wants to merge 1 commit into
matrix-org:masterfrom
mattthias:fix_repeated_history

Conversation

@mattthias

Copy link
Copy Markdown

Hello,

while writing a script that should parse the whole channel history i wondered why i always got the same messages when i called backfill_previous_messages(). Please see the example code which i run with a room that just contains 30 messages (message 1 ... message 30).

>>>frommatrix_client.clientimportMatrixClient>>>client=MatrixClient("https://synapse-server")
>>>token=client.login_with_password(username="mattthias", password="guesswhat")
>>>room=client.join_room("#matrixtest:synapse-server")
>>>print(room.events)
[]
>>>room.backfill_previous_messages()
>>>foreventinroom.events:
... print(event['content'])
... {'body': 'Message 21', 'msgtype': 'm.text'}
{'body': 'Message 22', 'msgtype': 'm.text'}
{'body': 'Message 25', 'msgtype': 'm.text'}
{'body': 'Message 26', 'msgtype': 'm.text'}
{'body': 'Message 23', 'msgtype': 'm.text'}
{'body': 'Message 27', 'msgtype': 'm.text'}
{'body': 'Message 24', 'msgtype': 'm.text'}
{'body': 'Message 28', 'msgtype': 'm.text'}
{'body': 'Message 29', 'msgtype': 'm.text'}
{'body': 'Message 30', 'msgtype': 'm.text'}
>>>room.backfill_previous_messages()
>>>len(room.events)
20>>>foreventinroom.events:
... print(event['content'])
... {'body': 'Message 21', 'msgtype': 'm.text'}
{'body': 'Message 22', 'msgtype': 'm.text'}
{'body': 'Message 25', 'msgtype': 'm.text'}
{'body': 'Message 26', 'msgtype': 'm.text'}
{'body': 'Message 23', 'msgtype': 'm.text'}
{'body': 'Message 27', 'msgtype': 'm.text'}
{'body': 'Message 24', 'msgtype': 'm.text'}
{'body': 'Message 28', 'msgtype': 'm.text'}
{'body': 'Message 29', 'msgtype': 'm.text'}
{'body': 'Message 30', 'msgtype': 'm.text'}
{'body': 'Message 21', 'msgtype': 'm.text'}
{'body': 'Message 22', 'msgtype': 'm.text'}
{'body': 'Message 25', 'msgtype': 'm.text'}
{'body': 'Message 26', 'msgtype': 'm.text'}
{'body': 'Message 23', 'msgtype': 'm.text'}
{'body': 'Message 27', 'msgtype': 'm.text'}
{'body': 'Message 24', 'msgtype': 'm.text'}
{'body': 'Message 28', 'msgtype': 'm.text'}
{'body': 'Message 29', 'msgtype': 'm.text'}
{'body': 'Message 30', 'msgtype': 'm.text'}
>>>

The function backfill_previous_messages() updates the room's event list
(room.events) using the api function "client.api.get_room_messages". The
latter function takes a start token as parameter to know from where in
the history of events to start.

backfill_previous_messages() handes over self.prev_batch as start token
but never updates it. So repeated calls to backfill_previous_messages()
always return the same chunk of events from the room's event history.

This commit fixes this wrong behavior by updating self.prev_batch on
every function call.

Signed-off-by: Matthias Schmitz matthias@sigxcpu.org

The function backfill_previous_messages() updates the room's event list
(room.events) using the api function "client.api.get_room_messages". The
latter function takes a start token as parameter to know from where in
the history of events to start.
backfill_previous_messages() handes over self.prev_batch as start token
but never updates it. So repeated calls to backfill_previous_messages()
always return the same chunk of events from the room's event history.
This commit fixes this wrong behavior by updating self.prev_batch on
every function call.
Signed-off-by: Matthias Schmitz <matthias@sigxcpu.org>
@Zil0

Zil0 commented Oct 8, 2018

Copy link
Copy Markdown
Contributor

Thanks for looking at this! It already came up that this behavior needs fixing.

This is trickier than it seems though, since to me it looks like the update of prev_batch that is done here is not consistent with the one done in client.py. Before, prev_batch was the point before the last messages we received in the last sync. With this, prev_batch can be either that, or any previous token depending on how many times backfilling was done.

There is a very basic case were an issue arises in an obvious way:

  • The client is listening for events in a thread T2 (eg start_listener_thread was called).
  • We operate in main thread T1, and we backfill. prev_batch gets updated.
  • A new event comes up, prev_batch gets updated.
  • We backfill again. Backfilling still exhibits the broken behavior you underlined.

I'm not 100% sure what is the proper fix. My intuition is that the prev_batch returned when backfilling shouldn't end up in the room state, but handed back to the user, and that a way to provide it to backfill_previous_messages should exist in order to retrieve even earlier messages. Possibly via an optional argument, which would default to the token obtained via sync if not present.

Feel free to try different approaches, I'm really interested in seeing this part of the SDK improved :)

@remram44

Copy link
Copy Markdown

I agree that backfilling should be completely independent. It shouldn't affect the sync state, but it probably shouldn't be calling the listeners either, since otherwise the listeners get events out-of-order. Worse, there is no way to distinguish a new message from the ones you get from the backfill request.

Currently, I avoid using backfill_previous_messages entirely, and call get_room_messages manually so I don't mess anything up.

mirukana added a commit to mirukana/matrix-python-sdk that referenced this pull request Jan 9, 2019
When loading new events, Client resets Room.prev_batch
matrix-org#284 (comment)
mirukana added a commit to mirukana/matrix-python-sdk that referenced this pull request Jan 9, 2019
When loading new events, Client resets Room.prev_batch
matrix-org#284 (comment)
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@mattthias@Zil0@remram44
, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Fix missing update of start_token while backfill prev messages by mattthias · Pull Request #284 · matrix-org/matrix-python-sdk · GitHub
Skip to content

Fix missing update of start_token while backfill prev messages - #284

Open
mattthias wants to merge 1 commit into
matrix-org:masterfrom
mattthias:fix_repeated_history
Open

Fix missing update of start_token while backfill prev messages#284
mattthias wants to merge 1 commit into
matrix-org:masterfrom
mattthias:fix_repeated_history

Conversation

@mattthias

Copy link
Copy Markdown

Hello,

while writing a script that should parse the whole channel history i wondered why i always got the same messages when i called backfill_previous_messages(). Please see the example code which i run with a room that just contains 30 messages (message 1 ... message 30).

>>>frommatrix_client.clientimportMatrixClient>>>client=MatrixClient("https://synapse-server")
>>>token=client.login_with_password(username="mattthias", password="guesswhat")
>>>room=client.join_room("#matrixtest:synapse-server")
>>>print(room.events)
[]
>>>room.backfill_previous_messages()
>>>foreventinroom.events:
... print(event['content'])
... {'body': 'Message 21', 'msgtype': 'm.text'}
{'body': 'Message 22', 'msgtype': 'm.text'}
{'body': 'Message 25', 'msgtype': 'm.text'}
{'body': 'Message 26', 'msgtype': 'm.text'}
{'body': 'Message 23', 'msgtype': 'm.text'}
{'body': 'Message 27', 'msgtype': 'm.text'}
{'body': 'Message 24', 'msgtype': 'm.text'}
{'body': 'Message 28', 'msgtype': 'm.text'}
{'body': 'Message 29', 'msgtype': 'm.text'}
{'body': 'Message 30', 'msgtype': 'm.text'}
>>>room.backfill_previous_messages()
>>>len(room.events)
20>>>foreventinroom.events:
... print(event['content'])
... {'body': 'Message 21', 'msgtype': 'm.text'}
{'body': 'Message 22', 'msgtype': 'm.text'}
{'body': 'Message 25', 'msgtype': 'm.text'}
{'body': 'Message 26', 'msgtype': 'm.text'}
{'body': 'Message 23', 'msgtype': 'm.text'}
{'body': 'Message 27', 'msgtype': 'm.text'}
{'body': 'Message 24', 'msgtype': 'm.text'}
{'body': 'Message 28', 'msgtype': 'm.text'}
{'body': 'Message 29', 'msgtype': 'm.text'}
{'body': 'Message 30', 'msgtype': 'm.text'}
{'body': 'Message 21', 'msgtype': 'm.text'}
{'body': 'Message 22', 'msgtype': 'm.text'}
{'body': 'Message 25', 'msgtype': 'm.text'}
{'body': 'Message 26', 'msgtype': 'm.text'}
{'body': 'Message 23', 'msgtype': 'm.text'}
{'body': 'Message 27', 'msgtype': 'm.text'}
{'body': 'Message 24', 'msgtype': 'm.text'}
{'body': 'Message 28', 'msgtype': 'm.text'}
{'body': 'Message 29', 'msgtype': 'm.text'}
{'body': 'Message 30', 'msgtype': 'm.text'}
>>>

The function backfill_previous_messages() updates the room's event list
(room.events) using the api function "client.api.get_room_messages". The
latter function takes a start token as parameter to know from where in
the history of events to start.

backfill_previous_messages() handes over self.prev_batch as start token
but never updates it. So repeated calls to backfill_previous_messages()
always return the same chunk of events from the room's event history.

This commit fixes this wrong behavior by updating self.prev_batch on
every function call.

Signed-off-by: Matthias Schmitz matthias@sigxcpu.org

The function backfill_previous_messages() updates the room's event list
(room.events) using the api function "client.api.get_room_messages". The
latter function takes a start token as parameter to know from where in
the history of events to start.
backfill_previous_messages() handes over self.prev_batch as start token
but never updates it. So repeated calls to backfill_previous_messages()
always return the same chunk of events from the room's event history.
This commit fixes this wrong behavior by updating self.prev_batch on
every function call.
Signed-off-by: Matthias Schmitz <matthias@sigxcpu.org>
@Zil0

Zil0 commented Oct 8, 2018

Copy link
Copy Markdown
Contributor

Thanks for looking at this! It already came up that this behavior needs fixing.

This is trickier than it seems though, since to me it looks like the update of prev_batch that is done here is not consistent with the one done in client.py. Before, prev_batch was the point before the last messages we received in the last sync. With this, prev_batch can be either that, or any previous token depending on how many times backfilling was done.

There is a very basic case were an issue arises in an obvious way:

  • The client is listening for events in a thread T2 (eg start_listener_thread was called).
  • We operate in main thread T1, and we backfill. prev_batch gets updated.
  • A new event comes up, prev_batch gets updated.
  • We backfill again. Backfilling still exhibits the broken behavior you underlined.

I'm not 100% sure what is the proper fix. My intuition is that the prev_batch returned when backfilling shouldn't end up in the room state, but handed back to the user, and that a way to provide it to backfill_previous_messages should exist in order to retrieve even earlier messages. Possibly via an optional argument, which would default to the token obtained via sync if not present.

Feel free to try different approaches, I'm really interested in seeing this part of the SDK improved :)

@remram44

Copy link
Copy Markdown

I agree that backfilling should be completely independent. It shouldn't affect the sync state, but it probably shouldn't be calling the listeners either, since otherwise the listeners get events out-of-order. Worse, there is no way to distinguish a new message from the ones you get from the backfill request.

Currently, I avoid using backfill_previous_messages entirely, and call get_room_messages manually so I don't mess anything up.

mirukana added a commit to mirukana/matrix-python-sdk that referenced this pull request Jan 9, 2019
When loading new events, Client resets Room.prev_batch
matrix-org#284 (comment)
mirukana added a commit to mirukana/matrix-python-sdk that referenced this pull request Jan 9, 2019
When loading new events, Client resets Room.prev_batch
matrix-org#284 (comment)
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@mattthias@Zil0@remram44
, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Fix missing update of start_token while backfill prev messages by mattthias · Pull Request #284 · matrix-org/matrix-python-sdk · GitHub
Skip to content

Fix missing update of start_token while backfill prev messages - #284

Open
mattthias wants to merge 1 commit into
matrix-org:masterfrom
mattthias:fix_repeated_history
Open

Fix missing update of start_token while backfill prev messages#284
mattthias wants to merge 1 commit into
matrix-org:masterfrom
mattthias:fix_repeated_history

Conversation

@mattthias

Copy link
Copy Markdown

Hello,

while writing a script that should parse the whole channel history i wondered why i always got the same messages when i called backfill_previous_messages(). Please see the example code which i run with a room that just contains 30 messages (message 1 ... message 30).

>>>frommatrix_client.clientimportMatrixClient>>>client=MatrixClient("https://synapse-server")
>>>token=client.login_with_password(username="mattthias", password="guesswhat")
>>>room=client.join_room("#matrixtest:synapse-server")
>>>print(room.events)
[]
>>>room.backfill_previous_messages()
>>>foreventinroom.events:
... print(event['content'])
... {'body': 'Message 21', 'msgtype': 'm.text'}
{'body': 'Message 22', 'msgtype': 'm.text'}
{'body': 'Message 25', 'msgtype': 'm.text'}
{'body': 'Message 26', 'msgtype': 'm.text'}
{'body': 'Message 23', 'msgtype': 'm.text'}
{'body': 'Message 27', 'msgtype': 'm.text'}
{'body': 'Message 24', 'msgtype': 'm.text'}
{'body': 'Message 28', 'msgtype': 'm.text'}
{'body': 'Message 29', 'msgtype': 'm.text'}
{'body': 'Message 30', 'msgtype': 'm.text'}
>>>room.backfill_previous_messages()
>>>len(room.events)
20>>>foreventinroom.events:
... print(event['content'])
... {'body': 'Message 21', 'msgtype': 'm.text'}
{'body': 'Message 22', 'msgtype': 'm.text'}
{'body': 'Message 25', 'msgtype': 'm.text'}
{'body': 'Message 26', 'msgtype': 'm.text'}
{'body': 'Message 23', 'msgtype': 'm.text'}
{'body': 'Message 27', 'msgtype': 'm.text'}
{'body': 'Message 24', 'msgtype': 'm.text'}
{'body': 'Message 28', 'msgtype': 'm.text'}
{'body': 'Message 29', 'msgtype': 'm.text'}
{'body': 'Message 30', 'msgtype': 'm.text'}
{'body': 'Message 21', 'msgtype': 'm.text'}
{'body': 'Message 22', 'msgtype': 'm.text'}
{'body': 'Message 25', 'msgtype': 'm.text'}
{'body': 'Message 26', 'msgtype': 'm.text'}
{'body': 'Message 23', 'msgtype': 'm.text'}
{'body': 'Message 27', 'msgtype': 'm.text'}
{'body': 'Message 24', 'msgtype': 'm.text'}
{'body': 'Message 28', 'msgtype': 'm.text'}
{'body': 'Message 29', 'msgtype': 'm.text'}
{'body': 'Message 30', 'msgtype': 'm.text'}
>>>

The function backfill_previous_messages() updates the room's event list
(room.events) using the api function "client.api.get_room_messages". The
latter function takes a start token as parameter to know from where in
the history of events to start.

backfill_previous_messages() handes over self.prev_batch as start token
but never updates it. So repeated calls to backfill_previous_messages()
always return the same chunk of events from the room's event history.

This commit fixes this wrong behavior by updating self.prev_batch on
every function call.

Signed-off-by: Matthias Schmitz matthias@sigxcpu.org

The function backfill_previous_messages() updates the room's event list
(room.events) using the api function "client.api.get_room_messages". The
latter function takes a start token as parameter to know from where in
the history of events to start.
backfill_previous_messages() handes over self.prev_batch as start token
but never updates it. So repeated calls to backfill_previous_messages()
always return the same chunk of events from the room's event history.
This commit fixes this wrong behavior by updating self.prev_batch on
every function call.
Signed-off-by: Matthias Schmitz <matthias@sigxcpu.org>
@Zil0

Zil0 commented Oct 8, 2018

Copy link
Copy Markdown
Contributor

Thanks for looking at this! It already came up that this behavior needs fixing.

This is trickier than it seems though, since to me it looks like the update of prev_batch that is done here is not consistent with the one done in client.py. Before, prev_batch was the point before the last messages we received in the last sync. With this, prev_batch can be either that, or any previous token depending on how many times backfilling was done.

There is a very basic case were an issue arises in an obvious way:

  • The client is listening for events in a thread T2 (eg start_listener_thread was called).
  • We operate in main thread T1, and we backfill. prev_batch gets updated.
  • A new event comes up, prev_batch gets updated.
  • We backfill again. Backfilling still exhibits the broken behavior you underlined.

I'm not 100% sure what is the proper fix. My intuition is that the prev_batch returned when backfilling shouldn't end up in the room state, but handed back to the user, and that a way to provide it to backfill_previous_messages should exist in order to retrieve even earlier messages. Possibly via an optional argument, which would default to the token obtained via sync if not present.

Feel free to try different approaches, I'm really interested in seeing this part of the SDK improved :)

@remram44

Copy link
Copy Markdown

I agree that backfilling should be completely independent. It shouldn't affect the sync state, but it probably shouldn't be calling the listeners either, since otherwise the listeners get events out-of-order. Worse, there is no way to distinguish a new message from the ones you get from the backfill request.

Currently, I avoid using backfill_previous_messages entirely, and call get_room_messages manually so I don't mess anything up.

mirukana added a commit to mirukana/matrix-python-sdk that referenced this pull request Jan 9, 2019
When loading new events, Client resets Room.prev_batch
matrix-org#284 (comment)
mirukana added a commit to mirukana/matrix-python-sdk that referenced this pull request Jan 9, 2019
When loading new events, Client resets Room.prev_batch
matrix-org#284 (comment)
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@mattthias@Zil0@remram44
, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Fix missing update of start_token while backfill prev messages by mattthias · Pull Request #284 · matrix-org/matrix-python-sdk · GitHub
Skip to content

Fix missing update of start_token while backfill prev messages - #284

Open
mattthias wants to merge 1 commit into
matrix-org:masterfrom
mattthias:fix_repeated_history
Open

Fix missing update of start_token while backfill prev messages#284
mattthias wants to merge 1 commit into
matrix-org:masterfrom
mattthias:fix_repeated_history

Conversation

@mattthias

Copy link
Copy Markdown

Hello,

while writing a script that should parse the whole channel history i wondered why i always got the same messages when i called backfill_previous_messages(). Please see the example code which i run with a room that just contains 30 messages (message 1 ... message 30).

>>>frommatrix_client.clientimportMatrixClient>>>client=MatrixClient("https://synapse-server")
>>>token=client.login_with_password(username="mattthias", password="guesswhat")
>>>room=client.join_room("#matrixtest:synapse-server")
>>>print(room.events)
[]
>>>room.backfill_previous_messages()
>>>foreventinroom.events:
... print(event['content'])
... {'body': 'Message 21', 'msgtype': 'm.text'}
{'body': 'Message 22', 'msgtype': 'm.text'}
{'body': 'Message 25', 'msgtype': 'm.text'}
{'body': 'Message 26', 'msgtype': 'm.text'}
{'body': 'Message 23', 'msgtype': 'm.text'}
{'body': 'Message 27', 'msgtype': 'm.text'}
{'body': 'Message 24', 'msgtype': 'm.text'}
{'body': 'Message 28', 'msgtype': 'm.text'}
{'body': 'Message 29', 'msgtype': 'm.text'}
{'body': 'Message 30', 'msgtype': 'm.text'}
>>>room.backfill_previous_messages()
>>>len(room.events)
20>>>foreventinroom.events:
... print(event['content'])
... {'body': 'Message 21', 'msgtype': 'm.text'}
{'body': 'Message 22', 'msgtype': 'm.text'}
{'body': 'Message 25', 'msgtype': 'm.text'}
{'body': 'Message 26', 'msgtype': 'm.text'}
{'body': 'Message 23', 'msgtype': 'm.text'}
{'body': 'Message 27', 'msgtype': 'm.text'}
{'body': 'Message 24', 'msgtype': 'm.text'}
{'body': 'Message 28', 'msgtype': 'm.text'}
{'body': 'Message 29', 'msgtype': 'm.text'}
{'body': 'Message 30', 'msgtype': 'm.text'}
{'body': 'Message 21', 'msgtype': 'm.text'}
{'body': 'Message 22', 'msgtype': 'm.text'}
{'body': 'Message 25', 'msgtype': 'm.text'}
{'body': 'Message 26', 'msgtype': 'm.text'}
{'body': 'Message 23', 'msgtype': 'm.text'}
{'body': 'Message 27', 'msgtype': 'm.text'}
{'body': 'Message 24', 'msgtype': 'm.text'}
{'body': 'Message 28', 'msgtype': 'm.text'}
{'body': 'Message 29', 'msgtype': 'm.text'}
{'body': 'Message 30', 'msgtype': 'm.text'}
>>>

The function backfill_previous_messages() updates the room's event list
(room.events) using the api function "client.api.get_room_messages". The
latter function takes a start token as parameter to know from where in
the history of events to start.

backfill_previous_messages() handes over self.prev_batch as start token
but never updates it. So repeated calls to backfill_previous_messages()
always return the same chunk of events from the room's event history.

This commit fixes this wrong behavior by updating self.prev_batch on
every function call.

Signed-off-by: Matthias Schmitz matthias@sigxcpu.org

The function backfill_previous_messages() updates the room's event list
(room.events) using the api function "client.api.get_room_messages". The
latter function takes a start token as parameter to know from where in
the history of events to start.
backfill_previous_messages() handes over self.prev_batch as start token
but never updates it. So repeated calls to backfill_previous_messages()
always return the same chunk of events from the room's event history.
This commit fixes this wrong behavior by updating self.prev_batch on
every function call.
Signed-off-by: Matthias Schmitz <matthias@sigxcpu.org>
@Zil0

Zil0 commented Oct 8, 2018

Copy link
Copy Markdown
Contributor

Thanks for looking at this! It already came up that this behavior needs fixing.

This is trickier than it seems though, since to me it looks like the update of prev_batch that is done here is not consistent with the one done in client.py. Before, prev_batch was the point before the last messages we received in the last sync. With this, prev_batch can be either that, or any previous token depending on how many times backfilling was done.

There is a very basic case were an issue arises in an obvious way:

  • The client is listening for events in a thread T2 (eg start_listener_thread was called).
  • We operate in main thread T1, and we backfill. prev_batch gets updated.
  • A new event comes up, prev_batch gets updated.
  • We backfill again. Backfilling still exhibits the broken behavior you underlined.

I'm not 100% sure what is the proper fix. My intuition is that the prev_batch returned when backfilling shouldn't end up in the room state, but handed back to the user, and that a way to provide it to backfill_previous_messages should exist in order to retrieve even earlier messages. Possibly via an optional argument, which would default to the token obtained via sync if not present.

Feel free to try different approaches, I'm really interested in seeing this part of the SDK improved :)

@remram44

Copy link
Copy Markdown

I agree that backfilling should be completely independent. It shouldn't affect the sync state, but it probably shouldn't be calling the listeners either, since otherwise the listeners get events out-of-order. Worse, there is no way to distinguish a new message from the ones you get from the backfill request.

Currently, I avoid using backfill_previous_messages entirely, and call get_room_messages manually so I don't mess anything up.

mirukana added a commit to mirukana/matrix-python-sdk that referenced this pull request Jan 9, 2019
When loading new events, Client resets Room.prev_batch
matrix-org#284 (comment)
mirukana added a commit to mirukana/matrix-python-sdk that referenced this pull request Jan 9, 2019
When loading new events, Client resets Room.prev_batch
matrix-org#284 (comment)
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@mattthias@Zil0@remram44
, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' Fix missing update of start_token while backfill prev messages by mattthias · Pull Request #284 · matrix-org/matrix-python-sdk · GitHub
Skip to content

Fix missing update of start_token while backfill prev messages - #284

Open
mattthias wants to merge 1 commit into
matrix-org:masterfrom
mattthias:fix_repeated_history
Open

Fix missing update of start_token while backfill prev messages#284
mattthias wants to merge 1 commit into
matrix-org:masterfrom
mattthias:fix_repeated_history

Conversation

@mattthias

Copy link
Copy Markdown

Hello,

while writing a script that should parse the whole channel history i wondered why i always got the same messages when i called backfill_previous_messages(). Please see the example code which i run with a room that just contains 30 messages (message 1 ... message 30).

>>>frommatrix_client.clientimportMatrixClient>>>client=MatrixClient("https://synapse-server")
>>>token=client.login_with_password(username="mattthias", password="guesswhat")
>>>room=client.join_room("#matrixtest:synapse-server")
>>>print(room.events)
[]
>>>room.backfill_previous_messages()
>>>foreventinroom.events:
... print(event['content'])
... {'body': 'Message 21', 'msgtype': 'm.text'}
{'body': 'Message 22', 'msgtype': 'm.text'}
{'body': 'Message 25', 'msgtype': 'm.text'}
{'body': 'Message 26', 'msgtype': 'm.text'}
{'body': 'Message 23', 'msgtype': 'm.text'}
{'body': 'Message 27', 'msgtype': 'm.text'}
{'body': 'Message 24', 'msgtype': 'm.text'}
{'body': 'Message 28', 'msgtype': 'm.text'}
{'body': 'Message 29', 'msgtype': 'm.text'}
{'body': 'Message 30', 'msgtype': 'm.text'}
>>>room.backfill_previous_messages()
>>>len(room.events)
20>>>foreventinroom.events:
... print(event['content'])
... {'body': 'Message 21', 'msgtype': 'm.text'}
{'body': 'Message 22', 'msgtype': 'm.text'}
{'body': 'Message 25', 'msgtype': 'm.text'}
{'body': 'Message 26', 'msgtype': 'm.text'}
{'body': 'Message 23', 'msgtype': 'm.text'}
{'body': 'Message 27', 'msgtype': 'm.text'}
{'body': 'Message 24', 'msgtype': 'm.text'}
{'body': 'Message 28', 'msgtype': 'm.text'}
{'body': 'Message 29', 'msgtype': 'm.text'}
{'body': 'Message 30', 'msgtype': 'm.text'}
{'body': 'Message 21', 'msgtype': 'm.text'}
{'body': 'Message 22', 'msgtype': 'm.text'}
{'body': 'Message 25', 'msgtype': 'm.text'}
{'body': 'Message 26', 'msgtype': 'm.text'}
{'body': 'Message 23', 'msgtype': 'm.text'}
{'body': 'Message 27', 'msgtype': 'm.text'}
{'body': 'Message 24', 'msgtype': 'm.text'}
{'body': 'Message 28', 'msgtype': 'm.text'}
{'body': 'Message 29', 'msgtype': 'm.text'}
{'body': 'Message 30', 'msgtype': 'm.text'}
>>>

The function backfill_previous_messages() updates the room's event list
(room.events) using the api function "client.api.get_room_messages". The
latter function takes a start token as parameter to know from where in
the history of events to start.

backfill_previous_messages() handes over self.prev_batch as start token
but never updates it. So repeated calls to backfill_previous_messages()
always return the same chunk of events from the room's event history.

This commit fixes this wrong behavior by updating self.prev_batch on
every function call.

Signed-off-by: Matthias Schmitz matthias@sigxcpu.org

The function backfill_previous_messages() updates the room's event list
(room.events) using the api function "client.api.get_room_messages". The
latter function takes a start token as parameter to know from where in
the history of events to start.
backfill_previous_messages() handes over self.prev_batch as start token
but never updates it. So repeated calls to backfill_previous_messages()
always return the same chunk of events from the room's event history.
This commit fixes this wrong behavior by updating self.prev_batch on
every function call.
Signed-off-by: Matthias Schmitz <matthias@sigxcpu.org>
@Zil0

Zil0 commented Oct 8, 2018

Copy link
Copy Markdown
Contributor

Thanks for looking at this! It already came up that this behavior needs fixing.

This is trickier than it seems though, since to me it looks like the update of prev_batch that is done here is not consistent with the one done in client.py. Before, prev_batch was the point before the last messages we received in the last sync. With this, prev_batch can be either that, or any previous token depending on how many times backfilling was done.

There is a very basic case were an issue arises in an obvious way:

  • The client is listening for events in a thread T2 (eg start_listener_thread was called).
  • We operate in main thread T1, and we backfill. prev_batch gets updated.
  • A new event comes up, prev_batch gets updated.
  • We backfill again. Backfilling still exhibits the broken behavior you underlined.

I'm not 100% sure what is the proper fix. My intuition is that the prev_batch returned when backfilling shouldn't end up in the room state, but handed back to the user, and that a way to provide it to backfill_previous_messages should exist in order to retrieve even earlier messages. Possibly via an optional argument, which would default to the token obtained via sync if not present.

Feel free to try different approaches, I'm really interested in seeing this part of the SDK improved :)

@remram44

Copy link
Copy Markdown

I agree that backfilling should be completely independent. It shouldn't affect the sync state, but it probably shouldn't be calling the listeners either, since otherwise the listeners get events out-of-order. Worse, there is no way to distinguish a new message from the ones you get from the backfill request.

Currently, I avoid using backfill_previous_messages entirely, and call get_room_messages manually so I don't mess anything up.

mirukana added a commit to mirukana/matrix-python-sdk that referenced this pull request Jan 9, 2019
When loading new events, Client resets Room.prev_batch
matrix-org#284 (comment)
mirukana added a commit to mirukana/matrix-python-sdk that referenced this pull request Jan 9, 2019
When loading new events, Client resets Room.prev_batch
matrix-org#284 (comment)
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@mattthias@Zil0@remram44
, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Fix missing update of start_token while backfill prev messages by mattthias · Pull Request #284 · matrix-org/matrix-python-sdk · GitHub
Skip to content

Fix missing update of start_token while backfill prev messages - #284

Open
mattthias wants to merge 1 commit into
matrix-org:masterfrom
mattthias:fix_repeated_history
Open

Fix missing update of start_token while backfill prev messages#284
mattthias wants to merge 1 commit into
matrix-org:masterfrom
mattthias:fix_repeated_history

Conversation

@mattthias

Copy link
Copy Markdown

Hello,

while writing a script that should parse the whole channel history i wondered why i always got the same messages when i called backfill_previous_messages(). Please see the example code which i run with a room that just contains 30 messages (message 1 ... message 30).

>>>frommatrix_client.clientimportMatrixClient>>>client=MatrixClient("https://synapse-server")
>>>token=client.login_with_password(username="mattthias", password="guesswhat")
>>>room=client.join_room("#matrixtest:synapse-server")
>>>print(room.events)
[]
>>>room.backfill_previous_messages()
>>>foreventinroom.events:
... print(event['content'])
... {'body': 'Message 21', 'msgtype': 'm.text'}
{'body': 'Message 22', 'msgtype': 'm.text'}
{'body': 'Message 25', 'msgtype': 'm.text'}
{'body': 'Message 26', 'msgtype': 'm.text'}
{'body': 'Message 23', 'msgtype': 'm.text'}
{'body': 'Message 27', 'msgtype': 'm.text'}
{'body': 'Message 24', 'msgtype': 'm.text'}
{'body': 'Message 28', 'msgtype': 'm.text'}
{'body': 'Message 29', 'msgtype': 'm.text'}
{'body': 'Message 30', 'msgtype': 'm.text'}
>>>room.backfill_previous_messages()
>>>len(room.events)
20>>>foreventinroom.events:
... print(event['content'])
... {'body': 'Message 21', 'msgtype': 'm.text'}
{'body': 'Message 22', 'msgtype': 'm.text'}
{'body': 'Message 25', 'msgtype': 'm.text'}
{'body': 'Message 26', 'msgtype': 'm.text'}
{'body': 'Message 23', 'msgtype': 'm.text'}
{'body': 'Message 27', 'msgtype': 'm.text'}
{'body': 'Message 24', 'msgtype': 'm.text'}
{'body': 'Message 28', 'msgtype': 'm.text'}
{'body': 'Message 29', 'msgtype': 'm.text'}
{'body': 'Message 30', 'msgtype': 'm.text'}
{'body': 'Message 21', 'msgtype': 'm.text'}
{'body': 'Message 22', 'msgtype': 'm.text'}
{'body': 'Message 25', 'msgtype': 'm.text'}
{'body': 'Message 26', 'msgtype': 'm.text'}
{'body': 'Message 23', 'msgtype': 'm.text'}
{'body': 'Message 27', 'msgtype': 'm.text'}
{'body': 'Message 24', 'msgtype': 'm.text'}
{'body': 'Message 28', 'msgtype': 'm.text'}
{'body': 'Message 29', 'msgtype': 'm.text'}
{'body': 'Message 30', 'msgtype': 'm.text'}
>>>

The function backfill_previous_messages() updates the room's event list
(room.events) using the api function "client.api.get_room_messages". The
latter function takes a start token as parameter to know from where in
the history of events to start.

backfill_previous_messages() handes over self.prev_batch as start token
but never updates it. So repeated calls to backfill_previous_messages()
always return the same chunk of events from the room's event history.

This commit fixes this wrong behavior by updating self.prev_batch on
every function call.

Signed-off-by: Matthias Schmitz matthias@sigxcpu.org

The function backfill_previous_messages() updates the room's event list
(room.events) using the api function "client.api.get_room_messages". The
latter function takes a start token as parameter to know from where in
the history of events to start.
backfill_previous_messages() handes over self.prev_batch as start token
but never updates it. So repeated calls to backfill_previous_messages()
always return the same chunk of events from the room's event history.
This commit fixes this wrong behavior by updating self.prev_batch on
every function call.
Signed-off-by: Matthias Schmitz <matthias@sigxcpu.org>
@Zil0

Zil0 commented Oct 8, 2018

Copy link
Copy Markdown
Contributor

Thanks for looking at this! It already came up that this behavior needs fixing.

This is trickier than it seems though, since to me it looks like the update of prev_batch that is done here is not consistent with the one done in client.py. Before, prev_batch was the point before the last messages we received in the last sync. With this, prev_batch can be either that, or any previous token depending on how many times backfilling was done.

There is a very basic case were an issue arises in an obvious way:

  • The client is listening for events in a thread T2 (eg start_listener_thread was called).
  • We operate in main thread T1, and we backfill. prev_batch gets updated.
  • A new event comes up, prev_batch gets updated.
  • We backfill again. Backfilling still exhibits the broken behavior you underlined.

I'm not 100% sure what is the proper fix. My intuition is that the prev_batch returned when backfilling shouldn't end up in the room state, but handed back to the user, and that a way to provide it to backfill_previous_messages should exist in order to retrieve even earlier messages. Possibly via an optional argument, which would default to the token obtained via sync if not present.

Feel free to try different approaches, I'm really interested in seeing this part of the SDK improved :)

@remram44

Copy link
Copy Markdown

I agree that backfilling should be completely independent. It shouldn't affect the sync state, but it probably shouldn't be calling the listeners either, since otherwise the listeners get events out-of-order. Worse, there is no way to distinguish a new message from the ones you get from the backfill request.

Currently, I avoid using backfill_previous_messages entirely, and call get_room_messages manually so I don't mess anything up.

mirukana added a commit to mirukana/matrix-python-sdk that referenced this pull request Jan 9, 2019
When loading new events, Client resets Room.prev_batch
matrix-org#284 (comment)
mirukana added a commit to mirukana/matrix-python-sdk that referenced this pull request Jan 9, 2019
When loading new events, Client resets Room.prev_batch
matrix-org#284 (comment)
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@mattthias@Zil0@remram44
, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Fix missing update of start_token while backfill prev messages by mattthias · Pull Request #284 · matrix-org/matrix-python-sdk · GitHub
Skip to content

Fix missing update of start_token while backfill prev messages - #284

Open
mattthias wants to merge 1 commit into
matrix-org:masterfrom
mattthias:fix_repeated_history
Open

Fix missing update of start_token while backfill prev messages#284
mattthias wants to merge 1 commit into
matrix-org:masterfrom
mattthias:fix_repeated_history

Conversation

@mattthias

Copy link
Copy Markdown

Hello,

while writing a script that should parse the whole channel history i wondered why i always got the same messages when i called backfill_previous_messages(). Please see the example code which i run with a room that just contains 30 messages (message 1 ... message 30).

>>>frommatrix_client.clientimportMatrixClient>>>client=MatrixClient("https://synapse-server")
>>>token=client.login_with_password(username="mattthias", password="guesswhat")
>>>room=client.join_room("#matrixtest:synapse-server")
>>>print(room.events)
[]
>>>room.backfill_previous_messages()
>>>foreventinroom.events:
... print(event['content'])
... {'body': 'Message 21', 'msgtype': 'm.text'}
{'body': 'Message 22', 'msgtype': 'm.text'}
{'body': 'Message 25', 'msgtype': 'm.text'}
{'body': 'Message 26', 'msgtype': 'm.text'}
{'body': 'Message 23', 'msgtype': 'm.text'}
{'body': 'Message 27', 'msgtype': 'm.text'}
{'body': 'Message 24', 'msgtype': 'm.text'}
{'body': 'Message 28', 'msgtype': 'm.text'}
{'body': 'Message 29', 'msgtype': 'm.text'}
{'body': 'Message 30', 'msgtype': 'm.text'}
>>>room.backfill_previous_messages()
>>>len(room.events)
20>>>foreventinroom.events:
... print(event['content'])
... {'body': 'Message 21', 'msgtype': 'm.text'}
{'body': 'Message 22', 'msgtype': 'm.text'}
{'body': 'Message 25', 'msgtype': 'm.text'}
{'body': 'Message 26', 'msgtype': 'm.text'}
{'body': 'Message 23', 'msgtype': 'm.text'}
{'body': 'Message 27', 'msgtype': 'm.text'}
{'body': 'Message 24', 'msgtype': 'm.text'}
{'body': 'Message 28', 'msgtype': 'm.text'}
{'body': 'Message 29', 'msgtype': 'm.text'}
{'body': 'Message 30', 'msgtype': 'm.text'}
{'body': 'Message 21', 'msgtype': 'm.text'}
{'body': 'Message 22', 'msgtype': 'm.text'}
{'body': 'Message 25', 'msgtype': 'm.text'}
{'body': 'Message 26', 'msgtype': 'm.text'}
{'body': 'Message 23', 'msgtype': 'm.text'}
{'body': 'Message 27', 'msgtype': 'm.text'}
{'body': 'Message 24', 'msgtype': 'm.text'}
{'body': 'Message 28', 'msgtype': 'm.text'}
{'body': 'Message 29', 'msgtype': 'm.text'}
{'body': 'Message 30', 'msgtype': 'm.text'}
>>>

The function backfill_previous_messages() updates the room's event list
(room.events) using the api function "client.api.get_room_messages". The
latter function takes a start token as parameter to know from where in
the history of events to start.

backfill_previous_messages() handes over self.prev_batch as start token
but never updates it. So repeated calls to backfill_previous_messages()
always return the same chunk of events from the room's event history.

This commit fixes this wrong behavior by updating self.prev_batch on
every function call.

Signed-off-by: Matthias Schmitz matthias@sigxcpu.org

The function backfill_previous_messages() updates the room's event list
(room.events) using the api function "client.api.get_room_messages". The
latter function takes a start token as parameter to know from where in
the history of events to start.
backfill_previous_messages() handes over self.prev_batch as start token
but never updates it. So repeated calls to backfill_previous_messages()
always return the same chunk of events from the room's event history.
This commit fixes this wrong behavior by updating self.prev_batch on
every function call.
Signed-off-by: Matthias Schmitz <matthias@sigxcpu.org>
@Zil0

Zil0 commented Oct 8, 2018

Copy link
Copy Markdown
Contributor

Thanks for looking at this! It already came up that this behavior needs fixing.

This is trickier than it seems though, since to me it looks like the update of prev_batch that is done here is not consistent with the one done in client.py. Before, prev_batch was the point before the last messages we received in the last sync. With this, prev_batch can be either that, or any previous token depending on how many times backfilling was done.

There is a very basic case were an issue arises in an obvious way:

  • The client is listening for events in a thread T2 (eg start_listener_thread was called).
  • We operate in main thread T1, and we backfill. prev_batch gets updated.
  • A new event comes up, prev_batch gets updated.
  • We backfill again. Backfilling still exhibits the broken behavior you underlined.

I'm not 100% sure what is the proper fix. My intuition is that the prev_batch returned when backfilling shouldn't end up in the room state, but handed back to the user, and that a way to provide it to backfill_previous_messages should exist in order to retrieve even earlier messages. Possibly via an optional argument, which would default to the token obtained via sync if not present.

Feel free to try different approaches, I'm really interested in seeing this part of the SDK improved :)

@remram44

Copy link
Copy Markdown

I agree that backfilling should be completely independent. It shouldn't affect the sync state, but it probably shouldn't be calling the listeners either, since otherwise the listeners get events out-of-order. Worse, there is no way to distinguish a new message from the ones you get from the backfill request.

Currently, I avoid using backfill_previous_messages entirely, and call get_room_messages manually so I don't mess anything up.

mirukana added a commit to mirukana/matrix-python-sdk that referenced this pull request Jan 9, 2019
When loading new events, Client resets Room.prev_batch
matrix-org#284 (comment)
mirukana added a commit to mirukana/matrix-python-sdk that referenced this pull request Jan 9, 2019
When loading new events, Client resets Room.prev_batch
matrix-org#284 (comment)
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@mattthias@Zil0@remram44
, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); Fix missing update of start_token while backfill prev messages by mattthias · Pull Request #284 · matrix-org/matrix-python-sdk · GitHub
Skip to content

Fix missing update of start_token while backfill prev messages - #284

Open
mattthias wants to merge 1 commit into
matrix-org:masterfrom
mattthias:fix_repeated_history
Open

Fix missing update of start_token while backfill prev messages#284
mattthias wants to merge 1 commit into
matrix-org:masterfrom
mattthias:fix_repeated_history

Conversation

@mattthias

Copy link
Copy Markdown

Hello,

while writing a script that should parse the whole channel history i wondered why i always got the same messages when i called backfill_previous_messages(). Please see the example code which i run with a room that just contains 30 messages (message 1 ... message 30).

>>>frommatrix_client.clientimportMatrixClient>>>client=MatrixClient("https://synapse-server")
>>>token=client.login_with_password(username="mattthias", password="guesswhat")
>>>room=client.join_room("#matrixtest:synapse-server")
>>>print(room.events)
[]
>>>room.backfill_previous_messages()
>>>foreventinroom.events:
... print(event['content'])
... {'body': 'Message 21', 'msgtype': 'm.text'}
{'body': 'Message 22', 'msgtype': 'm.text'}
{'body': 'Message 25', 'msgtype': 'm.text'}
{'body': 'Message 26', 'msgtype': 'm.text'}
{'body': 'Message 23', 'msgtype': 'm.text'}
{'body': 'Message 27', 'msgtype': 'm.text'}
{'body': 'Message 24', 'msgtype': 'm.text'}
{'body': 'Message 28', 'msgtype': 'm.text'}
{'body': 'Message 29', 'msgtype': 'm.text'}
{'body': 'Message 30', 'msgtype': 'm.text'}
>>>room.backfill_previous_messages()
>>>len(room.events)
20>>>foreventinroom.events:
... print(event['content'])
... {'body': 'Message 21', 'msgtype': 'm.text'}
{'body': 'Message 22', 'msgtype': 'm.text'}
{'body': 'Message 25', 'msgtype': 'm.text'}
{'body': 'Message 26', 'msgtype': 'm.text'}
{'body': 'Message 23', 'msgtype': 'm.text'}
{'body': 'Message 27', 'msgtype': 'm.text'}
{'body': 'Message 24', 'msgtype': 'm.text'}
{'body': 'Message 28', 'msgtype': 'm.text'}
{'body': 'Message 29', 'msgtype': 'm.text'}
{'body': 'Message 30', 'msgtype': 'm.text'}
{'body': 'Message 21', 'msgtype': 'm.text'}
{'body': 'Message 22', 'msgtype': 'm.text'}
{'body': 'Message 25', 'msgtype': 'm.text'}
{'body': 'Message 26', 'msgtype': 'm.text'}
{'body': 'Message 23', 'msgtype': 'm.text'}
{'body': 'Message 27', 'msgtype': 'm.text'}
{'body': 'Message 24', 'msgtype': 'm.text'}
{'body': 'Message 28', 'msgtype': 'm.text'}
{'body': 'Message 29', 'msgtype': 'm.text'}
{'body': 'Message 30', 'msgtype': 'm.text'}
>>>

The function backfill_previous_messages() updates the room's event list
(room.events) using the api function "client.api.get_room_messages". The
latter function takes a start token as parameter to know from where in
the history of events to start.

backfill_previous_messages() handes over self.prev_batch as start token
but never updates it. So repeated calls to backfill_previous_messages()
always return the same chunk of events from the room's event history.

This commit fixes this wrong behavior by updating self.prev_batch on
every function call.

Signed-off-by: Matthias Schmitz matthias@sigxcpu.org

The function backfill_previous_messages() updates the room's event list
(room.events) using the api function "client.api.get_room_messages". The
latter function takes a start token as parameter to know from where in
the history of events to start.
backfill_previous_messages() handes over self.prev_batch as start token
but never updates it. So repeated calls to backfill_previous_messages()
always return the same chunk of events from the room's event history.
This commit fixes this wrong behavior by updating self.prev_batch on
every function call.
Signed-off-by: Matthias Schmitz <matthias@sigxcpu.org>
@Zil0

Zil0 commented Oct 8, 2018

Copy link
Copy Markdown
Contributor

Thanks for looking at this! It already came up that this behavior needs fixing.

This is trickier than it seems though, since to me it looks like the update of prev_batch that is done here is not consistent with the one done in client.py. Before, prev_batch was the point before the last messages we received in the last sync. With this, prev_batch can be either that, or any previous token depending on how many times backfilling was done.

There is a very basic case were an issue arises in an obvious way:

  • The client is listening for events in a thread T2 (eg start_listener_thread was called).
  • We operate in main thread T1, and we backfill. prev_batch gets updated.
  • A new event comes up, prev_batch gets updated.
  • We backfill again. Backfilling still exhibits the broken behavior you underlined.

I'm not 100% sure what is the proper fix. My intuition is that the prev_batch returned when backfilling shouldn't end up in the room state, but handed back to the user, and that a way to provide it to backfill_previous_messages should exist in order to retrieve even earlier messages. Possibly via an optional argument, which would default to the token obtained via sync if not present.

Feel free to try different approaches, I'm really interested in seeing this part of the SDK improved :)

@remram44

Copy link
Copy Markdown

I agree that backfilling should be completely independent. It shouldn't affect the sync state, but it probably shouldn't be calling the listeners either, since otherwise the listeners get events out-of-order. Worse, there is no way to distinguish a new message from the ones you get from the backfill request.

Currently, I avoid using backfill_previous_messages entirely, and call get_room_messages manually so I don't mess anything up.

mirukana added a commit to mirukana/matrix-python-sdk that referenced this pull request Jan 9, 2019
When loading new events, Client resets Room.prev_batch
matrix-org#284 (comment)
mirukana added a commit to mirukana/matrix-python-sdk that referenced this pull request Jan 9, 2019
When loading new events, Client resets Room.prev_batch
matrix-org#284 (comment)
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@mattthias@Zil0@remram44