Skip to content

Commit 35f2749

Browse files
authored
🎨 Adds realtime domain in web-server and WEBSERVER_REALTIME_COLLABORATION Dev Feature Toggle to Settings (ITISFoundation#8120)
1 parent fc18d82 commit 35f2749

File tree

9 files changed

+91
-4
lines changed

9 files changed

+91
-4
lines changed

.env-devel

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,7 @@ WEBSERVER_PROJECTS={}
395395
WEBSERVER_PROMETHEUS_API_VERSION=v1
396396
WEBSERVER_PROMETHEUS_URL=http://prometheus:9090
397397
WEBSERVER_PUBLICATIONS=1
398+
WEBSERVER_REALTIME_COLLABORATION='{"RTC_MAX_NUMBER_OF_USERS":3}'
398399
WEBSERVER_SCICRUNCH={}
399400
WEBSERVER_SESSION_SECRET_KEY='REPLACE_ME_with_result__Fernet_generate_key='
400401
WEBSERVER_SOCKETIO=1

services/docker-compose.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -673,6 +673,7 @@ services:
673673
SWARM_STACK_NAME: ${SWARM_STACK_NAME}
674674

675675
WEBSERVER_DEV_FEATURES_ENABLED: ${WEBSERVER_DEV_FEATURES_ENABLED}
676+
WEBSERVER_REALTIME_COLLABORATION: ${WEBSERVER_REALTIME_COLLABORATION}
676677

677678
WEBSERVER_LOGLEVEL: ${WEBSERVER_LOGLEVEL}
678679
WEBSERVER_PROFILING: ${WEBSERVER_PROFILING}

services/static-webserver/client/Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ follow-dev-logs: ## follow the logs of the qx compiler
4444
.PHONY: compile touch upgrade
4545
compile: ## qx compiles host' 'source' -> image's 'build-output'
4646
# qx compile 'source' within $(docker_image) image [itisfoundation/qooxdoo-kit:${QOOXDOO_KIT_TAG}]
47-
@docker --debug buildx build \
47+
@docker buildx build \
4848
--load \
4949
--file $(docker_file) \
5050
--tag $(docker_image) \
@@ -58,7 +58,7 @@ compile: ## qx compiles host' 'source' -> image's 'build-output'
5858

5959
touch: ## minimal image build with /project/output-build inside
6060
# touch /project/output-build such that multi-stage 'services/web/Dockerfile' can build development target (fixes #1097)
61-
@docker --debug buildx build \
61+
@docker buildx build \
6262
--load \
6363
--file $(docker_file) \
6464
--tag $(docker_image) \

services/web/server/src/simcore_service_webserver/application.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77

88
from aiohttp import web
99
from servicelib.aiohttp.application import create_safe_application
10+
from simcore_service_webserver.collaboration.bootstrap import (
11+
setup_realtime_collaboration,
12+
)
1013

1114
from ._meta import WELCOME_DB_LISTENER_MSG, WELCOME_GC_MSG, WELCOME_MSG, info
1215
from .activity.plugin import setup_activity
@@ -160,6 +163,7 @@ def create_application() -> web.Application:
160163
setup_publications(app)
161164
setup_studies_dispatcher(app)
162165
setup_exporter(app)
166+
setup_realtime_collaboration(app)
163167

164168
# NOTE: *last* events
165169
app.on_startup.append(_welcome_banner)

services/web/server/src/simcore_service_webserver/application_settings.py

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929

3030
from ._meta import API_VERSION, API_VTAG, APP_NAME
3131
from .catalog.settings import CatalogSettings
32+
from .collaboration.settings import RealTimeCollaborationSettings
3233
from .constants import APP_SETTINGS_KEY
3334
from .diagnostics.settings import DiagnosticsSettings
3435
from .director_v2.settings import DirectorV2Settings
@@ -55,7 +56,7 @@
5556

5657

5758
# NOTE: to mark a plugin as a DEV-FEATURE annotated it with
58-
# `Field(json_schema_extra={_X_DEV_FEATURE_FLAG: True})`
59+
# `Field(json_schema_extra={_X_FEATURE_UNDER_DEVELOPMENT: True})`
5960
# This will force it to be disabled when WEBSERVER_DEV_FEATURES_ENABLED=False
6061
_X_FEATURE_UNDER_DEVELOPMENT: Final[str] = "x-dev-feature"
6162

@@ -277,6 +278,17 @@ class ApplicationSettings(BaseApplicationSettings, MixinLoggingSettings):
277278
Field(json_schema_extra={"auto_default_from_env": True}),
278279
]
279280

