Skip to content

Commit

Permalink
Add CacheDatabaseAdapter keys method
Browse files Browse the repository at this point in the history
  • Loading branch information
cjdsellers committed Dec 3, 2023
1 parent f626d8c commit 633e6b5
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 1 deletion.
30 changes: 30 additions & 0 deletions nautilus_trader/cache/database.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,36 @@ cdef class CacheDatabaseAdapter(CacheDatabaseFacade):
self._backing.flushdb()
self._log.info("Flushed database.", LogColor.BLUE)

cpdef list[str] keys(self, str pattern = "*"):
"""
Return all keys in the database matching the given `pattern`.
Parameters
----------
pattern : str, default '*'
The glob-style pattern to match against the keys in the database.
Returns
-------
list[str]
Raises
------
ValueError
If `pattern` is not a valid string.
Warnings
--------
Using the default '*' pattern string can have serious performance implications and
can take a long time to execute if many keys exist in the database. This operation
can lead to high memory and CPU usage, and should be used with caution, especially
in production environments.
"""
Condition.valid_string(pattern, "pattern")

return self._backing.keys(pattern)

cpdef dict load(self):
"""
Load all general objects from the database.
Expand Down
1 change: 1 addition & 0 deletions nautilus_trader/cache/facade.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ cdef class CacheDatabaseFacade:
cdef LoggerAdapter _log

cpdef void flush(self)
cpdef list[str] keys(self, str pattern=*)
cpdef dict load(self)
cpdef dict load_currencies(self)
cpdef dict load_instruments(self)
Expand Down
4 changes: 4 additions & 0 deletions nautilus_trader/cache/facade.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,10 @@ cdef class CacheDatabaseFacade:
"""Abstract method (implement in subclass)."""
raise NotImplementedError("method must be implemented in the subclass") # pragma: no cover

cpdef list[str] keys(self, str pattern = "*"):
"""Abstract method (implement in subclass)."""
raise NotImplementedError("method must be implemented in the subclass") # pragma: no cover

cpdef dict load(self):
"""Abstract method (implement in subclass)."""
raise NotImplementedError("method must be implemented in the subclass") # pragma: no cover
Expand Down
10 changes: 9 additions & 1 deletion tests/integration_tests/infrastructure/test_cache_database.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,11 @@ def setup(self):
def teardown(self):
# Tests will fail if Redis is not flushed on tear down
self.database.flush() # Comment this line out to preserve data between tests for debugging
time.sleep(0.1) # Ensure clean slate

# Ensure clean slate
while self.database.keys("*"):
time.sleep(0.1)
continue

@pytest.mark.asyncio
async def test_load_general_objects_when_nothing_in_cache_returns_empty_dict(self):
Expand All @@ -156,6 +160,7 @@ async def test_load_general_objects_when_nothing_in_cache_returns_empty_dict(sel

# Assert
assert result == {}
assert self.database.keys() == []

@pytest.mark.asyncio
async def test_add_general_object_adds_to_cache(self):
Expand All @@ -171,6 +176,7 @@ async def test_add_general_object_adds_to_cache(self):

# Assert
assert self.database.load() == {key: str(bar).encode()}
assert self.database.keys() == ["trader-TESTER-000:general:" + key]

@pytest.mark.asyncio
async def test_add_currency(self):
Expand Down Expand Up @@ -1191,6 +1197,8 @@ async def test_rerunning_backtest_with_redis_db_builds_correct_index(self):
# Reset engine
self.engine.reset()

await asyncio.sleep(0.5)

# Act
self.engine.run()

Expand Down

0 comments on commit 633e6b5

Please sign in to comment.