mirror of
				https://github.com/matrix-org/synapse.git
				synced 2025-11-04 02:01:03 +01:00 
			
		
		
		
	Merge pull request #1923 from matrix-org/erikj/push_action_compress
Store the default push actions in a more efficient manner
This commit is contained in:
		
						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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user