Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Use universal interface for Redis, or remove @internal from RedisProxy #42428

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

Closed
4 tasks
sirian opened this issue Aug 8, 2021 · 6 comments
Closed
4 tasks

Use universal interface for Redis, or remove @internal from RedisProxy #42428

sirian opened this issue Aug 8, 2021 · 6 comments

Comments

@sirian
Copy link
Contributor

sirian commented Aug 8, 2021

Description

At this moment all of Symfony Redis adapters/handlers tightly bound to \Redis | \RedisArray | \RedisCluster | RedisProxy | RedisClusterProxy | \Predis\ClientInterface

Symfony\Component\Lock\Store\RedisStore
Symfony\Component\Cache\Adapter\RedisAdapter
Symfony\Component\HttpFoundation\Session\Storage\Handler\RedisSessionHandler

I want to log/profile redis commands (phpredis), but there is no right way to use decorated Redis class with Symfony components.

  • Attempt 1 - Simple decoration - won't bypass instanceof checks inside Symfony classes.
/** @mixin Redis */
class RedisClient
{
    public function __construct(
        private Redis $redis;
        private LoggerInterface $logger;
    ) {}

    public function call(string $name, array $arguments)
    {
            $this->logger->debug('...');
            return $this->redis->{$name}(...$arguments);
    }
}

new Symfony\Component\Lock\Store\RedisStore(new RedisClient(...)); // throws InvalidArgumentException
  • Attempt 2 - extend \Redis
    This requires to override all Redis methods and this is ridiculous. Look at this 1500+ lines example:
    https://github.com/snc/SncRedisBundle/blob/d7718cd75166bb256380cf428cbde54402be149e/Client/Phpredis/Client.php#L189

  • Attempt 3 (dirty) - extend Symfony\Component\Cache\Traits\RedisProxy.
    This works, but RedisProxy marked as @internal so you will get deprecation errors. And since it's internal - there is no guarantee that this class will not be silently changed.

  • Attempt 4 (dirty+monkeypatching) - copy RedisProxy to src. Configure autoload and exclude-from-classmap in composer.json. But let's leave monkeypatching for javascript community!

Final thoughts
Please either remove @internal from Symfony\Component\Cache\Traits\RedisProxy or add another way to solve this problem

@ro0NL
Copy link
Contributor

ro0NL commented Aug 9, 2021

i also concluded RedisProxy was our main extension point, see #42087

im 👍 given RedisProxy symbol seems gerally more useful than Redis

@sirian
Copy link
Contributor Author

sirian commented Aug 9, 2021

@nicolas-grekas #42087 (comment)

We can keep the symbol internal as you don't reference it directly.

You wrong. At this moment RedisProxy is the only one way to use decorated Redis with Symfony components like

Symfony\Component\Lock\Store\RedisStore
Symfony\Component\Cache\Adapter\RedisAdapter
Symfony\Component\HttpFoundation\Session\Storage\Handler\RedisSessionHandler

because all of them has strict instanceof checks like

if (
            !$redis instanceof \Redis &&
            !$redis instanceof \RedisArray &&
            !$redis instanceof \RedisCluster &&
            !$redis instanceof \Predis\ClientInterface &&
            !$redis instanceof RedisProxy &&
            !$redis instanceof RedisClusterProxy
        ) {
            throw new \InvalidArgumentException(sprintf('"%s()" expects parameter 1 to be Redis, RedisArray, RedisCluster or Predis\ClientInterface, "%s" given.', __METHOD__, get_debug_type($redis)));
        }

@ro0NL
Copy link
Contributor

ro0NL commented Nov 8, 2021

@nicolas-grekas pls reconsider :) im depending on it for a RedisClientInterface implementation.

@nicolas-grekas
Copy link
Member

I'm sorry but as I explained in #42087 I don't have a solution better than telling you to extend RedisProxy despite it being @internal. Or to find another way to add profiling instrumentation on your side.

@ro0NL
Copy link
Contributor

ro0NL commented Nov 8, 2021

Now im wondering, if good old lazy: true on the service definition (with proxy-manager) would work actually 😅

@nicolas-grekas
Copy link
Member

Could be! :)
Closing meanwhile.

nicolas-grekas added a commit that referenced this issue Sep 12, 2022
This PR was merged into the 6.2 branch.

Discussion
----------

[Cache] make `Redis*Proxy` extend `Redis*`

| Q             | A
| ------------- | ---
| Branch?       | 6.2
| Bug fix?      | no
| New feature?  | no
| Deprecations? | no
| Tickets       | Fix #47267, #42428
| License       | MIT
| Doc PR        | -

`Redis*Proxy` did not extend native classes because we missed the code infrastructure to generate appropriate proxies.
With #47236, we now have it. This PR adds generated proxies to the cache component to keep it lazy-able out of the box.

Commits
-------

cfb46ed [Cache] make `Redis*Proxy` extend `Redis*`
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

3 participants