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
2 changes: 1 addition & 1 deletion tiled/_tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -363,7 +363,7 @@ def tiled_websocket_context(tmpdir, redis_uri):
init_if_not_exists=True,
# This uses shorter defaults than the production defaults. Nothing in
# the test suite should be going on for more than ten minutes.
cache_settings={
cache_config={
"uri": redis_uri,
"data_ttl": 600, # 10 minutes
"seq_ttl": 600, # 10 minutes
Expand Down
22 changes: 12 additions & 10 deletions tiled/catalog/adapter.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ def __init__(
writable_storage=None,
readable_storage=None,
adapters_by_mimetype=None,
cache_settings=None,
cache_config=None,
key_maker=lambda: str(uuid.uuid4()),
storage_pool_size=5,
storage_max_overflow=10,
Expand Down Expand Up @@ -219,7 +219,7 @@ def __init__(
adapters_by_mimetype, DEFAULT_ADAPTERS_BY_MIMETYPE
)
self.adapters_by_mimetype = merged_adapters_by_mimetype
self.cache_settings = cache_settings
self.cache_config = cache_config

def session(self):
"Convenience method for constructing an AsyncSession context"
Expand All @@ -241,10 +241,12 @@ async def startup(self):
await check_catalog_database(self.engine)

self.streaming_cache = None
if self.cache_settings:
if self.cache_settings["uri"].startswith("redis"):
self.cache_settings["datastore"] = "redis"
self.streaming_cache = StreamingCache(self.cache_settings)
if self.cache_config:
if self.cache_config["uri"].startswith("redis"):
self.cache_config["datastore"] = "redis"
elif self.cache_config["uri"].startswith("ttlcache"):
self.cache_config["datastore"] = "ttlcache"
self.streaming_cache = StreamingCache(self.cache_config)

async def shutdown(self):
await close_database_connection_pool(self.database_settings)
Expand Down Expand Up @@ -1676,7 +1678,7 @@ def in_memory(
readable_storage=None,
adapters_by_mimetype=None,
top_level_access_blob=None,
cache_settings=None,
cache_config=None,
):
if not named_memory:
uri = "sqlite:///:memory:"
Expand All @@ -1693,7 +1695,7 @@ def in_memory(
init_if_not_exists=True,
adapters_by_mimetype=adapters_by_mimetype,
top_level_access_blob=top_level_access_blob,
cache_settings=cache_settings,
cache_config=cache_config,
)


Expand All @@ -1708,7 +1710,7 @@ def from_uri(
adapters_by_mimetype=None,
top_level_access_blob=None,
mount_node: Optional[Union[str, List[str]]] = None,
cache_settings=None,
cache_config=None,
catalog_pool_size=5,
storage_pool_size=5,
catalog_max_overflow=10,
Expand Down Expand Up @@ -1745,7 +1747,7 @@ def from_uri(
writable_storage,
readable_storage,
adapters_by_mimetype,
cache_settings,
cache_config,
storage_pool_size=storage_pool_size,
storage_max_overflow=storage_max_overflow,
)
Expand Down
19 changes: 11 additions & 8 deletions tiled/commandline/_serve.py
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,9 @@ def serve_catalog(

write = write or []
if temp:
if cache_uri is None:
# Setup a TTLCache if nothing specified while using the --temp flag
cache_uri = "ttlcache"
if database is not None:
typer.echo(
"The option --temp was set but a database was also provided. "
Expand Down Expand Up @@ -414,7 +417,7 @@ def serve_catalog(
from ..alembic_utils import stamp_head
from ..catalog.alembic_constants import ALEMBIC_DIR, ALEMBIC_INI_TEMPLATE_PATH
from ..catalog.core import initialize_database
from ..config import StreamingCache
from ..config import StreamingCacheConfig
from ..utils import ensure_specified_sql_driver

database = ensure_specified_sql_driver(database)
Expand Down Expand Up @@ -477,23 +480,23 @@ def serve_catalog(
)

if cache_uri:
cli_cache_settings = {}
cli_cache_settings["uri"] = cache_uri
cli_cache_config = {}
cli_cache_config["uri"] = cache_uri
if cache_data_ttl:
cli_cache_settings["data_ttl"] = cache_data_ttl
cli_cache_config["data_ttl"] = cache_data_ttl
if cache_seq_ttl:
cli_cache_settings["seq_ttl"] = cache_seq_ttl
cli_cache_config["seq_ttl"] = cache_seq_ttl
# Apply defaults.
cache_settings = StreamingCache(**cli_cache_settings).model_dump()
cache_config = StreamingCacheConfig(**cli_cache_config).model_dump()
else:
cache_settings = None
cache_config = None

tree = from_uri(
database,
writable_storage=write,
readable_storage=read,
init_if_not_exists=init,
cache_settings=cache_settings,
cache_config=cache_config,
)
web_app = build_app(
tree,
Expand Down
6 changes: 3 additions & 3 deletions tiled/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ class ValidationSpec(BaseModel):
validator: Optional[EntryPointString] = None


class StreamingCache(BaseModel):
class StreamingCacheConfig(BaseModel):
uri: str
data_ttl: int = 3600 # 1 hr
seq_ttl: int = 2592000 # 30 days
Expand Down Expand Up @@ -205,7 +205,7 @@ class Config(BaseModel):
catalog_max_overflow: int = 10
storage_max_overflow: int = 10

streaming_cache: Optional[StreamingCache] = None
streaming_cache: Optional[StreamingCacheConfig] = None

@field_validator("access_policy")
@classmethod
Expand Down Expand Up @@ -249,7 +249,7 @@ def fudge_tree_args(self):
self.storage_max_overflow or defaults.storage_max_overflow
)
if tree.tree_type in (from_uri, in_memory):
tree.args["cache_settings"] = (
tree.args["cache_config"] = (
self.streaming_cache.model_dump() if self.streaming_cache else None
)
return self
Expand Down
11 changes: 11 additions & 0 deletions tiled/server/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,17 @@ def build_app(
tasks["shutdown"].extend(getattr(tree, "shutdown_tasks", []))

if scalable:
streaming_cache = server_settings.get("streaming_cache", None)
if streaming_cache and streaming_cache["uri"].startswith("ttlcache"):
raise UnscalableConfig(
dedent(
"""
In a scaled (multi-process) deployment, Tiled cannot
use ttlcache as its streaming datastore.

"""
)
)
if authenticators:
# Even if the deployment allows public, anonymous access, secret
# keys are needed to generate JWTs for any users that do log in.
Expand Down
Loading
Loading