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

Skip to content

[Console][Lock] Allow LockableTrait to use custom stores #31914

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
wants to merge 12 commits into from

Conversation

stixx
Copy link

@stixx stixx commented Jun 6, 2019

Q A
Branch? 4.4
Bug fix? no
New feature? yes
BC breaks? no
Deprecations? no
Tests pass? yes
Fixed tickets n/a
License MIT
Doc PR n/a

This PR adds the possibility to inject a custom store which implements the StoreInterface in a command by doing the following:

  • Configure a default store in the configuration of Symfony;
  • Adding the LockableTrait to the command;
  • Adding the marker interface LockableInterface to the command;

Symfony configuration:

lock:
    resources:
        default: flock

If those two conditions are met in the AddConsoleCommandPass, the setStore method will be called and the store of choice will be set.

I had difficulty choosing the best solution while keeping simplicity in tact. A different solution would be to add this functionality to the base command (Symfony\Component\Console\Command\Command) and make it configurable.

If no store is configured the LockableTrait will work as it was, by either giving the SemaphoreStore or the FlockStore.

@chalasr chalasr added Console and removed Lock labels Jun 7, 2019
@chalasr chalasr added this to the next milestone Jun 7, 2019
@stixx stixx changed the title [Lock] Allow LockableTrait to use custom stores [Console][Lock] Allow LockableTrait to use custom stores Jun 7, 2019
Copy link
Member

@chalasr chalasr left a comment

Choose a reason for hiding this comment

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

Some comments. Thank you for the PR.


$storeDefinition = 'lock.default.store';
if ($container->hasDefinition($storeDefinition)) {
if (\method_exists($definition->getClass(), 'setStore')) {
Copy link
Member

Choose a reason for hiding this comment

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

I'm a bit unsure about injecting the store based on method existence.
This is about autoconfiguration which usually works on types, and traits are not types. Should we add a marker LockableInterface and use it as a type for ContainerBuilder::registerForAutoconfiguration()?

*
* @param StoreInterface $store
*/
public function setStore(StoreInterface $store)
Copy link
Contributor

Choose a reason for hiding this comment

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

what about passing a non-default store as optional 3rd arg in lock()? and avoid this state issue.

Copy link
Contributor

Choose a reason for hiding this comment

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

meaning the user injects his own store if needed

Copy link
Author

@stixx stixx Jun 17, 2019

Choose a reason for hiding this comment

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

If that's the case then this change wouldn't be needed because you can implement the Symfony\Component\Lock\Factory service in a command by dependency injection to create locks.

Copy link
Contributor

Choose a reason for hiding this comment

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

Right ... the user can also set private $store; already.Then, im not sure what we're solving here 🤔

We should favor pure DI / service usage IMHO.

Copy link
Author

Choose a reason for hiding this comment

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

I'm trying to solve a configurable store that can be used in commands, this can either be done by:

  • The current solution (setStore in LockableTrait);
  • Implementing a default store in Symfony\Component\Console\Command\Command;
  • Writing a LockableCommand class which basically does what LockableTrait does now, so this could mean bye bye for LockableTrait - would also mean more abstraction;

Why?

Because currently LockableTrait is limited to SemaphoreStore and FlockStore. Also you can use dependency injection but that would mean that you have to overwrite the constructor. Last, it's not configurable as in available in a command by default.

Copy link
Contributor

Choose a reason for hiding this comment

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

you can use dependency injection but that would mean that you have to overwrite the constructor.

Is that a real problem? IMHO it's the explicit way.. compared to calling an arbitrary setStore method. At least i agree with https://github.com/symfony/symfony/pull/31914/files#r294103123; if we do this we should add a marker interface for it.

Copy link
Author

Choose a reason for hiding this comment

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

I agree that we should be using a marker interface. I've updated the PR.

Jelle van Oosterbosch added 3 commits June 21, 2019 20:23
@stixx stixx force-pushed the set-store-in-lockable-trait branch from 045a7ac to bbfb8aa Compare June 21, 2019 18:23
@stixx
Copy link
Author

stixx commented Jun 28, 2019

Bump, requesting new review after proposed changes.

@fabpot
Copy link
Member

fabpot commented Jul 8, 2019

@jderusse Can you have a look at this PR?

Copy link
Member

@jderusse jderusse left a comment

Choose a reason for hiding this comment

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

Wonder if the marker couldn't be replaced by a autowired setter?

trait LockableTrait 
{
  /**
   * @required
   */
  public function setStore(StoreInterface $store)
  {
    $this->store = $store;
  }
}

class OverrideStoreCommand 
{
  use LockableTrait;

  /**
   * @required
   */
  public function setStore(StoreInterface $notdefaultLockStore)
  {
    $this->store = $store;
  }
}

use Symfony\Component\Lock\Store\FlockStore;
use Symfony\Component\Lock\Store\SemaphoreStore;
use Symfony\Component\Lock\StoreInterface;
Copy link
Member

Choose a reason for hiding this comment

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

beware, the interface has been renamed in #32198

@nicolas-grekas
Copy link
Member

No need to add a setter, named autowiring aliases can be used instead.

@nicolas-grekas nicolas-grekas modified the milestones: next, 5.1 May 4, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants