Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: allow feature value size to be configured per installation #4446

Merged
merged 11 commits into from
Sep 27, 2024
6 changes: 6 additions & 0 deletions api/app/settings/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -1213,6 +1213,12 @@
"SEGMENT_CONDITION_VALUE_LIMIT must be between 0 and 2,000,000 (2MB)."
)

FEATURE_VALUE_LIMIT = env.int("FEATURE_VALUE_LIMIT", default=20_000)
if not 0 <= FEATURE_VALUE_LIMIT <= 2000000: # pragma: no cover
raise ImproperlyConfigured(
"FEATURE_VALUE_LIMIT must be between 0 and 2,000,000 (2MB)."
)

SEGMENT_RULES_CONDITIONS_LIMIT = env.int("SEGMENT_RULES_CONDITIONS_LIMIT", 100)

WEBHOOK_BACKOFF_BASE = env.int("WEBHOOK_BACKOFF_BASE", default=2)
Expand Down
5 changes: 4 additions & 1 deletion api/features/feature_states/models.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import typing

from django.conf import settings
from django.db import models

from features.value_types import (
Expand All @@ -23,7 +24,9 @@ class Meta:
)
boolean_value = models.BooleanField(null=True, blank=True)
integer_value = models.IntegerField(null=True, blank=True)
string_value = models.CharField(null=True, max_length=20000, blank=True)
string_value = models.CharField(
null=True, max_length=settings.FEATURE_VALUE_LIMIT, blank=True
)

@property
def value(self) -> typing.Union[str, int, bool]:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Generated by Django 3.2.25 on 2024-08-01 21:09
from django.conf import settings
from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('features', '0064_fix_feature_help_text_typo'),
]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we add the sqlmigrate for this and the other migration

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here they are without setting the environment variable:

❯ python manage.py sqlmigrate features 0065
BEGIN;
--
-- Alter field initial_value on feature
--
-- (no-op)
--
-- Alter field initial_value on historicalfeature
--
-- (no-op)
--
-- Alter field string_value on featurestatevalue
--
-- (no-op)
--
-- Alter field string_value on historicalfeaturestatevalue
--
-- (no-op)
COMMIT;
❯ python manage.py sqlmigrate multivariate 0008
BEGIN;
--
-- Alter field string_value on historicalmultivariatefeatureoption
--
-- (no-op)
--
-- Alter field string_value on multivariatefeatureoption
--
-- (no-op)
COMMIT;

... and with the environment variable

❯ export FEATURE_VALUE_LIMIT=2000000
❯ python manage.py sqlmigrate features 0065
BEGIN;
--
-- Alter field initial_value on feature
--
ALTER TABLE "features_feature" ALTER COLUMN "initial_value" TYPE varchar(2000000);
--
-- Alter field initial_value on historicalfeature
--
ALTER TABLE "features_historicalfeature" ALTER COLUMN "initial_value" TYPE varchar(2000000);
--
-- Alter field string_value on featurestatevalue
--
ALTER TABLE "features_featurestatevalue" ALTER COLUMN "string_value" TYPE varchar(2000000);
--
-- Alter field string_value on historicalfeaturestatevalue
--
ALTER TABLE "features_historicalfeaturestatevalue" ALTER COLUMN "string_value" TYPE varchar(2000000);
COMMIT;
❯ python manage.py sqlmigrate multivariate 0008
BEGIN;
--
-- Alter field string_value on historicalmultivariatefeatureoption
--
ALTER TABLE "multivariate_historicalmultivariatefeatureoption" ALTER COLUMN "string_value" TYPE varchar(2000000);
--
-- Alter field string_value on multivariatefeatureoption
--
ALTER TABLE "multivariate_multivariatefeatureoption" ALTER COLUMN "string_value" TYPE varchar(2000000);
COMMIT;


operations = [
migrations.AlterField(
model_name='feature',
name='initial_value',
field=models.CharField(blank=True, max_length=settings.FEATURE_VALUE_LIMIT, null=True, default=None),
),
migrations.AlterField(
model_name='historicalfeature',
name='initial_value',
field=models.CharField(blank=True, max_length=settings.FEATURE_VALUE_LIMIT, null=True, default=None),
),
migrations.AlterField(
model_name='featurestatevalue',
name='string_value',
field=models.CharField(blank=True, max_length=settings.FEATURE_VALUE_LIMIT, null=True),
),
migrations.AlterField(
model_name='historicalfeaturestatevalue',
name='string_value',
field=models.CharField(blank=True, max_length=settings.FEATURE_VALUE_LIMIT, null=True),
),
]
3 changes: 2 additions & 1 deletion api/features/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
SoftDeleteExportableModel,
abstract_base_auditable_model_factory,
)
from django.conf import settings
from django.contrib.contenttypes.fields import GenericRelation
from django.core.exceptions import (
NON_FIELD_ERRORS,
Expand Down Expand Up @@ -109,7 +110,7 @@ class Feature(
on_delete=models.DO_NOTHING,
)
initial_value = models.CharField(
max_length=20000, null=True, default=None, blank=True
max_length=settings.FEATURE_VALUE_LIMIT, null=True, default=None, blank=True
)
description = models.TextField(null=True, blank=True)
default_enabled = models.BooleanField(default=False)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Generated by Django 3.2.25 on 2024-08-01 21:09
from django.conf import settings
from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('multivariate', '0007_alter_boolean_values'),
]

operations = [
migrations.AlterField(
model_name='historicalmultivariatefeatureoption',
name='string_value',
field=models.CharField(blank=True, max_length=settings.FEATURE_VALUE_LIMIT, null=True),
),
migrations.AlterField(
model_name='multivariatefeatureoption',
name='string_value',
field=models.CharField(blank=True, max_length=settings.FEATURE_VALUE_LIMIT, null=True),
),
]
Loading