From b3e45165e62d0f03a03959ee0d15101b940c58d0 Mon Sep 17 00:00:00 2001 From: David Vo Date: Wed, 22 Jul 2020 16:50:49 +1000 Subject: [PATCH 01/12] Reduce unnecessary whitespace in JSON responses --- synapse/http/server.py | 5 +++-- synapse/util/__init__.py | 3 +++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/synapse/http/server.py b/synapse/http/server.py index 8e003689c4d8..06478c78807e 100644 --- a/synapse/http/server.py +++ b/synapse/http/server.py @@ -25,7 +25,7 @@ from typing import Any, Callable, Dict, Tuple, Union import jinja2 -from canonicaljson import encode_canonical_json, encode_pretty_printed_json, json +from canonicaljson import encode_canonical_json, encode_pretty_printed_json from twisted.internet import defer from twisted.python import failure @@ -46,6 +46,7 @@ from synapse.http.site import SynapseRequest from synapse.logging.context import preserve_fn from synapse.logging.opentracing import trace_servlet +from synapse.util import json_encoder from synapse.util.caches import intern_dict logger = logging.getLogger(__name__) @@ -546,7 +547,7 @@ def respond_with_json( # canonicaljson already encodes to bytes json_bytes = encode_canonical_json(json_object) else: - json_bytes = json.dumps(json_object).encode("utf-8") + json_bytes = json_encoder.encode(json_object).encode("utf-8") return respond_with_json_bytes(request, code, json_bytes, send_cors=send_cors) diff --git a/synapse/util/__init__.py b/synapse/util/__init__.py index c63256d3bd04..9c598148e5d8 100644 --- a/synapse/util/__init__.py +++ b/synapse/util/__init__.py @@ -18,12 +18,15 @@ import attr +from canonicaljson import json from twisted.internet import defer, task from synapse.logging import context logger = logging.getLogger(__name__) +json_encoder = json.JSONEncoder(separators=(",", ":")) + def unwrapFirstError(failure): # defer.gatherResults and DeferredLists wrap failures. From 7ca45aba0e5c494819a6bd156ce102848e46dc6b Mon Sep 17 00:00:00 2001 From: David Vo Date: Wed, 29 Apr 2020 00:09:47 +1000 Subject: [PATCH 02/12] Reduce unnecessary whitespace stored for events --- synapse/util/frozenutils.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/synapse/util/frozenutils.py b/synapse/util/frozenutils.py index eab78dd2567f..06e50113170f 100644 --- a/synapse/util/frozenutils.py +++ b/synapse/util/frozenutils.py @@ -64,4 +64,6 @@ def _handle_frozendict(obj): # A JSONEncoder which is capable of encoding frozendicts without barfing -frozendict_json_encoder = json.JSONEncoder(default=_handle_frozendict) +frozendict_json_encoder = json.JSONEncoder( + default=_handle_frozendict, separators=(",", ":"), +) From 87025ef7300ed2c790271c7ec8873b2877f04bfb Mon Sep 17 00:00:00 2001 From: David Vo Date: Wed, 22 Jul 2020 16:54:08 +1000 Subject: [PATCH 03/12] Remove unnecessary JSON whitespace stored for RRs --- synapse/storage/data_stores/main/receipts.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/synapse/storage/data_stores/main/receipts.py b/synapse/storage/data_stores/main/receipts.py index 1d723f2d347e..a40dd0c64797 100644 --- a/synapse/storage/data_stores/main/receipts.py +++ b/synapse/storage/data_stores/main/receipts.py @@ -18,13 +18,12 @@ import logging from typing import List, Tuple -from canonicaljson import json - from twisted.internet import defer from synapse.storage._base import SQLBaseStore, db_to_json, make_in_list_sql_clause from synapse.storage.database import Database from synapse.storage.util.id_generators import StreamIdGenerator +from synapse.util import json_encoder from synapse.util.async_helpers import ObservableDeferred from synapse.util.caches.descriptors import cached, cachedInlineCallbacks, cachedList from synapse.util.caches.stream_change_cache import StreamChangeCache @@ -457,7 +456,7 @@ def insert_linearized_receipt_txn( values={ "stream_id": stream_id, "event_id": event_id, - "data": json.dumps(data), + "data": json_encoder.encode(data), }, # receipts_linearized has a unique constraint on # (user_id, room_id, receipt_type), so no need to lock @@ -583,7 +582,7 @@ def insert_graph_receipt_txn( "room_id": room_id, "receipt_type": receipt_type, "user_id": user_id, - "event_ids": json.dumps(event_ids), - "data": json.dumps(data), + "event_ids": json_encoder.encode(event_ids), + "data": json_encoder.encode(data), }, ) From 14aa5c49af3940196c83dc22fa562df5e7d2e5c7 Mon Sep 17 00:00:00 2001 From: David Vo Date: Wed, 22 Jul 2020 17:01:15 +1000 Subject: [PATCH 04/12] Reduce unnecessary JSON whitespace stored for E2E --- synapse/storage/data_stores/main/deviceinbox.py | 9 ++++----- synapse/storage/data_stores/main/devices.py | 11 +++++------ synapse/storage/data_stores/main/e2e_room_keys.py | 11 +++++------ synapse/storage/data_stores/main/end_to_end_keys.py | 5 +++-- 4 files changed, 17 insertions(+), 19 deletions(-) diff --git a/synapse/storage/data_stores/main/deviceinbox.py b/synapse/storage/data_stores/main/deviceinbox.py index da297b31fbbe..e8a6a37e4bad 100644 --- a/synapse/storage/data_stores/main/deviceinbox.py +++ b/synapse/storage/data_stores/main/deviceinbox.py @@ -16,13 +16,12 @@ import logging from typing import List, Tuple -from canonicaljson import json - from twisted.internet import defer from synapse.logging.opentracing import log_kv, set_tag, trace from synapse.storage._base import SQLBaseStore, db_to_json, make_in_list_sql_clause from synapse.storage.database import Database +from synapse.util import json_encoder from synapse.util.caches.expiringcache import ExpiringCache logger = logging.getLogger(__name__) @@ -354,7 +353,7 @@ def add_messages_txn(txn, now_ms, stream_id): ) rows = [] for destination, edu in remote_messages_by_destination.items(): - edu_json = json.dumps(edu) + edu_json = json_encoder.encode(edu) rows.append((destination, stream_id, now_ms, edu_json)) txn.executemany(sql, rows) @@ -432,7 +431,7 @@ def _add_messages_to_local_device_inbox_txn( # Handle wildcard device_ids. sql = "SELECT device_id FROM devices WHERE user_id = ?" txn.execute(sql, (user_id,)) - message_json = json.dumps(messages_by_device["*"]) + message_json = json_encoder.encode(messages_by_device["*"]) for row in txn: # Add the message for all devices for this user on this # server. @@ -454,7 +453,7 @@ def _add_messages_to_local_device_inbox_txn( # Only insert into the local inbox if the device exists on # this server device = row[0] - message_json = json.dumps(messages_by_device[device]) + message_json = json_encoder.encode(messages_by_device[device]) messages_json_for_user[device] = message_json if messages_json_for_user: diff --git a/synapse/storage/data_stores/main/devices.py b/synapse/storage/data_stores/main/devices.py index 45581a65004e..880276b0d2f5 100644 --- a/synapse/storage/data_stores/main/devices.py +++ b/synapse/storage/data_stores/main/devices.py @@ -17,8 +17,6 @@ import logging from typing import List, Optional, Set, Tuple -from canonicaljson import json - from twisted.internet import defer from synapse.api.errors import Codes, StoreError @@ -36,6 +34,7 @@ make_tuple_comparison_clause, ) from synapse.types import Collection, get_verify_key_from_cross_signing_key +from synapse.util import json_encoder from synapse.util.caches.descriptors import ( Cache, cached, @@ -397,7 +396,7 @@ def _add_user_signature_change_txn(self, txn, from_user_id, user_ids, stream_id) values={ "stream_id": stream_id, "from_user_id": from_user_id, - "user_ids": json.dumps(user_ids), + "user_ids": json_encoder.encode(user_ids), }, ) @@ -1030,7 +1029,7 @@ def _update_remote_device_list_cache_entry_txn( txn, table="device_lists_remote_cache", keyvalues={"user_id": user_id, "device_id": device_id}, - values={"content": json.dumps(content)}, + values={"content": json_encoder.encode(content)}, # we don't need to lock, because we assume we are the only thread # updating this user's devices. lock=False, @@ -1086,7 +1085,7 @@ def _update_remote_device_list_cache_txn(self, txn, user_id, devices, stream_id) { "user_id": user_id, "device_id": content["device_id"], - "content": json.dumps(content), + "content": json_encoder.encode(content), } for content in devices ], @@ -1207,7 +1206,7 @@ def _add_device_outbound_poke_to_stream_txn( "device_id": device_id, "sent": False, "ts": now, - "opentracing_context": json.dumps(context) + "opentracing_context": json_encoder.encode(context) if whitelisted_homeserver(destination) else "{}", } diff --git a/synapse/storage/data_stores/main/e2e_room_keys.py b/synapse/storage/data_stores/main/e2e_room_keys.py index 615364f01837..240c054398fc 100644 --- a/synapse/storage/data_stores/main/e2e_room_keys.py +++ b/synapse/storage/data_stores/main/e2e_room_keys.py @@ -14,13 +14,12 @@ # See the License for the specific language governing permissions and # limitations under the License. -from canonicaljson import json - from twisted.internet import defer from synapse.api.errors import StoreError from synapse.logging.opentracing import log_kv, trace from synapse.storage._base import SQLBaseStore, db_to_json +from synapse.util import json_encoder class EndToEndRoomKeyStore(SQLBaseStore): @@ -50,7 +49,7 @@ def update_e2e_room_key(self, user_id, version, room_id, session_id, room_key): "first_message_index": room_key["first_message_index"], "forwarded_count": room_key["forwarded_count"], "is_verified": room_key["is_verified"], - "session_data": json.dumps(room_key["session_data"]), + "session_data": json_encoder.encode(room_key["session_data"]), }, desc="update_e2e_room_key", ) @@ -77,7 +76,7 @@ def add_e2e_room_keys(self, user_id, version, room_keys): "first_message_index": room_key["first_message_index"], "forwarded_count": room_key["forwarded_count"], "is_verified": room_key["is_verified"], - "session_data": json.dumps(room_key["session_data"]), + "session_data": json_encoder.encode(room_key["session_data"]), } ) log_kv( @@ -360,7 +359,7 @@ def _create_e2e_room_keys_version_txn(txn): "user_id": user_id, "version": new_version, "algorithm": info["algorithm"], - "auth_data": json.dumps(info["auth_data"]), + "auth_data": json_encoder.encode(info["auth_data"]), }, ) @@ -387,7 +386,7 @@ def update_e2e_room_keys_version( updatevalues = {} if info is not None and "auth_data" in info: - updatevalues["auth_data"] = json.dumps(info["auth_data"]) + updatevalues["auth_data"] = json_encoder.encode(info["auth_data"]) if version_etag is not None: updatevalues["etag"] = version_etag diff --git a/synapse/storage/data_stores/main/end_to_end_keys.py b/synapse/storage/data_stores/main/end_to_end_keys.py index 317c07a8297c..73a616651de3 100644 --- a/synapse/storage/data_stores/main/end_to_end_keys.py +++ b/synapse/storage/data_stores/main/end_to_end_keys.py @@ -16,7 +16,7 @@ # limitations under the License. from typing import Dict, List, Tuple -from canonicaljson import encode_canonical_json, json +from canonicaljson import encode_canonical_json from twisted.enterprise.adbapi import Connection from twisted.internet import defer @@ -24,6 +24,7 @@ from synapse.logging.opentracing import log_kv, set_tag, trace from synapse.storage._base import SQLBaseStore, db_to_json from synapse.storage.database import make_in_list_sql_clause +from synapse.util import json_encoder from synapse.util.caches.descriptors import cached, cachedList from synapse.util.iterutils import batch_iter @@ -698,7 +699,7 @@ def _set_e2e_cross_signing_key_txn(self, txn, user_id, key_type, key): values={ "user_id": user_id, "keytype": key_type, - "keydata": json.dumps(key), + "keydata": json_encoder.encode(key), "stream_id": stream_id, }, ) From 1dd3679fb955972f183a760bdf1d04fca12e0c06 Mon Sep 17 00:00:00 2001 From: David Vo Date: Wed, 22 Jul 2020 17:08:10 +1000 Subject: [PATCH 05/12] Reduce unnecessary JSON whitespace for account data --- synapse/storage/data_stores/main/account_data.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/synapse/storage/data_stores/main/account_data.py b/synapse/storage/data_stores/main/account_data.py index 33cc372dfd7e..d3efcfebb382 100644 --- a/synapse/storage/data_stores/main/account_data.py +++ b/synapse/storage/data_stores/main/account_data.py @@ -18,13 +18,12 @@ import logging from typing import List, Tuple -from canonicaljson import json - from twisted.internet import defer from synapse.storage._base import SQLBaseStore, db_to_json from synapse.storage.database import Database from synapse.storage.util.id_generators import StreamIdGenerator +from synapse.util import json_encoder from synapse.util.caches.descriptors import cached, cachedInlineCallbacks from synapse.util.caches.stream_change_cache import StreamChangeCache @@ -327,7 +326,7 @@ def add_account_data_to_room(self, user_id, room_id, account_data_type, content) Returns: A deferred that completes once the account_data has been added. """ - content_json = json.dumps(content) + content_json = json_encoder.encode(content) with self._account_data_id_gen.get_next() as next_id: # no need to lock here as room_account_data has a unique constraint @@ -373,7 +372,7 @@ def add_account_data_for_user(self, user_id, account_data_type, content): Returns: A deferred that completes once the account_data has been added. """ - content_json = json.dumps(content) + content_json = json_encoder.encode(content) with self._account_data_id_gen.get_next() as next_id: # no need to lock here as account_data has a unique constraint on From c6ceb3864f24aaaef17e484753e7e8a23926b9ba Mon Sep 17 00:00:00 2001 From: David Vo Date: Wed, 22 Jul 2020 17:12:27 +1000 Subject: [PATCH 06/12] Remove unnecessary JSON whitespace stored for push rules --- synapse/storage/data_stores/main/event_push_actions.py | 5 ++--- synapse/storage/data_stores/main/push_rule.py | 9 ++++----- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/synapse/storage/data_stores/main/event_push_actions.py b/synapse/storage/data_stores/main/event_push_actions.py index 504babaa7e18..070cb7d556aa 100644 --- a/synapse/storage/data_stores/main/event_push_actions.py +++ b/synapse/storage/data_stores/main/event_push_actions.py @@ -16,13 +16,12 @@ import logging -from canonicaljson import json - from twisted.internet import defer from synapse.metrics.background_process_metrics import run_as_background_process from synapse.storage._base import LoggingTransaction, SQLBaseStore, db_to_json from synapse.storage.database import Database +from synapse.util import json_encoder from synapse.util.caches.descriptors import cachedInlineCallbacks logger = logging.getLogger(__name__) @@ -51,7 +50,7 @@ def _serialize_action(actions, is_highlight): else: if actions == DEFAULT_NOTIF_ACTION: return "" - return json.dumps(actions) + return json_encoder.encode(actions) def _deserialize_action(actions, is_highlight): diff --git a/synapse/storage/data_stores/main/push_rule.py b/synapse/storage/data_stores/main/push_rule.py index d181488db710..5cc559fbf86c 100644 --- a/synapse/storage/data_stores/main/push_rule.py +++ b/synapse/storage/data_stores/main/push_rule.py @@ -18,8 +18,6 @@ import logging from typing import List, Tuple, Union -from canonicaljson import json - from twisted.internet import defer from synapse.push.baserules import list_with_base_rules @@ -33,6 +31,7 @@ from synapse.storage.database import Database from synapse.storage.push_rule import InconsistentRuleException, RuleNotFoundException from synapse.storage.util.id_generators import ChainedIdGenerator +from synapse.util import json_encoder from synapse.util.caches.descriptors import cachedInlineCallbacks, cachedList from synapse.util.caches.stream_change_cache import StreamChangeCache @@ -411,8 +410,8 @@ def add_push_rule( before=None, after=None, ): - conditions_json = json.dumps(conditions) - actions_json = json.dumps(actions) + conditions_json = json_encoder.encode(conditions) + actions_json = json_encoder.encode(actions) with self._push_rules_stream_id_gen.get_next() as ids: stream_id, event_stream_ordering = ids if before or after: @@ -681,7 +680,7 @@ def _set_push_rule_enabled_txn( @defer.inlineCallbacks def set_push_rule_actions(self, user_id, rule_id, actions, is_default_rule): - actions_json = json.dumps(actions) + actions_json = json_encoder.encode(actions) def set_push_rule_actions_txn(txn, stream_id, event_stream_ordering): if is_default_rule: From 4c5a0d5dde76a12177c9554d1b487f17c9bcc683 Mon Sep 17 00:00:00 2001 From: David Vo Date: Wed, 22 Jul 2020 17:15:05 +1000 Subject: [PATCH 07/12] Remove unnecessary JSON whitespace stored for groups --- .../storage/data_stores/main/group_server.py | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/synapse/storage/data_stores/main/group_server.py b/synapse/storage/data_stores/main/group_server.py index 01ff561e1a61..89f1aa7a663c 100644 --- a/synapse/storage/data_stores/main/group_server.py +++ b/synapse/storage/data_stores/main/group_server.py @@ -16,12 +16,11 @@ from typing import List, Tuple -from canonicaljson import json - from twisted.internet import defer from synapse.api.errors import SynapseError from synapse.storage._base import SQLBaseStore, db_to_json +from synapse.util import json_encoder # The category ID for the "default" category. We don't store as null in the # database to avoid the fun of null != null @@ -750,7 +749,7 @@ def upsert_group_category(self, group_id, category_id, profile, is_public): if profile is None: insertion_values["profile"] = "{}" else: - update_values["profile"] = json.dumps(profile) + update_values["profile"] = json_encoder.encode(profile) if is_public is None: insertion_values["is_public"] = True @@ -781,7 +780,7 @@ def upsert_group_role(self, group_id, role_id, profile, is_public): if profile is None: insertion_values["profile"] = "{}" else: - update_values["profile"] = json.dumps(profile) + update_values["profile"] = json_encoder.encode(profile) if is_public is None: insertion_values["is_public"] = True @@ -1005,7 +1004,7 @@ def _add_user_to_group_txn(txn): "group_id": group_id, "user_id": user_id, "valid_until_ms": remote_attestation["valid_until_ms"], - "attestation_json": json.dumps(remote_attestation), + "attestation_json": json_encoder.encode(remote_attestation), }, ) @@ -1129,7 +1128,7 @@ def _register_user_group_membership_txn(txn, next_id): "is_admin": is_admin, "membership": membership, "is_publicised": is_publicised, - "content": json.dumps(content), + "content": json_encoder.encode(content), }, ) @@ -1141,7 +1140,7 @@ def _register_user_group_membership_txn(txn, next_id): "group_id": group_id, "user_id": user_id, "type": "membership", - "content": json.dumps( + "content": json_encoder.encode( {"membership": membership, "content": content} ), }, @@ -1169,7 +1168,7 @@ def _register_user_group_membership_txn(txn, next_id): "group_id": group_id, "user_id": user_id, "valid_until_ms": remote_attestation["valid_until_ms"], - "attestation_json": json.dumps(remote_attestation), + "attestation_json": json_encoder.encode(remote_attestation), }, ) else: @@ -1238,7 +1237,7 @@ def update_remote_attestion(self, group_id, user_id, attestation): keyvalues={"group_id": group_id, "user_id": user_id}, updatevalues={ "valid_until_ms": attestation["valid_until_ms"], - "attestation_json": json.dumps(attestation), + "attestation_json": json_encoder.encode(attestation), }, desc="update_remote_attestion", ) From c2531d9b69dcdefbb06ae4a1f764d042533f56ec Mon Sep 17 00:00:00 2001 From: David Vo Date: Thu, 30 Apr 2020 16:49:46 +1000 Subject: [PATCH 08/12] Add changelog for squish-json branch Signed-off-by: David Vo --- changelog.d/7372.misc | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/7372.misc diff --git a/changelog.d/7372.misc b/changelog.d/7372.misc new file mode 100644 index 000000000000..67a39f04719b --- /dev/null +++ b/changelog.d/7372.misc @@ -0,0 +1 @@ +Reduce the amount of whitespace in JSON stored and sent in responses. Contributed by David Vo. From 14083b1216e1c735c84006e95eeac91abec6ddbb Mon Sep 17 00:00:00 2001 From: David Vo Date: Wed, 22 Jul 2020 17:23:55 +1000 Subject: [PATCH 09/12] isort --- synapse/util/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/synapse/util/__init__.py b/synapse/util/__init__.py index 9c598148e5d8..6261fb24d244 100644 --- a/synapse/util/__init__.py +++ b/synapse/util/__init__.py @@ -17,8 +17,8 @@ import re import attr - from canonicaljson import json + from twisted.internet import defer, task from synapse.logging import context From b4e170cebf825b3d19718435b3f577b3890f6b41 Mon Sep 17 00:00:00 2001 From: David Vo Date: Fri, 31 Jul 2020 02:20:39 +1000 Subject: [PATCH 10/12] Remove unnecessary JSON whitespace in URL previews --- synapse/rest/media/v1/preview_url_resource.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/synapse/rest/media/v1/preview_url_resource.py b/synapse/rest/media/v1/preview_url_resource.py index e12f65a20649..2be2106c4ba5 100644 --- a/synapse/rest/media/v1/preview_url_resource.py +++ b/synapse/rest/media/v1/preview_url_resource.py @@ -27,7 +27,6 @@ from urllib import parse as urlparse import attr -from canonicaljson import json from twisted.internet import defer from twisted.internet.error import DNSLookupError @@ -43,6 +42,7 @@ from synapse.logging.context import make_deferred_yieldable, run_in_background from synapse.metrics.background_process_metrics import run_as_background_process from synapse.rest.media.v1._base import get_filename_from_headers +from synapse.util import json_encoder from synapse.util.async_helpers import ObservableDeferred from synapse.util.caches.expiringcache import ExpiringCache from synapse.util.stringutils import random_string @@ -355,7 +355,7 @@ async def _do_preview(self, url: str, user: str, ts: int) -> bytes: logger.debug("Calculated OG for %s as %s", url, og) - jsonog = json.dumps(og) + jsonog = json_encoder.encode(og) # store OG in history-aware DB cache await self.store.store_url_cache( From 95ad291040ee132d15380d0c1a0601287376368d Mon Sep 17 00:00:00 2001 From: David Vo Date: Fri, 7 Aug 2020 16:19:11 +1000 Subject: [PATCH 11/12] Add comments about JSONEncoder whitespace Co-authored-by: Patrick Cloke --- synapse/util/__init__.py | 1 + synapse/util/frozenutils.py | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/synapse/util/__init__.py b/synapse/util/__init__.py index 6261fb24d244..b3f76428b65e 100644 --- a/synapse/util/__init__.py +++ b/synapse/util/__init__.py @@ -25,6 +25,7 @@ logger = logging.getLogger(__name__) +# Create a custom encoder to reduce the whitespace produced by JSON encoding. json_encoder = json.JSONEncoder(separators=(",", ":")) diff --git a/synapse/util/frozenutils.py b/synapse/util/frozenutils.py index 06e50113170f..0e445e01d773 100644 --- a/synapse/util/frozenutils.py +++ b/synapse/util/frozenutils.py @@ -63,7 +63,8 @@ def _handle_frozendict(obj): ) -# A JSONEncoder which is capable of encoding frozendicts without barfing +# A JSONEncoder which is capable of encoding frozendicts without barfing. +# Additionally reduce the whitespace produced by JSON encoding. frozendict_json_encoder = json.JSONEncoder( default=_handle_frozendict, separators=(",", ":"), ) From 1a7e15296fd6b2d5a05737389dd8a3102ea4bc8a Mon Sep 17 00:00:00 2001 From: David Vo Date: Fri, 7 Aug 2020 21:33:21 +1000 Subject: [PATCH 12/12] Replace JSON encoder in replication --- synapse/replication/tcp/commands.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/synapse/replication/tcp/commands.py b/synapse/replication/tcp/commands.py index f33801f8838e..d853e4447eb6 100644 --- a/synapse/replication/tcp/commands.py +++ b/synapse/replication/tcp/commands.py @@ -18,11 +18,12 @@ allowed to be sent by which side. """ import abc -import json import logging from typing import Tuple, Type -_json_encoder = json.JSONEncoder() +from canonicaljson import json + +from synapse.util import json_encoder as _json_encoder logger = logging.getLogger(__name__)