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

feature: find way to build flexible nested feature set #9

Open
1 task
kamilsk opened this issue May 27, 2022 · 0 comments
Open
1 task

feature: find way to build flexible nested feature set #9

kamilsk opened this issue May 27, 2022 · 0 comments
Assignees
Labels
difficulty: medium Issue has medium complexity. kind: feature New feature request. scope: code Issue related to source code. scope: test Issue related to tests.

Comments

@kamilsk
Copy link
Member

kamilsk commented May 27, 2022

Motivation: there is no way to work with features granularly, based on nested context, e.g. global > workspace > project > user.

Inspiration:

final class Feature
{
    public function __construct(
        private string $name,
        private ?int $workspace = null,
        private ?int $user = null,
    ) {
    }

    public function keys(): array
    {
        $keys = [sprintf('feature:%s', $this->name)];
        if ($this->workspace) {
            $keys[] = sprintf('feature:%s:workspace:%d', $this->name, $this->workspace);
        }
        if ($this->user) {
            $keys[] = sprintf('feature:%s:user:%d', $this->name, $this->user);
        }
        if (count($keys) > 1) {
            // move up from specific to generic
            $keys = array_reverse($keys);
        }
        return $keys;
    }
}

final class Service
{
    public function isEnabled(Feature $feature, bool $default = false): bool
    {
        foreach ($feature->keys() as $key) {
            $toggle = Redis::get($key);
            if ($toggle === null || $toggle === false) {
                continue;
            }
            return filter_var($toggle, FILTER_VALIDATE_BOOL);
        }

        return $default;
    }

    public function toggle(Feature $feature, ?bool $value): void
    {
        $userFeatureKey = $feature->userKey();
        Redis::set($userFeatureKey, $value ?? !$this->isEnabled($feature));
    }
}

Need abstraction to adapt it to different storages: MySQL, Redis, PostgreSQL, Bolt, etc.

To do:

@kamilsk kamilsk added difficulty: medium Issue has medium complexity. kind: feature New feature request. scope: code Issue related to source code. scope: test Issue related to tests. labels May 27, 2022
@kamilsk kamilsk self-assigned this May 27, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
difficulty: medium Issue has medium complexity. kind: feature New feature request. scope: code Issue related to source code. scope: test Issue related to tests.
Projects
Status: Backlog
Development

No branches or pull requests

1 participant