Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions langfuse/_utils/prompt_cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,13 @@ def __init__(self, prompt: PromptClient, ttl_seconds: int):
self._expiry = ttl_seconds + self.get_epoch_seconds()

def is_expired(self) -> bool:
return self.get_epoch_seconds() > self._expiry
"""Return whether the full cache lifetime has elapsed."""
return self.get_epoch_seconds() >= self._expiry

@staticmethod
def get_epoch_seconds() -> int:
return int(datetime.now().timestamp())
def get_epoch_seconds() -> float:
"""Keep fractional seconds so expiry reflects the actual insertion time."""
return datetime.now().timestamp()


class PromptCacheRefreshConsumer(Thread):
Expand Down
11 changes: 11 additions & 0 deletions tests/unit/test_prompt.py
Original file line number Diff line number Diff line change
Expand Up @@ -748,3 +748,14 @@ def test_get_fresh_prompt_when_version_changes(langfuse: Langfuse):
result_call_2 = langfuse.get_prompt(prompt_name, version=2)
assert mock_server_call.call_count == 2
assert result_call_2 == version_changed_prompt_client


def test_prompt_cache_item_expires_at_exact_ttl_without_rounding():
"""A cached prompt stays fresh only until its full TTL has elapsed."""
with patch("langfuse._utils.prompt_cache.datetime") as clock:
clock.now.return_value.timestamp.return_value = 100.75
item = PromptCacheItem(prompt=Mock(), ttl_seconds=1)
clock.now.return_value.timestamp.return_value = 101.70
assert not item.is_expired()
clock.now.return_value.timestamp.return_value = 101.75
assert item.is_expired()
Loading