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

[FrameworkBundle] revert implementing LoggerAwareInterface in HTTP client decorators #54674

Merged
merged 1 commit into from May 2, 2024

Conversation

xabbuh
Copy link
Member

@xabbuh xabbuh commented Apr 19, 2024

Q A
Branch? 7.1
Bug fix? no
New feature? no
Deprecations? no
Issues
License MIT

@@ -28,7 +28,7 @@
*
* @author Jérémy Derussé <jeremy@derusse.com>
*/
class RetryableHttpClient implements HttpClientInterface, LoggerAwareInterface, ResetInterface
class RetryableHttpClient implements HttpClientInterface, ResetInterface
Copy link
Member Author

Choose a reason for hiding this comment

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

Implementing the LoggerAwareInterface when the constructor already receives a logger doesn't look reasonable to me.

Copy link
Member Author

Choose a reason for hiding this comment

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

I also wonder if we shouldn't change the other decorators to let them optionally receive a logger in their constructor too instead of implementing the LoggerAwareInterface

Copy link
Member Author

Choose a reason for hiding this comment

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

doing so would also allow us to revert the composer.json changes

@xabbuh xabbuh force-pushed the pr-54668 branch 2 times, most recently from bbc39d2 to 3d39484 Compare April 19, 2024 11:51
@@ -46,6 +46,10 @@ public function __construct(HttpClientInterface $client, ?RetryStrategyInterface
$this->strategy = $strategy ?? new GenericRetryStrategy();
$this->maxRetries = $maxRetries;
$this->logger = $logger;

if (null !== $logger && $this->client instanceof LoggerAwareInterface) {
$this->client->setLogger($logger);
Copy link
Member Author

Choose a reason for hiding this comment

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

I am not convinced that a decorator should actually modify the decorated HTTP client this way. IMO setting the logger is the user's responsibility when constructing the client.

@nicolas-grekas
Copy link
Member

Looking at your comments here, I wonder if we should keep #54668 or not?
Maybe @yann-eugone can tell use how he wires the client so that we understant why adding LoggerAwareInterface helps?
I'm not keen on the bump in composer.json, it'd prefer not doing it.

@yann-eugone
Copy link
Contributor

yann-eugone commented Apr 22, 2024

Sure,

On that project, constructing an HttpClientInterface is a thing that is done at runtime, because it all depend on configuration (what service you are trying to call)

final class HttpClientFactory
{
    public function __construct(
        private readonly HttpClientInterface $http,
    ) {
    }

    public function create(Config $config, LoggerInterface $logger): HttpClientInterface
    {
        $client = match (...) {
            Config::A => $this->clientA(),
            Config::B => $this->clientB(),
        };
        if ($client instanceof LoggerAwareInterface) {
            $client->setLogger($logger);
        }

        return $client;
    }

    private function clientA(): HttpClientInterface
    {
        return $this->http->withOptions([
            ...
        ]);
    }

    private function clientB(): HttpClientInterface
    {
        return $this->http->withOptions([
            ...
        ]);
    }
}

I'm using Symfony\Contracts\HttpClient\HttpClientInterface::withOptions because it's way safer for unit testing to clone a client provided from a constructor than having to build from the ground.

As you can see, the $logger is provided in the factory method, because each feature has it's own logger instance, but they all share dependency on HttpClientFactory

#[WithMonologChannel('feature1')]
final class Feature1
{
    public function __construct(
        private readonly HttpClientFactory $httpClientFactory,
        private readonly LoggerInterface $logger,
    ) {
    }

    public function method(Config $config): void
    {
        $http = $this->httpClientFactory->create($config, $this->logger);
        ...
    }
}

#[WithMonologChannel('feature2')]
final class Feature2
{
    public function __construct(
        private readonly HttpClientFactory $httpClientFactory,
        private readonly LoggerInterface $logger,
    ) {
    }

    public function method(Config $config): void
    {
        $http = $this->httpClientFactory->create($config, $this->logger);
        ...
    }
}

I've only proposed adding LoggerAwareInterface because I saw that actual clients already implemented it, so I believed it was just about someone forgetting to add it everywhere.

@OskarStark

This comment was marked as outdated.

@OskarStark OskarStark changed the title [FrameworkBundle] wire setLogger() calls for registered HTTP clients [FrameworkBundle] wire setLogger() calls for registered HTTP clients Apr 22, 2024
@yann-eugone

This comment was marked as outdated.

@xabbuh
Copy link
Member Author

xabbuh commented Apr 24, 2024

What about supporting passing the logger to withOptions() instead? This could look something like this in your factory then:

private function clientA(LoggerInterface $logger): HttpClientInterface
{
    return $this->http->withOptions([
        'extra' => [
            'logger' => $logger,
        ],
        // ...
    ]);
}

@nicolas-grekas
Copy link
Member

I wonder if we need this PR at all: to me, the actual http client that does log should already have the logger wired. Did you check this aspect?

@xabbuh xabbuh force-pushed the pr-54668 branch 2 times, most recently from 8ae7a05 to 436bf31 Compare April 30, 2024 09:10
@xabbuh xabbuh changed the title [FrameworkBundle] wire setLogger() calls for registered HTTP clients [HttpClient] revert implementing LoggerAwareInterface in HTTP client decorators Apr 30, 2024
@xabbuh
Copy link
Member Author

xabbuh commented Apr 30, 2024

to me, the actual http client that does log should already have the logger wired

I agree with this reasoning. That's why I suggest to revert implementing the LoggerAwareInterface in HTTP client decorators.

@yann-eugone
Copy link
Contributor

I don't have any opinion on this honestly
But why removing setLogger on decorated clients, but not on actual ones ?

@xabbuh
Copy link
Member Author

xabbuh commented Apr 30, 2024

The actual clients do use the logger themselves. They do not use this property to configure another client. We can argue if using the interface was the right decision back when we introduced it, but that’s a different topic.

@xabbuh xabbuh added the ❄️ Feature Freeze Important Pull Requests to finish before the next Symfony "feature freeze" label May 2, 2024
@carsonbot carsonbot changed the title [HttpClient] revert implementing LoggerAwareInterface in HTTP client decorators [FrameworkBundle] revert implementing LoggerAwareInterface in HTTP client decorators May 2, 2024
Copy link
Member

@nicolas-grekas nicolas-grekas left a comment

Choose a reason for hiding this comment

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

🚀

We could even deprecate existing setLogger proxies.

@fabpot
Copy link
Member

fabpot commented May 2, 2024

Thank you @xabbuh.

@fabpot fabpot merged commit fa77dc6 into symfony:7.1 May 2, 2024
8 of 10 checks passed
@xabbuh xabbuh deleted the pr-54668 branch May 2, 2024 08:57
@xabbuh
Copy link
Member Author

xabbuh commented May 2, 2024

We could even deprecate existing setLogger proxies.

see #54806

fabpot added a commit that referenced this pull request May 2, 2024
…ing clients (xabbuh)

This PR was merged into the 7.1 branch.

Discussion
----------

[HttpClient]  deprecate setLogger() methods of decorating clients

| Q             | A
| ------------- | ---
| Branch?       | 7.1
| Bug fix?      | no
| New feature?  | no
| Deprecations? | yes
| Issues        | Fix #54674 (review)
| License       | MIT

Commits
-------

9d95152 deprecate setLogger() methods of decorating clients
@fabpot fabpot mentioned this pull request May 2, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
FrameworkBundle ❄️ Feature Freeze Important Pull Requests to finish before the next Symfony "feature freeze" Status: Reviewed
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants