forked from MirrorHub/synapse
Merge pull request #1095 from matrix-org/erikj/batch_edus
Clobber EDUs in send queue
This commit is contained in:
commit
555460ae1b
5 changed files with 60 additions and 20 deletions
|
@ -122,8 +122,12 @@ class FederationClient(FederationBase):
|
|||
pdu.event_id
|
||||
)
|
||||
|
||||
def send_presence(self, destination, states):
|
||||
if destination != self.server_name:
|
||||
self._transaction_queue.enqueue_presence(destination, states)
|
||||
|
||||
@log_function
|
||||
def send_edu(self, destination, edu_type, content):
|
||||
def send_edu(self, destination, edu_type, content, key=None):
|
||||
edu = Edu(
|
||||
origin=self.server_name,
|
||||
destination=destination,
|
||||
|
@ -134,7 +138,7 @@ class FederationClient(FederationBase):
|
|||
sent_edus_counter.inc()
|
||||
|
||||
# TODO, add errback, etc.
|
||||
self._transaction_queue.enqueue_edu(edu)
|
||||
self._transaction_queue.enqueue_edu(edu, key=key)
|
||||
return defer.succeed(None)
|
||||
|
||||
@log_function
|
||||
|
|
|
@ -26,6 +26,7 @@ from synapse.util.retryutils import (
|
|||
get_retry_limiter, NotRetryingDestination,
|
||||
)
|
||||
from synapse.util.metrics import measure_func
|
||||
from synapse.handlers.presence import format_user_presence_state
|
||||
import synapse.metrics
|
||||
|
||||
import logging
|
||||
|
@ -69,13 +70,21 @@ class TransactionQueue(object):
|
|||
# destination -> list of tuple(edu, deferred)
|
||||
self.pending_edus_by_dest = edus = {}
|
||||
|
||||
# Presence needs to be separate as we send single aggragate EDUs
|
||||
self.pending_presence_by_dest = presence = {}
|
||||
self.pending_edus_keyed_by_dest = edus_keyed = {}
|
||||
|
||||
metrics.register_callback(
|
||||
"pending_pdus",
|
||||
lambda: sum(map(len, pdus.values())),
|
||||
)
|
||||
metrics.register_callback(
|
||||
"pending_edus",
|
||||
lambda: sum(map(len, edus.values())),
|
||||
lambda: (
|
||||
sum(map(len, edus.values()))
|
||||
+ sum(map(len, presence.values()))
|
||||
+ sum(map(len, edus_keyed.values()))
|
||||
),
|
||||
)
|
||||
|
||||
# destination -> list of tuple(failure, deferred)
|
||||
|
@ -130,13 +139,27 @@ class TransactionQueue(object):
|
|||
self._attempt_new_transaction, destination
|
||||
)
|
||||
|
||||
def enqueue_edu(self, edu):
|
||||
def enqueue_presence(self, destination, states):
|
||||
self.pending_presence_by_dest.setdefault(destination, {}).update({
|
||||
state.user_id: state for state in states
|
||||
})
|
||||
|
||||
preserve_context_over_fn(
|
||||
self._attempt_new_transaction, destination
|
||||
)
|
||||
|
||||
def enqueue_edu(self, edu, key=None):
|
||||
destination = edu.destination
|
||||
|
||||
if not self.can_send_to(destination):
|
||||
return
|
||||
|
||||
self.pending_edus_by_dest.setdefault(destination, []).append(edu)
|
||||
if key:
|
||||
self.pending_edus_keyed_by_dest.setdefault(
|
||||
destination, {}
|
||||
)[(edu.edu_type, key)] = edu
|
||||
else:
|
||||
self.pending_edus_by_dest.setdefault(destination, []).append(edu)
|
||||
|
||||
preserve_context_over_fn(
|
||||
self._attempt_new_transaction, destination
|
||||
|
@ -190,8 +213,13 @@ class TransactionQueue(object):
|
|||
while True:
|
||||
pending_pdus = self.pending_pdus_by_dest.pop(destination, [])
|
||||
pending_edus = self.pending_edus_by_dest.pop(destination, [])
|
||||
pending_presence = self.pending_presence_by_dest.pop(destination, {})
|
||||
pending_failures = self.pending_failures_by_dest.pop(destination, [])
|
||||
|
||||
pending_edus.extend(
|
||||
self.pending_edus_keyed_by_dest.pop(destination, {}).values()
|
||||
)
|
||||
|
||||
limiter = yield get_retry_limiter(
|
||||
destination,
|
||||
self.clock,
|
||||
|
@ -203,6 +231,22 @@ class TransactionQueue(object):
|
|||
)
|
||||
|
||||
pending_edus.extend(device_message_edus)
|
||||
if pending_presence:
|
||||
pending_edus.append(
|
||||
Edu(
|
||||
origin=self.server_name,
|
||||
destination=destination,
|
||||
edu_type="m.presence",
|
||||
content={
|
||||
"push": [
|
||||
format_user_presence_state(
|
||||
presence, self.clock.time_msec()
|
||||
)
|
||||
for presence in pending_presence.values()
|
||||
]
|
||||
},
|
||||
)
|
||||
)
|
||||
|
||||
if pending_pdus:
|
||||
logger.debug("TX [%s] len(pending_pdus_by_dest[dest]) = %d",
|
||||
|
|
|
@ -625,18 +625,8 @@ class PresenceHandler(object):
|
|||
Args:
|
||||
hosts_to_states (dict): Mapping `server_name` -> `[UserPresenceState]`
|
||||
"""
|
||||
now = self.clock.time_msec()
|
||||
for host, states in hosts_to_states.items():
|
||||
self.federation.send_edu(
|
||||
destination=host,
|
||||
edu_type="m.presence",
|
||||
content={
|
||||
"push": [
|
||||
_format_user_presence_state(state, now)
|
||||
for state in states
|
||||
]
|
||||
}
|
||||
)
|
||||
self.federation.send_presence(host, states)
|
||||
|
||||
@defer.inlineCallbacks
|
||||
def incoming_presence(self, origin, content):
|
||||
|
@ -723,13 +713,13 @@ class PresenceHandler(object):
|
|||
defer.returnValue([
|
||||
{
|
||||
"type": "m.presence",
|
||||
"content": _format_user_presence_state(state, now),
|
||||
"content": format_user_presence_state(state, now),
|
||||
}
|
||||
for state in updates
|
||||
])
|
||||
else:
|
||||
defer.returnValue([
|
||||
_format_user_presence_state(state, now) for state in updates
|
||||
format_user_presence_state(state, now) for state in updates
|
||||
])
|
||||
|
||||
@defer.inlineCallbacks
|
||||
|
@ -988,7 +978,7 @@ def should_notify(old_state, new_state):
|
|||
return False
|
||||
|
||||
|
||||
def _format_user_presence_state(state, now):
|
||||
def format_user_presence_state(state, now):
|
||||
"""Convert UserPresenceState to a format that can be sent down to clients
|
||||
and to other servers.
|
||||
"""
|
||||
|
@ -1101,7 +1091,7 @@ class PresenceEventSource(object):
|
|||
defer.returnValue(([
|
||||
{
|
||||
"type": "m.presence",
|
||||
"content": _format_user_presence_state(s, now),
|
||||
"content": format_user_presence_state(s, now),
|
||||
}
|
||||
for s in updates.values()
|
||||
if include_offline or s.state != PresenceState.OFFLINE
|
||||
|
|
|
@ -156,6 +156,7 @@ class ReceiptsHandler(BaseHandler):
|
|||
}
|
||||
},
|
||||
},
|
||||
key=(room_id, receipt_type, user_id),
|
||||
)
|
||||
|
||||
@defer.inlineCallbacks
|
||||
|
|
|
@ -187,6 +187,7 @@ class TypingHandler(object):
|
|||
"user_id": user_id,
|
||||
"typing": typing,
|
||||
},
|
||||
key=(room_id, user_id),
|
||||
))
|
||||
|
||||
yield preserve_context_over_deferred(
|
||||
|
|
Loading…
Reference in a new issue