281+
WEBSERVER_REALTIME_COLLABORATION: Annotated[
282+
RealTimeCollaborationSettings | None,
283+
Field(
284+
description="Enables real-time collaboration features",
285+
json_schema_extra={
286+
"auto_default_from_env": True,
287+
_X_FEATURE_UNDER_DEVELOPMENT: True,
288+
},
289+
),
290+
]
291+
280292
WEBSERVER_REDIS: Annotated[
281293
RedisSettings | None, Field(json_schema_extra={"auto_default_from_env": True})
282294
]
@@ -482,6 +494,7 @@ def _get_disabled_advertised_plugins(self) -> list[str]:
482494
"WEBSERVER_LICENSES",
483495
"WEBSERVER_PAYMENTS",
484496
"WEBSERVER_SCICRUNCH",
497+
"WEBSERVER_REALTIME_COLLABORATION",
485498
}
486499
return [_ for _ in advertised_plugins if not self.is_enabled(_)] + [
487500
# NOTE: Permanently retired in https://github.com/ITISFoundation/osparc-simcore/pull/7182
@@ -558,6 +571,9 @@ def to_client_statics(self) -> dict[str, Any]:
558571
"WEBSERVER_PROJECTS": {
559572
"PROJECTS_MAX_NUM_RUNNING_DYNAMIC_NODES",
560573
},
574+
"WEBSERVER_REALTIME_COLLABORATION": {
575+
"RTC_MAX_NUMBER_OF_USERS",
576+
},
561577
"WEBSERVER_SESSION": {"SESSION_COOKIE_MAX_AGE"},
562578
"WEBSERVER_TRASH": {
563579
"TRASH_RETENTION_DAYS",

services/web/server/src/simcore_service_webserver/collaboration/__init__.py

Whitespace-only changes.
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import logging
2+
3+
from aiohttp import web
4+
from servicelib.aiohttp.application_setup import ModuleCategory, app_module_setup
5+
6+
_logger = logging.getLogger(__name__)
7+
8+
9+
@app_module_setup(
10+
__name__,
11+
ModuleCategory.ADDON,
12+
settings_name="WEBSERVER_REALTIME_COLLABORATION",
13+
logger=_logger,
14+
)
15+
def setup_realtime_collaboration(app: web.Application):
16+
from .settings import get_plugin_settings
17+
18+
assert get_plugin_settings(app), "setup_settings not called?"
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
from typing import Annotated
2+
3+
from aiohttp import web
4+
from pydantic import (
5+
PositiveInt,
6+
)
7+
from pydantic.fields import Field
8+
from settings_library.base import BaseCustomSettings
9+
10+
from ..constants import APP_SETTINGS_KEY
11+
12+
13+
class RealTimeCollaborationSettings(BaseCustomSettings):
14+
RTC_MAX_NUMBER_OF_USERS: Annotated[
15+
PositiveInt,
16+
Field(
17+
description="Maximum number of users allowed in a real-time collaboration session",
18+
),
19+
]
20+
21+
22+
def get_plugin_settings(app: web.Application) -> RealTimeCollaborationSettings:
23+
settings = app[APP_SETTINGS_KEY].WEBSERVER_REALTIME_COLLABORATION
24+
assert settings, "setup_settings not called?" # nosec
25+
assert isinstance(settings, RealTimeCollaborationSettings) # nosec
26+
return settings

services/web/server/tests/unit/isolated/test_application_settings.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,9 @@ def test_settings_to_client_statics(app_settings: ApplicationSettings):
7373
def test_settings_to_client_statics_plugins(
7474
mock_webserver_service_environment: EnvVarsDict, monkeypatch: pytest.MonkeyPatch
7575
):
76+
monkeypatch.delenv("WEBSERVER_REALTIME_COLLABORATION", raising=False)
77+
78+
# explicitly disable these plugins
7679
disable_plugins = {
7780
"WEBSERVER_EXPORTER",
7881
"WEBSERVER_SCICRUNCH",
@@ -82,12 +85,21 @@ def test_settings_to_client_statics_plugins(
8285
for name in disable_plugins:
8386
monkeypatch.setenv(name, "null")
8487

88+
# explicitly disable WEBSERVER_FOLDERS
8589
monkeypatch.setenv("WEBSERVER_FOLDERS", "0")
8690
disable_plugins.add("WEBSERVER_FOLDERS")
8791

92+
# set WEBSERVER_REALTIME_COLLABORATION (NOTE: for now WEBSERVER_DEV_FEATURES_ENABLED=True) )
93+
monkeypatch.setenv(
94+
"WEBSERVER_REALTIME_COLLABORATION", '{"RTC_MAX_NUMBER_OF_USERS":3}'
95+
)
96+
8897
settings = ApplicationSettings.create_from_envs()
89-
statics = settings.to_client_statics()
98+
assert settings.WEBSERVER_DEV_FEATURES_ENABLED
99+
100+
# -------------
90101

102+
statics = settings.to_client_statics()
91103
print("STATICS:\n", json_dumps(statics, indent=1))
92104

93105
assert settings.WEBSERVER_LOGIN
@@ -111,6 +123,15 @@ def test_settings_to_client_statics_plugins(
111123
assert statics["vcsReleaseTag"]
112124
assert TypeAdapter(HttpUrl).validate_python(statics["vcsReleaseUrl"])
113125

126+
# check WEBSERVER_REALTIME_COLLABORATION enabled
127+
assert "WEBSERVER_REALTIME_COLLABORATION" not in statics["pluginsDisabled"]
128+
assert settings.WEBSERVER_REALTIME_COLLABORATION
129+
assert (
130+
statics["webserverRealtimeCollaboration"]["RTC_MAX_NUMBER_OF_USERS"]
131+
== settings.WEBSERVER_REALTIME_COLLABORATION.RTC_MAX_NUMBER_OF_USERS
132+
)
133+
134+
# check disabled plugins
114135
assert set(statics["pluginsDisabled"]) == (disable_plugins)
115136

116137

0 commit comments

Comments
 (0)