From 679b0779f4744b6ff0a95b58f30d769ae5045a92 Mon Sep 17 00:00:00 2001
From: Jorrit Schaap <schaap@astron.nl>
Date: Thu, 14 Jul 2022 15:39:48 +0200
Subject: [PATCH] TMSS-1912: use fast usjon serializer for all json responses

---
 Docker/lofar-ci/Dockerfile_ci_scu        |  2 +-
 SAS/TMSS/backend/src/tmss/CMakeLists.txt |  1 +
 SAS/TMSS/backend/src/tmss/renderers.py   | 27 ++++++++++++++++++++++++
 SAS/TMSS/backend/src/tmss/settings.py    |  5 +++++
 4 files changed, 34 insertions(+), 1 deletion(-)
 create mode 100644 SAS/TMSS/backend/src/tmss/renderers.py

diff --git a/Docker/lofar-ci/Dockerfile_ci_scu b/Docker/lofar-ci/Dockerfile_ci_scu
index 5779b5efc49..21b693d8012 100644
--- a/Docker/lofar-ci/Dockerfile_ci_scu
+++ b/Docker/lofar-ci/Dockerfile_ci_scu
@@ -27,7 +27,7 @@ RUN mkdir -p /opt/oracle && \
     unzip instantclient-basic-linux.x64-21.1.0.0.0.zip
 ENV LD_LIBRARY_PATH /opt/oracle/instantclient_21_1:$LD_LIBRARY_PATH
 
-RUN pip3 install cython kombu lxml requests pygcn xmljson mysql-connector-python python-dateutil Django==3.0.9 djangorestframework==3.11.1 djangorestframework-xml ldap==1.0.2 flask fabric coverage python-qpid-proton PyGreSQL numpy h5py psycopg2 testing.postgresql Flask-Testing scipy Markdown django-filter python-ldap python-ldap-test ldap3 django-jsonforms django-json-widget django-jsoneditor drf-yasg flex swagger-spec-validator django-auth-ldap mozilla-django-oidc jsonschema comet pyxb==1.2.5 graphviz isodate astropy packaging django-debug-toolbar pymysql astroplan SimpleWebSocketServer websocket_client drf-flex-fields django-property-filter cx_Oracle cachetools gunicorn gevent
+RUN pip3 install cython kombu lxml requests pygcn xmljson mysql-connector-python python-dateutil Django==3.0.9 djangorestframework==3.11.1 djangorestframework-xml ldap==1.0.2 flask fabric coverage python-qpid-proton PyGreSQL numpy h5py psycopg2 testing.postgresql Flask-Testing scipy Markdown django-filter python-ldap python-ldap-test ldap3 django-jsonforms django-json-widget django-jsoneditor drf-yasg flex swagger-spec-validator django-auth-ldap mozilla-django-oidc jsonschema comet pyxb==1.2.5 graphviz isodate astropy packaging django-debug-toolbar pymysql astroplan SimpleWebSocketServer websocket_client drf-flex-fields django-property-filter cx_Oracle cachetools gunicorn gevent ujson
 
 #Viewflow package 
 RUN pip3 install django-material django-viewflow
diff --git a/SAS/TMSS/backend/src/tmss/CMakeLists.txt b/SAS/TMSS/backend/src/tmss/CMakeLists.txt
index eff8df62cd8..7f639e654a3 100644
--- a/SAS/TMSS/backend/src/tmss/CMakeLists.txt
+++ b/SAS/TMSS/backend/src/tmss/CMakeLists.txt
@@ -6,6 +6,7 @@ set(_py_files
     settings.py
     urls.py
     wsgi.py
+    renderers.py
     exceptions.py
     authentication_backends.py
     )
diff --git a/SAS/TMSS/backend/src/tmss/renderers.py b/SAS/TMSS/backend/src/tmss/renderers.py
new file mode 100644
index 00000000000..414e2c59603
--- /dev/null
+++ b/SAS/TMSS/backend/src/tmss/renderers.py
@@ -0,0 +1,27 @@
+from rest_framework.renderers import JSONRenderer, SHORT_SEPARATORS, LONG_SEPARATORS, JSONRenderer
+import ujson
+
+class UJSONRenderer(JSONRenderer):
+    """
+    Faster version of plain drf JSONRenderer using ujson
+    """
+    def render(self, data, accepted_media_type=None, renderer_context=None):
+        """
+        Render `data` into JSON, returning a bytestring.
+        """
+        if data is None:
+            return b''
+
+        renderer_context = renderer_context or {}
+        indent = self.get_indent(accepted_media_type, renderer_context)
+
+        ret = ujson.dumps(data,
+                          indent=indent or 0,
+                          ensure_ascii=self.ensure_ascii,
+                          escape_forward_slashes=False)
+
+        # For speed reasons we do not replace \u2028 and \u2029,
+        # as we hardly encounter them and there is a severe speed penalty in replacing them.
+        # See remarks in super().render
+
+        return ret.encode()
diff --git a/SAS/TMSS/backend/src/tmss/settings.py b/SAS/TMSS/backend/src/tmss/settings.py
index 1e82d9921df..5ea8982af87 100644
--- a/SAS/TMSS/backend/src/tmss/settings.py
+++ b/SAS/TMSS/backend/src/tmss/settings.py
@@ -211,6 +211,11 @@ REST_FRAMEWORK = {
     'DEFAULT_PERMISSION_CLASSES': [],
     'PAGE_SIZE': 50,
     'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination',
+    'DEFAULT_RENDERER_CLASSES': (
+        # we use our own faster ujson serializer
+        'lofar.sas.tmss.tmss.renderers.UJSONRenderer',
+        'rest_framework.renderers.BrowsableAPIRenderer',
+    ),
     'DEFAULT_FILTER_BACKENDS': (
         # allows ?field=value filtering in URLs
         # (fields allowed for filtering must be annotated in viewsets using filter_fields = ('field', ...))
-- 
GitLab