Skip to content

Commit 75cefb6

Browse files
committed
xrpc_sync.list_repos: add minimal kwarg
skips keys and other setup. should speed up listRepos in prod by 90%+
1 parent f857a41 commit 75cefb6

5 files changed

Lines changed: 34 additions & 5 deletions

File tree

arroba/datastore_storage.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -715,7 +715,7 @@ def load_repo(self, did_or_handle):
715715
rotation_key=atp_repo.rotation_key)
716716

717717
@ndb_context
718-
def load_repos(self, after=None, limit=500):
718+
def load_repos(self, after=None, limit=500, minimal=False):
719719
query = AtpRepo.query()
720720
if after:
721721
query = query.filter(AtpRepo.key > AtpRepo(id=after).key)
@@ -727,6 +727,10 @@ def load_repos(self, after=None, limit=500):
727727
blocks = self.read_many(cids) # dict mapping CID to block
728728
heads = [blocks[cid] for cid in cids]
729729

730+
if minimal:
731+
return [Repo(storage=self, head=head, status=atp_repo.status)
732+
for atp_repo, head in zip(atp_repos, heads)]
733+
730734
# MST.load doesn't read from storage
731735
msts = [MST.load(storage=self, cid=block.decoded['data']) for block in heads]
732736
return [Repo(storage=self, mst=mst, head=head, status=atp_repo.status,

arroba/repo.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,6 @@ def __init__(self, *, storage=None, mst=None, head=None, handle=None,
7676
rotation_key (ec.EllipticCurvePrivateKey)
7777
"""
7878
assert storage
79-
assert signing_key
8079

8180
self.storage = storage
8281
self.mst = mst

arroba/storage.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,7 @@ def store_repo(self, repo):
232232
"""
233233
raise NotImplementedError()
234234

235-
def load_repos(self, after=None, limit=500):
235+
def load_repos(self, after=None, limit=500, minimal=False):
236236
"""Loads multiple repos from storage.
237237
238238
Repos are returned in lexicographic order of their DIDs, ascending.
@@ -241,6 +241,10 @@ def load_repos(self, after=None, limit=500):
241241
Args:
242242
after (str): optional DID to start at, *exclusive*
243243
limit (int): maximum number of repos to return
244+
minimal (bool): if True, returned :class:`Repo` s will only include
245+
``head`` and ``status``; other attributes like ``signing_key``,
246+
``rotation_key``, ``mst``, and ``handle`` may be None. Intended
247+
for ``com.atproto.sync.listRepos``.
244248
245249
Returns:
246250
sequence of Repo:
@@ -679,7 +683,7 @@ def load_repo(self, did_or_handle):
679683
def store_repo(self, repo):
680684
self.repos[repo.did] = repo
681685

682-
def load_repos(self, after=None, limit=500):
686+
def load_repos(self, after=None, limit=500, minimal=False):
683687
it = iter(sorted(self.repos.values(), key=lambda repo: repo.did))
684688

685689
if after:

arroba/tests/test_storage.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,19 @@ def test_load_repos_limit(self):
228228
self.assertEqual(1, len(got))
229229
self.assertEqual('did:plc:bob', got[0].did)
230230

231+
def test_load_repos_minimal(self):
232+
alice = Repo.create(self.storage, 'did:web:alice', signing_key=self.key)
233+
bob = Repo.create(self.storage, 'did:plc:bob', signing_key=self.key)
234+
self.storage.tombstone_repo(bob)
235+
236+
got_bob, got_alice = self.storage.load_repos(minimal=True)
237+
238+
self.assertEqual(alice.head, got_alice.head)
239+
self.assertIsNone(got_alice.status)
240+
241+
self.assertEqual(bob.head, got_bob.head)
242+
self.assertEqual('tombstoned', got_bob.status)
243+
231244
def test_tombstone_repo(self):
232245
seen = []
233246
repo = Repo.create(self.storage, 'did:user', signing_key=self.key)
@@ -500,6 +513,15 @@ def test_commit_callback(self):
500513

501514
class DatastoreStorageTest(StorageTest, DatastoreTest):
502515
"""Run all of StorageTest's tests with DatastoreStorage."""
516+
def test_load_repos_minimal_skips_keys_and_mst(self):
517+
Repo.create(self.storage, 'did:web:alice', signing_key=self.key)
518+
519+
got = self.storage.load_repos(minimal=True)
520+
self.assertEqual(1, len(got))
521+
self.assertIsNone(got[0].signing_key)
522+
self.assertIsNone(got[0].rotation_key)
523+
self.assertIsNone(got[0].mst)
524+
503525
def test_create_commit_datastore_transaction_retry(self):
504526
# fake what a Repo.create => Storage.commit retry due to datastore transaction
505527
# contention would look like.

arroba/xrpc_sync.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ def list_repos(input, limit=500, cursor=None):
7676
STATUSES = {'tombstoned': 'deactivated'}
7777

7878
repos = []
79-
for repo in server.storage.load_repos(limit=limit, after=cursor):
79+
for repo in server.storage.load_repos(limit=limit, after=cursor, minimal=True):
8080
repo_obj = {
8181
'did': repo.did,
8282
'head': repo.head.cid.encode('base32'),

0 commit comments

Comments
 (0)