Skip to content
Open
2 changes: 1 addition & 1 deletion providers/openfeature-provider-flagd/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ The default options can be defined in the FlagdProvider constructor.
|--------------------------|--------------------------------|----------------------------|-------------------------------|---------------------|
| resolver_type | FLAGD_RESOLVER | enum - `rpc`, `in-process` | rpc | |
| host | FLAGD_HOST | str | localhost | rpc & in-process |
| port | FLAGD_PORT | int | 8013 (rpc), 8015 (in-process) | rpc & in-process |
| port | FLAGD_SYNC_PORT (in-process), FLAGD_PORT (rpc or fallback) | int | 8013 (rpc), 8015 (in-process) | rpc & in-process |
Comment thread
MridulTailor marked this conversation as resolved.
Outdated
| tls | FLAGD_TLS | bool | false | rpc & in-process |
| cert_path | FLAGD_SERVER_CERT_PATH | String | null | rpc & in-process |
| deadline | FLAGD_DEADLINE_MS | int | 500 | rpc & in-process |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ class CacheType(Enum):
ENV_VAR_OFFLINE_FLAG_SOURCE_PATH = "FLAGD_OFFLINE_FLAG_SOURCE_PATH"
ENV_VAR_OFFLINE_POLL_MS = "FLAGD_OFFLINE_POLL_MS"
ENV_VAR_PORT = "FLAGD_PORT"
ENV_VAR_SYNC_PORT = "FLAGD_SYNC_PORT"
ENV_VAR_RESOLVER_TYPE = "FLAGD_RESOLVER"
ENV_VAR_RETRY_BACKOFF_MS = "FLAGD_RETRY_BACKOFF_MS"
ENV_VAR_RETRY_BACKOFF_MAX_MS = "FLAGD_RETRY_BACKOFF_MAX_MS"
Expand Down Expand Up @@ -79,7 +80,7 @@ def env_or_default(

@dataclasses.dataclass
class Config:
def __init__( # noqa: PLR0913
def __init__( # noqa: PLR0913, PLR0915
self,
host: typing.Optional[str] = None,
port: typing.Optional[int] = None,
Expand Down Expand Up @@ -149,17 +150,27 @@ def __init__( # noqa: PLR0913
else resolver
)

default_port = (
DEFAULT_PORT_RPC
if self.resolver is ResolverType.RPC
else DEFAULT_PORT_IN_PROCESS
)

self.port: int = (
int(env_or_default(ENV_VAR_PORT, default_port, cast=int))
if port is None
else port
)
# Port configuration with FLAGD_SYNC_PORT support for in-process mode
if port is None:
if self.resolver is ResolverType.IN_PROCESS:
# For in-process: try FLAGD_SYNC_PORT first, then FLAGD_PORT (backwards compatibility), then default
sync_port_env = os.environ.get(ENV_VAR_SYNC_PORT)
if sync_port_env is not None:
self.port = int(sync_port_env)
else:
port_env = os.environ.get(ENV_VAR_PORT)
self.port = (
int(port_env)
if port_env is not None
else DEFAULT_PORT_IN_PROCESS
)
Comment thread
MridulTailor marked this conversation as resolved.
Outdated
else:
# For RPC: use FLAGD_PORT only
self.port = int(
env_or_default(ENV_VAR_PORT, DEFAULT_PORT_RPC, cast=int)
)
else:
self.port = port
Comment thread
MridulTailor marked this conversation as resolved.

self.offline_flag_source_path = (
env_or_default(
Expand Down
54 changes: 54 additions & 0 deletions providers/openfeature-provider-flagd/tests/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
ENV_VAR_PORT,
ENV_VAR_RETRY_BACKOFF_MS,
ENV_VAR_STREAM_DEADLINE_MS,
ENV_VAR_SYNC_PORT,
ENV_VAR_TLS,
CacheType,
Config,
Expand Down Expand Up @@ -147,3 +148,56 @@ def test_uses_arguments_over_environments_and_defaults(monkeypatch, resolver_typ
assert config.retry_backoff_ms == retry_backoff
assert config.stream_deadline_ms == stream_deadline
assert config.tls is tls


def test_in_process_uses_sync_port(monkeypatch):
"""Test that FLAGD_SYNC_PORT is used for in-process mode when set."""
sync_port = 9999
monkeypatch.setenv(ENV_VAR_SYNC_PORT, str(sync_port))

config = Config(resolver=ResolverType.IN_PROCESS)
assert config.port == sync_port
assert config.resolver == ResolverType.IN_PROCESS


def test_in_process_fallback_to_port(monkeypatch):
"""Test that FLAGD_PORT is used as fallback when FLAGD_SYNC_PORT is not set."""
port = 7777
monkeypatch.setenv(ENV_VAR_PORT, str(port))

config = Config(resolver=ResolverType.IN_PROCESS)
assert config.port == port
assert config.resolver == ResolverType.IN_PROCESS


def test_in_process_sync_port_priority(monkeypatch):
"""Test that FLAGD_SYNC_PORT takes priority over FLAGD_PORT when both are set."""
sync_port = 9999
port = 7777
monkeypatch.setenv(ENV_VAR_SYNC_PORT, str(sync_port))
monkeypatch.setenv(ENV_VAR_PORT, str(port))

config = Config(resolver=ResolverType.IN_PROCESS)
assert config.port == sync_port # FLAGD_SYNC_PORT should win
assert config.resolver == ResolverType.IN_PROCESS


def test_rpc_ignores_sync_port(monkeypatch):
"""Test that RPC mode uses FLAGD_PORT and ignores FLAGD_SYNC_PORT."""
sync_port = 9999
port = 7777
monkeypatch.setenv(ENV_VAR_SYNC_PORT, str(sync_port))
monkeypatch.setenv(ENV_VAR_PORT, str(port))

config = Config(resolver=ResolverType.RPC)
assert config.port == port # RPC should use FLAGD_PORT
assert config.resolver == ResolverType.RPC


def test_in_process_default_port_when_no_env_var(monkeypatch):
"""Test that in-process mode uses default port when neither env var is set."""
monkeypatch.delenv(ENV_VAR_SYNC_PORT, raising=False)
monkeypatch.delenv(ENV_VAR_PORT, raising=False)
config = Config(resolver=ResolverType.IN_PROCESS)
assert config.port == DEFAULT_PORT_IN_PROCESS
assert config.resolver == ResolverType.IN_PROCESS