This repository has been archived by the owner on Apr 26, 2024. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Calculate stream_ordering_month_ago correctly on workers #2923
Merged
+85
−80
Merged
Changes from 1 commit
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
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
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,7 +14,7 @@ | |
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
|
||
from ._base import SQLBaseStore | ||
from synapse.storage._base import SQLBaseStore, LoggingTransaction | ||
from twisted.internet import defer | ||
from synapse.util.async import sleep | ||
from synapse.util.caches.descriptors import cachedInlineCallbacks | ||
|
@@ -64,6 +64,27 @@ def _deserialize_action(actions, is_highlight): | |
|
||
|
||
class EventPushActionsWorkerStore(SQLBaseStore): | ||
def __init__(self, db_conn, hs): | ||
super(EventPushActionsWorkerStore, self).__init__(db_conn, hs) | ||
|
||
# These get correctly ste by _find_stream_orderings_for_times_txn | ||
self.stream_ordering_month_ago = 0 | ||
self.stream_ordering_day_ago = 0 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we have code here which appears to expect this to be initialised to None (though I see no evidence of it being intialised at all, so perhaps it was just broken before) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah, may as well set it to |
||
|
||
cur = LoggingTransaction( | ||
db_conn.cursor(), | ||
name="_find_stream_orderings_for_times_txn", | ||
database_engine=self.database_engine, | ||
after_callbacks=[], | ||
final_callbacks=[], | ||
) | ||
self._find_stream_orderings_for_times_txn(cur) | ||
cur.close() | ||
|
||
self.find_stream_orderings_looping_call = self._clock.looping_call( | ||
self._find_stream_orderings_for_times, 10 * 60 * 1000 | ||
) | ||
|
||
@cachedInlineCallbacks(num_args=3, tree=True, max_entries=5000) | ||
def get_unread_event_push_actions_by_room_for_user( | ||
self, room_id, user_id, last_read_event_id | ||
|
@@ -443,6 +464,69 @@ def remove_push_actions_from_staging(self, event_id): | |
desc="remove_push_actions_from_staging", | ||
) | ||
|
||
@defer.inlineCallbacks | ||
def _find_stream_orderings_for_times(self): | ||
yield self.runInteraction( | ||
"_find_stream_orderings_for_times", | ||
self._find_stream_orderings_for_times_txn | ||
) | ||
|
||
def _find_stream_orderings_for_times_txn(self, txn): | ||
logger.info("Searching for stream ordering 1 month ago") | ||
self.stream_ordering_month_ago = self._find_first_stream_ordering_after_ts_txn( | ||
txn, self._clock.time_msec() - 30 * 24 * 60 * 60 * 1000 | ||
) | ||
logger.info( | ||
"Found stream ordering 1 month ago: it's %d", | ||
self.stream_ordering_month_ago | ||
) | ||
logger.info("Searching for stream ordering 1 day ago") | ||
self.stream_ordering_day_ago = self._find_first_stream_ordering_after_ts_txn( | ||
txn, self._clock.time_msec() - 24 * 60 * 60 * 1000 | ||
) | ||
logger.info( | ||
"Found stream ordering 1 day ago: it's %d", | ||
self.stream_ordering_day_ago | ||
) | ||
|
||
def _find_first_stream_ordering_after_ts_txn(self, txn, ts): | ||
""" | ||
Find the stream_ordering of the first event that was received after | ||
a given timestamp. This is relatively slow as there is no index on | ||
received_ts but we can then use this to delete push actions before | ||
this. | ||
|
||
received_ts must necessarily be in the same order as stream_ordering | ||
and stream_ordering is indexed, so we manually binary search using | ||
stream_ordering | ||
""" | ||
txn.execute("SELECT MAX(stream_ordering) FROM events") | ||
max_stream_ordering = txn.fetchone()[0] | ||
|
||
if max_stream_ordering is None: | ||
return 0 | ||
|
||
range_start = 0 | ||
range_end = max_stream_ordering | ||
|
||
sql = ( | ||
"SELECT received_ts FROM events" | ||
" WHERE stream_ordering > ?" | ||
" ORDER BY stream_ordering" | ||
" LIMIT 1" | ||
) | ||
|
||
while range_end - range_start > 1: | ||
middle = int((range_end + range_start) / 2) | ||
txn.execute(sql, (middle,)) | ||
middle_ts = txn.fetchone()[0] | ||
if ts > middle_ts: | ||
range_start = middle | ||
else: | ||
range_end = middle | ||
|
||
return range_end | ||
|
||
|
||
class EventPushActionsStore(EventPushActionsWorkerStore): | ||
EPA_HIGHLIGHT_INDEX = "epa_highlight_index" | ||
|
@@ -650,69 +734,6 @@ def _remove_old_push_actions_before_txn(self, txn, room_id, user_id, | |
WHERE room_id = ? AND user_id = ? AND stream_ordering <= ? | ||
""", (room_id, user_id, stream_ordering)) | ||
|
||
@defer.inlineCallbacks | ||
def _find_stream_orderings_for_times(self): | ||
yield self.runInteraction( | ||
"_find_stream_orderings_for_times", | ||
self._find_stream_orderings_for_times_txn | ||
) | ||
|
||
def _find_stream_orderings_for_times_txn(self, txn): | ||
logger.info("Searching for stream ordering 1 month ago") | ||
self.stream_ordering_month_ago = self._find_first_stream_ordering_after_ts_txn( | ||
txn, self._clock.time_msec() - 30 * 24 * 60 * 60 * 1000 | ||
) | ||
logger.info( | ||
"Found stream ordering 1 month ago: it's %d", | ||
self.stream_ordering_month_ago | ||
) | ||
logger.info("Searching for stream ordering 1 day ago") | ||
self.stream_ordering_day_ago = self._find_first_stream_ordering_after_ts_txn( | ||
txn, self._clock.time_msec() - 24 * 60 * 60 * 1000 | ||
) | ||
logger.info( | ||
"Found stream ordering 1 day ago: it's %d", | ||
self.stream_ordering_day_ago | ||
) | ||
|
||
def _find_first_stream_ordering_after_ts_txn(self, txn, ts): | ||
""" | ||
Find the stream_ordering of the first event that was received after | ||
a given timestamp. This is relatively slow as there is no index on | ||
received_ts but we can then use this to delete push actions before | ||
this. | ||
|
||
received_ts must necessarily be in the same order as stream_ordering | ||
and stream_ordering is indexed, so we manually binary search using | ||
stream_ordering | ||
""" | ||
txn.execute("SELECT MAX(stream_ordering) FROM events") | ||
max_stream_ordering = txn.fetchone()[0] | ||
|
||
if max_stream_ordering is None: | ||
return 0 | ||
|
||
range_start = 0 | ||
range_end = max_stream_ordering | ||
|
||
sql = ( | ||
"SELECT received_ts FROM events" | ||
" WHERE stream_ordering > ?" | ||
" ORDER BY stream_ordering" | ||
" LIMIT 1" | ||
) | ||
|
||
while range_end - range_start > 1: | ||
middle = int((range_end + range_start) / 2) | ||
txn.execute(sql, (middle,)) | ||
middle_ts = txn.fetchone()[0] | ||
if ts > middle_ts: | ||
range_start = middle | ||
else: | ||
range_end = middle | ||
|
||
return range_end | ||
|
||
@defer.inlineCallbacks | ||
def _rotate_notifs(self): | ||
if self._doing_notif_rotation or self.stream_ordering_day_ago is None: | ||
|
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ste