Join GitHub today
GitHub is home to over 20 million developers working together to host and review code, manage projects, and build software together.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
Already on GitHub? Sign in to your account
Change pushers to use the event_actions table #705
Conversation
dbkr
added some commits
Apr 6, 2016
dbkr
assigned
erikjohnston
Apr 7, 2016
dbkr
commented on the diff
Apr 7, 2016
dbkr
added some commits
Apr 7, 2016
erikjohnston
commented on an outdated diff
Apr 7, 2016
| +# you may not use this file except in compliance with the License. | ||
| +# You may obtain a copy of the License at | ||
| +# | ||
| +# http://www.apache.org/licenses/LICENSE-2.0 | ||
| +# | ||
| +# Unless required by applicable law or agreed to in writing, software | ||
| +# distributed under the License is distributed on an "AS IS" BASIS, | ||
| +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| +# See the License for the specific language governing permissions and | ||
| +# limitations under the License. | ||
| + | ||
| +from twisted.internet import defer | ||
| + | ||
| + | ||
| +@defer.inlineCallbacks | ||
| +def get_badge_count(hs, user_id): |
erikjohnston
Owner
|
erikjohnston
commented on an outdated diff
Apr 7, 2016
| + | ||
| + for r in joins: | ||
| + if r.room_id in my_receipts_by_room: | ||
| + last_unread_event_id = my_receipts_by_room[r.room_id] | ||
| + | ||
| + notifs = yield ( | ||
| + hs.get_datastore().get_unread_event_push_actions_by_room_for_user( | ||
| + r.room_id, user_id, last_unread_event_id | ||
| + ) | ||
| + ) | ||
| + badge += notifs["notify_count"] | ||
| + defer.returnValue(badge) | ||
| + | ||
| + | ||
| +@defer.inlineCallbacks | ||
| +def get_context_for_event(hs, ev): |
|
|
erikjohnston
commented on an outdated diff
Apr 7, 2016
| ) | ||
| - else: | ||
| - raise PusherConfigException( | ||
| - "Unknown pusher type '%s' for user %s" % | ||
| - (pusherdict['kind'], pusherdict['user_name']) | ||
| + for u in users_affected: | ||
| + if u in self.pushers: | ||
| + for p in self.pushers[u].values(): | ||
| + yield p.on_new_notifications(min_stream_id, max_stream_id) |
erikjohnston
Owner
|
erikjohnston
commented on an outdated diff
Apr 7, 2016
erikjohnston
and 1 other
commented on an outdated diff
Apr 7, 2016
| @@ -100,6 +100,54 @@ def _get_unread_event_push_actions_by_room(txn): | ||
| ) | ||
| defer.returnValue(ret) | ||
| + @defer.inlineCallbacks | ||
| + def get_push_action_users_in_range(self, min_stream_ordering, max_stream_ordering): | ||
| + def f(txn): | ||
| + sql = ( | ||
| + "SELECT DISTINCT(user_id) FROM event_push_actions WHERE" | ||
| + " stream_ordering >= ? AND stream_ordering >= ?" |
erikjohnston
Owner
|
dbkr
added some commits
Apr 7, 2016
erikjohnston
commented on an outdated diff
Apr 7, 2016
| - kind=kind, | ||
| - app_display_name=app_display_name, | ||
| - device_display_name=device_display_name, | ||
| - ts=pushkey_ts, | ||
| - lang=lang, | ||
| - data=encode_canonical_json(data), | ||
| - profile_tag=profile_tag, | ||
| - id=stream_id, | ||
| - ), | ||
| - desc="add_pusher", | ||
| - ) | ||
| + pushkey, pushkey_ts, lang, data, last_stream_ordering, | ||
| + profile_tag=""): | ||
| + def f(txn): | ||
| + txn.call_after(self.get_users_with_pushers_in_room.invalidate_all) | ||
| + with self._pushers_id_gen.get_next() as stream_id: |
|
|
erikjohnston
commented on an outdated diff
Apr 7, 2016
| - lang=lang, | ||
| - data=encode_canonical_json(data), | ||
| - profile_tag=profile_tag, | ||
| - id=stream_id, | ||
| - ), | ||
| - desc="add_pusher", | ||
| - ) | ||
| + pushkey, pushkey_ts, lang, data, last_stream_ordering, | ||
| + profile_tag=""): | ||
| + def f(txn): | ||
| + txn.call_after(self.get_users_with_pushers_in_room.invalidate_all) | ||
| + with self._pushers_id_gen.get_next() as stream_id: | ||
| + return self._simple_upsert_txn( | ||
| + txn, | ||
| + "pushers", | ||
| + dict( |
|
|
erikjohnston
commented on the diff
Apr 7, 2016
| + FROM pushers | ||
| + """) | ||
| + count = 0 | ||
| + for row in cur.fetchall(): | ||
| + row = list(row) | ||
| + row[12] = token_to_stream_ordering(row[12]) | ||
| + cur.execute(database_engine.convert_param_style(""" | ||
| + INSERT into pushers2 ( | ||
| + id, user_name, access_token, profile_tag, kind, | ||
| + app_id, app_display_name, device_display_name, | ||
| + pushkey, ts, lang, data, last_stream_ordering, last_success, | ||
| + failing_since | ||
| + ) values (%s)""" % (','.join(['?' for _ in range(len(row))]))), | ||
| + row | ||
| + ) | ||
| + count += 1 |
erikjohnston
Owner
|
dbkr
added some commits
Apr 7, 2016
erikjohnston
commented on an outdated diff
Apr 8, 2016
| - ctx = yield self.get_context_for_event(event) | ||
| + def on_stop(self): | ||
| + if self.timed_call: | ||
| + self.timed_call.cancel() | ||
| + | ||
| + @defer.inlineCallbacks | ||
| + def _process(self): | ||
| + try: | ||
| + self.processing = True | ||
| + yield self._unsafe_process() | ||
| + finally: | ||
| + self.processing = False | ||
| + | ||
| + @defer.inlineCallbacks | ||
| + def _unsafe_process(self): | ||
| + unprocessed = yield self.store.get_unread_push_actions_for_user_in_range( |
erikjohnston
Owner
|
erikjohnston
commented on an outdated diff
Apr 8, 2016
| self.data_minus_url = {} | ||
| self.data_minus_url.update(self.data) | ||
| del self.data_minus_url['url'] | ||
| @defer.inlineCallbacks | ||
| - def _build_notification_dict(self, event, tweaks, badge): | ||
| - # we probably do not want to push for every presence update | ||
| - # (we may want to be able to set up notifications when specific | ||
| - # people sign in, but we'd want to only deliver the pertinent ones) | ||
| - # Actually, presence events will not get this far now because we | ||
| - # need to filter them out in the main Pusher code. | ||
| - if 'event_id' not in event: | ||
| - defer.returnValue(None) | ||
| + def on_started(self): | ||
| + yield self._process() | ||
| + | ||
| + @defer.inlineCallbacks | ||
| + def on_new_notifications(self, min_stream_ordering, max_stream_ordering): | ||
| + with Measure(self.clock, "push.on_new_notifications"): | ||
| + self.max_stream_ordering = max_stream_ordering |
|
|
dbkr
added some commits
Apr 8, 2016
dbkr
referenced this pull request
in matrix-org/sytest
Apr 8, 2016
Merged
Test unread counts in pushes #224
|
I've also fixed broken invite pushing and added a test for it: https://github.com/matrix-org/sytest/compare/dbkr/test_invites_pushed ptal |
erikjohnston
and 1 other
commented on an outdated diff
Apr 8, 2016
| - ctx = yield self.get_context_for_event(event) | ||
| + def on_stop(self): | ||
| + if self.timed_call: | ||
| + self.timed_call.cancel() | ||
| + | ||
| + @defer.inlineCallbacks | ||
| + def _process(self): | ||
| + if self.processing: | ||
| + return | ||
| + try: | ||
| + self.processing = True | ||
| + yield self._unsafe_process() | ||
| + finally: | ||
| + self.processing = False |
erikjohnston
Owner
|
erikjohnston
and 1 other
commented on an outdated diff
Apr 11, 2016
| + ) | ||
| + | ||
| + self.failing_since = None | ||
| + yield self.store.update_pusher_failing_since( | ||
| + self.app_id, | ||
| + self.pushkey, | ||
| + self.user_id, | ||
| + self.failing_since | ||
| + ) | ||
| + else: | ||
| + logger.info("Push failed: delaying for %ds", self.backoff_delay) | ||
| + self.timed_call = reactor.callLater(self.backoff_delay, self.on_timer) | ||
| + self.backoff_delay = min(self.backoff_delay * 2, self.MAX_BACKOFF_SEC) | ||
| + break | ||
| + if self.max_stream_ordering != starting_max_ordering: | ||
| + self._unsafe_process() |
dbkr
Member
|
|
LGTM |
dbkr commentedApr 7, 2016
Makes pushers no longer run as separate things that each listen on an event stream. They now have hooks that are called from points in message / receipt sending code where they go and query the event_push_actions table for new notifications.
This will completely eliminate the runtime used by the old style pushers, but done mostly to make way for doing email notifications in the same way.