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

Array adapter #117

Open
TheCelavi opened this issue Oct 21, 2024 · 1 comment
Open

Array adapter #117

TheCelavi opened this issue Oct 21, 2024 · 1 comment

Comments

@TheCelavi
Copy link

Would it be possible to write array adapter?

Seams kinda missing for unit/integration tests, right?

Would you accept such PR?

@TheCelavi
Copy link
Author

TheCelavi commented Oct 21, 2024

Ok, I wrote adapter, you can use it if you like. Only thing which is missing here is to reset adapter when test ends. In Symfony, that would be to implement ResetInterface.

To be framework agnostic, this could be implemented as singletone pattern, and then to use PHPUnit hooks to call reset().

/**
 * @phpstan-type Record = array{
 *     service: string,
 *     count: int,
 *     lastFailureTime: int|null,
 *     status: int,
 * }
 *
 * @SuppressWarnings(PHPMD.TooManyPublicMethods)
 */
final class ArrayAdapter implements AdapterInterface, TumblingTimeWindowInterface, SlidingTimeWindowInterface
{
   /**
     * Storage must be shared among all instances of the adapter.
     *
     * @var array<string, int|null>
     */
    private static array $storage = [];

    /**
     * {@inheritdoc}
     */
    public function supportCountStrategy(): bool
    {
        return true;
    }

    /**
     * {@inheritdoc}
     */
    public function supportRateStrategy(): bool
    {
        return true;
    }

    /**
     * {@inheritdoc}
     */
    public function setContext(Context $context): void
    {
        // This adapter doesn't use the context.
    }

    /**
     * {@inheritdoc}
     */
    public function setConfiguration(Configuration $configuration): void
    {
        // noop
    }

    /**
     * {@inheritdoc}
     */
    public function load(string $service): int
    {
        self::$storage[$service] = self::$storage[$service] ?? 0;
        return self::$storage[$service] ?? 0;
    }

    /**
     * {@inheritdoc}
     */
    public function save(string $service, int $count): void
    {
        self::$storage[$service] = $count;
    }

    /**
     * {@inheritdoc}
     */
    public function increment(string $service): void
    {
        self::$storage[$service] = (self::$storage[$service] ?? 0) + 1;
    }

    /**
     * {@inheritdoc}
     */
    public function decrement(string $service): void
    {
        self::$storage[$service] = \max(0, (self::$storage[$service] ?? 0) - 1);
    }

    /**
     * {@inheritdoc}
     */
    public function saveLastFailureTime(string $service, int $lastFailureTime): void
    {
        // WHY??? Count strategy does not work without this, why?
        $service = \sprintf('%s_last_failure_time', $service);

        self::$storage[$service] = $lastFailureTime;
    }

    /**
     * {@inheritdoc}
     */
    public function loadLastFailureTime(string $service)
    {
        // WHY???
        $service = \sprintf('%s_last_failure_time', $service);

        return self::$storage[$service] ?? null;
    }

    /**
     * {@inheritdoc}
     */
    public function saveStatus(string $service, int $status): void
    {
        self::$storage[$service] = $status;
    }

    /**
     * {@inheritdoc}
     */
    public function loadStatus(string $service): int
    {
        if (!isset(self::$storage[$service])) {
            self::$storage[$service] = Ganesha::STATUS_CALMED_DOWN;
        }

        return self::$storage[$service];
    }

    /**
     * {@inheritdoc}
     */
    public function reset(): void
    {
        self::$storage = [];
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant