Skip to content

Commit

Permalink
In-memory caching JWT decode/serialization
Browse files Browse the repository at this point in the history
  • Loading branch information
judtinzhang committed Apr 25, 2024
1 parent 01e373a commit 037d29b
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 14 deletions.
30 changes: 23 additions & 7 deletions analytics/analytics.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import json
import time
from concurrent.futures import ThreadPoolExecutor
from enum import IntEnum
from typing import Optional
Expand Down Expand Up @@ -65,17 +66,32 @@ def __new__(cls, *args, **kwargs):

def __init__(self):
self.executor = ThreadPoolExecutor(max_workers=self.POOL_SIZE)
self.session = NoRebuildAuthSession()

def submit(self, txn: AnalyticsTxn):
_refresh_if_outdated()
self.expires_at = None
self.headers = dict()

# Local caching of expiration date and headers
self._refresh_expires_at()
self._refresh_headers()

def _refresh_expires_at(self):
self.expires_at = json.loads(container.access_jwt.claims)["exp"]

headers = {
def _refresh_headers(self):
self.headers = {
"Authorization": f"Bearer {container.access_jwt.serialize()}",
"Content-Type": "application/json"
}
self.executor.submit(self.request_job, txn.to_json(), headers)

def request_job(self, json, headers):
session = NoRebuildAuthSession()
session.post(url=self.ANALYTICS_URL, json=json, headers=headers)
def submit(self, txn: AnalyticsTxn):
# Offer a 30 second buffer to refresh
if time.time() < self.expires_at - 30:
_refresh_if_outdated()
self._refresh_expires_at()
self._refresh_headers()

self.executor.submit(self.send_message, txn.to_json())

def send_message(self, json):
self.session.post(url=self.ANALYTICS_URL, json=json, headers=self.headers)
13 changes: 8 additions & 5 deletions tests/analytics/test_analytics.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ def test_analytics_txn(self):

txn = AnalyticsTxn(**data)
data_json = txn.to_json()
# data_dict = json.dumps(data_json)

self.assertEqual(Product.MOBILE_BACKEND.value, int(data_json["product"]))
self.assertIsNone(data_json["pennkey"])
Expand All @@ -33,11 +32,15 @@ def setUp(self):
def test_submit(self):
data = {
"product": Product.MOBILE_BACKEND,
"pennkey": "hi",
"data": [{"key": "backend", "value": "data"}],
"pennkey": "judtin",
"data": [{"key": "backend", "value": "some data"}],
}

txn = AnalyticsTxn(**data)
for _ in range(20):
data["product"] = Product((data["product"].value + 1) % len(Product))
txn = AnalyticsTxn(**data)
self.analytics_wrapper.submit(txn)

self.analytics_wrapper.executor.shutdown(wait=True)

self.analytics_wrapper.submit(txn)
assert False
2 changes: 2 additions & 0 deletions tests/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
"django.contrib.admin",
"django.contrib.messages",
"accounts.apps.AccountsConfig",
"identity.apps.IdentityConfig",
"analytics.apps.AnalyticsConfig",
"tests",
)

Expand Down
4 changes: 2 additions & 2 deletions tox.ini
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
[tox]
isolated_build = true
envlist =
; lint,
lint,
py311-django{502},
; sentry-django{30,31},
sentry-django{502},

[testenv]
allowlist_externals = poetry
Expand Down

0 comments on commit 037d29b

Please sign in to comment.