Merge pull request #1923 from matrix-org/erikj/push_action_compress
Store the default push actions in a more efficient mannerpull/1925/head
commit
b6557f2cfe
|
@ -26,6 +26,42 @@ import ujson as json
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
DEFAULT_NOTIF_ACTION = ["notify", {"set_tweak": "highlight", "value": False}]
|
||||||
|
DEFAULT_HIGHLIGHT_ACTION = [
|
||||||
|
"notify", {"set_tweak": "sound", "value": "default"}, {"set_tweak": "highlight"}
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def _serialize_action(actions, is_highlight):
|
||||||
|
"""Custom serializer for actions. This allows us to "compress" common actions.
|
||||||
|
|
||||||
|
We use the fact that most users have the same actions for notifs (and for
|
||||||
|
highlights).
|
||||||
|
We store these default actions as the empty string rather than the full JSON.
|
||||||
|
Since the empty string isn't valid JSON there is no risk of this clashing with
|
||||||
|
any real JSON actions
|
||||||
|
"""
|
||||||
|
if is_highlight:
|
||||||
|
if actions == DEFAULT_HIGHLIGHT_ACTION:
|
||||||
|
return "" # We use empty string as the column is non-NULL
|
||||||
|
else:
|
||||||
|
if actions == DEFAULT_NOTIF_ACTION:
|
||||||
|
return ""
|
||||||
|
return json.dumps(actions)
|
||||||
|
|
||||||
|
|
||||||
|
def _deserialize_action(actions, is_highlight):
|
||||||
|
"""Custom deserializer for actions. This allows us to "compress" common actions
|
||||||
|
"""
|
||||||
|
if actions:
|
||||||
|
return json.loads(actions)
|
||||||
|
|
||||||
|
if is_highlight:
|
||||||
|
return DEFAULT_HIGHLIGHT_ACTION
|
||||||
|
else:
|
||||||
|
return DEFAULT_NOTIF_ACTION
|
||||||
|
|
||||||
|
|
||||||
class EventPushActionsStore(SQLBaseStore):
|
class EventPushActionsStore(SQLBaseStore):
|
||||||
EPA_HIGHLIGHT_INDEX = "epa_highlight_index"
|
EPA_HIGHLIGHT_INDEX = "epa_highlight_index"
|
||||||
|
|
||||||
|
@ -58,15 +94,17 @@ class EventPushActionsStore(SQLBaseStore):
|
||||||
"""
|
"""
|
||||||
values = []
|
values = []
|
||||||
for uid, actions in tuples:
|
for uid, actions in tuples:
|
||||||
|
is_highlight = 1 if _action_has_highlight(actions) else 0
|
||||||
|
|
||||||
values.append({
|
values.append({
|
||||||
'room_id': event.room_id,
|
'room_id': event.room_id,
|
||||||
'event_id': event.event_id,
|
'event_id': event.event_id,
|
||||||
'user_id': uid,
|
'user_id': uid,
|
||||||
'actions': json.dumps(actions),
|
'actions': _serialize_action(actions, is_highlight),
|
||||||
'stream_ordering': event.internal_metadata.stream_ordering,
|
'stream_ordering': event.internal_metadata.stream_ordering,
|
||||||
'topological_ordering': event.depth,
|
'topological_ordering': event.depth,
|
||||||
'notif': 1,
|
'notif': 1,
|
||||||
'highlight': 1 if _action_has_highlight(actions) else 0,
|
'highlight': is_highlight,
|
||||||
})
|
})
|
||||||
|
|
||||||
for uid, __ in tuples:
|
for uid, __ in tuples:
|
||||||
|
@ -202,7 +240,8 @@ class EventPushActionsStore(SQLBaseStore):
|
||||||
# find rooms that have a read receipt in them and return the next
|
# find rooms that have a read receipt in them and return the next
|
||||||
# push actions
|
# push actions
|
||||||
sql = (
|
sql = (
|
||||||
"SELECT ep.event_id, ep.room_id, ep.stream_ordering, ep.actions"
|
"SELECT ep.event_id, ep.room_id, ep.stream_ordering, ep.actions,"
|
||||||
|
" ep.highlight "
|
||||||
" FROM ("
|
" FROM ("
|
||||||
" SELECT room_id,"
|
" SELECT room_id,"
|
||||||
" MAX(topological_ordering) as topological_ordering,"
|
" MAX(topological_ordering) as topological_ordering,"
|
||||||
|
@ -243,7 +282,7 @@ class EventPushActionsStore(SQLBaseStore):
|
||||||
def get_no_receipt(txn):
|
def get_no_receipt(txn):
|
||||||
sql = (
|
sql = (
|
||||||
"SELECT ep.event_id, ep.room_id, ep.stream_ordering, ep.actions,"
|
"SELECT ep.event_id, ep.room_id, ep.stream_ordering, ep.actions,"
|
||||||
" e.received_ts"
|
" ep.highlight "
|
||||||
" FROM event_push_actions AS ep"
|
" FROM event_push_actions AS ep"
|
||||||
" INNER JOIN events AS e USING (room_id, event_id)"
|
" INNER JOIN events AS e USING (room_id, event_id)"
|
||||||
" WHERE"
|
" WHERE"
|
||||||
|
@ -272,7 +311,7 @@ class EventPushActionsStore(SQLBaseStore):
|
||||||
"event_id": row[0],
|
"event_id": row[0],
|
||||||
"room_id": row[1],
|
"room_id": row[1],
|
||||||
"stream_ordering": row[2],
|
"stream_ordering": row[2],
|
||||||
"actions": json.loads(row[3]),
|
"actions": _deserialize_action(row[3], row[4]),
|
||||||
} for row in after_read_receipt + no_read_receipt
|
} for row in after_read_receipt + no_read_receipt
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -311,7 +350,7 @@ class EventPushActionsStore(SQLBaseStore):
|
||||||
def get_after_receipt(txn):
|
def get_after_receipt(txn):
|
||||||
sql = (
|
sql = (
|
||||||
"SELECT ep.event_id, ep.room_id, ep.stream_ordering, ep.actions,"
|
"SELECT ep.event_id, ep.room_id, ep.stream_ordering, ep.actions,"
|
||||||
" e.received_ts"
|
" ep.highlight, e.received_ts"
|
||||||
" FROM ("
|
" FROM ("
|
||||||
" SELECT room_id,"
|
" SELECT room_id,"
|
||||||
" MAX(topological_ordering) as topological_ordering,"
|
" MAX(topological_ordering) as topological_ordering,"
|
||||||
|
@ -353,7 +392,7 @@ class EventPushActionsStore(SQLBaseStore):
|
||||||
def get_no_receipt(txn):
|
def get_no_receipt(txn):
|
||||||
sql = (
|
sql = (
|
||||||
"SELECT ep.event_id, ep.room_id, ep.stream_ordering, ep.actions,"
|
"SELECT ep.event_id, ep.room_id, ep.stream_ordering, ep.actions,"
|
||||||
" e.received_ts"
|
" ep.highlight, e.received_ts"
|
||||||
" FROM event_push_actions AS ep"
|
" FROM event_push_actions AS ep"
|
||||||
" INNER JOIN events AS e USING (room_id, event_id)"
|
" INNER JOIN events AS e USING (room_id, event_id)"
|
||||||
" WHERE"
|
" WHERE"
|
||||||
|
@ -383,8 +422,8 @@ class EventPushActionsStore(SQLBaseStore):
|
||||||
"event_id": row[0],
|
"event_id": row[0],
|
||||||
"room_id": row[1],
|
"room_id": row[1],
|
||||||
"stream_ordering": row[2],
|
"stream_ordering": row[2],
|
||||||
"actions": json.loads(row[3]),
|
"actions": _deserialize_action(row[3], row[4]),
|
||||||
"received_ts": row[4],
|
"received_ts": row[5],
|
||||||
} for row in after_read_receipt + no_read_receipt
|
} for row in after_read_receipt + no_read_receipt
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -418,7 +457,7 @@ class EventPushActionsStore(SQLBaseStore):
|
||||||
sql = (
|
sql = (
|
||||||
"SELECT epa.event_id, epa.room_id,"
|
"SELECT epa.event_id, epa.room_id,"
|
||||||
" epa.stream_ordering, epa.topological_ordering,"
|
" epa.stream_ordering, epa.topological_ordering,"
|
||||||
" epa.actions, epa.profile_tag, e.received_ts"
|
" epa.actions, epa.highlight, epa.profile_tag, e.received_ts"
|
||||||
" FROM event_push_actions epa, events e"
|
" FROM event_push_actions epa, events e"
|
||||||
" WHERE epa.event_id = e.event_id"
|
" WHERE epa.event_id = e.event_id"
|
||||||
" AND epa.user_id = ? %s"
|
" AND epa.user_id = ? %s"
|
||||||
|
@ -433,7 +472,7 @@ class EventPushActionsStore(SQLBaseStore):
|
||||||
"get_push_actions_for_user", f
|
"get_push_actions_for_user", f
|
||||||
)
|
)
|
||||||
for pa in push_actions:
|
for pa in push_actions:
|
||||||
pa["actions"] = json.loads(pa["actions"])
|
pa["actions"] = _deserialize_action(pa["actions"], pa["highlight"])
|
||||||
defer.returnValue(push_actions)
|
defer.returnValue(push_actions)
|
||||||
|
|
||||||
@defer.inlineCallbacks
|
@defer.inlineCallbacks
|
||||||
|
|
Loading…
Reference in New Issue