Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Add docs for the Lock component#7364

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
javiereguiluz merged 9 commits intosymfony:masterfromjderusse:lock-component
Apr 24, 2017

Conversation

@jderusse
Copy link
Member

Copy link
Member

@javiereguiluzjaviereguiluz left a comment

Choose a reason for hiding this comment

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

I've left lots of comments ... but they are for very minor typos. Overall this doc is in good shape!

@jderusse thanks for implementing this feature and documenting it!

The Lock Component
====================

The Lock Component provides a mechanism to garentee an exclusive access into

Choose a reason for hiding this comment

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

garentee ->guarantee

Then, you can ask to this store to create a Lock for your ``resource``.

The :method:`Symfony\\Component\\Lock\\LockInterface::acquire` method tries to
acquire the lock. If the lock is can not be acquired, the method throws a

Choose a reason for hiding this comment

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

is can not ->can not

The :method:`Symfony\\Component\\Lock\\LockInterface::acquire` method tries to
acquire the lock. If the lock is can not be acquired, the method throws a
:class:`Symfony\\Component\\Lock\\Exception\\LockConflictedException`. You can
safly call the ``acquire()`` method several time, even if you already acquired

Choose a reason for hiding this comment

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

safly ->safely

Choose a reason for hiding this comment

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

several time ->several times

use Symfony\Component\Lock\Exception\LockConflictedException;

$store = new SemaphoreStore();
$lock = $store->createLock('hello');

Choose a reason for hiding this comment

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

This component may be tricky to understand to some people, so I recomment to use realistic code samples (in other words, replacehello,foo,bar with real-world looking examples).

Copy link
MemberAuthor

Choose a reason for hiding this comment

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

I'll fix it.
Do you think aKey Concepts introduction on top of this page (like in the cache component) would be usefull?

// the resource "hello" is already locked by another process
}

The first argument of `createLock` is a string representation of the

Choose a reason for hiding this comment

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

Double backticks forcreateLock

That's why, when you create a lock on an expirable ``Store``. You have to choose
carrefully the correct TTL. When too low, you take the risk to "loose" the lock
(and someone else acquire it) wheras you don't finish your task.
When too hight and the process crash before you call the ``release()`` method,

Choose a reason for hiding this comment

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

hight ->high


.. tip::

To avoid to let the Lock in a locking state, try to always release an

Choose a reason for hiding this comment

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

To avoid to let ->To avoid letting

To avoid to let the Lock in a locking state, try to always release an
expirable lock by wraping the job in a try/catch block for instance.


Choose a reason for hiding this comment

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

Extra blank line here



When you have to work on a really long task, you should not set the TTL to
overlaps the duration of this task. Instead, the Lock Component expose a

Choose a reason for hiding this comment

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

overlaps ->overlap

``Stores`` are classes that implement :class:`Symfony\\Component\\Lock\\StoreInterface`.
This component provides several adapters ready to use in your applications.

Here is a small summary of availanble ``Stores`` and theire capabilities.

Choose a reason for hiding this comment

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

availanble ->available

Choose a reason for hiding this comment

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

theire ->their

@jderusse
Copy link
MemberAuthor

Thank you@javiereguiluz for this review.

Do you think this page should be split into several sub-pages? for instance, one page for advanced usage (expiration, blocking....) and one for listing stores?
Or there is not enought content and a single page is better?

@javiereguiluz
Copy link
Member

@jderusse about splitting this into several pages ... we usually start with one page and split if needed later. For now the docs of this component are not too long, so I guess we can keep the single page doc for now.

SemaphoreStore
~~~~~~~~~~~~~~

The SemaphoreStore uses the PHP semaphore function to lock a ``resources``.

Choose a reason for hiding this comment

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

This phrase is confusing"the PHP semaphore function" ... because PHP doesn't have asemaphore() function, right?

Copy link
MemberAuthor

Choose a reason for hiding this comment

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

You're right, I was thinking aboutPHP semaphore function**s** is it more clear? Or should I rewrite the sentence?


$lock->acquire(true);

Expirable Locks

Choose a reason for hiding this comment

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

I have some doubts about theExpirable word. "Official" dictionaries don't include it, but Internet dictionaries include it. In any case, after readingthis discussion maybe it's a good idea to rename it toExpiring Locks.

The key is that "expirable lock" means "it can expire" (maybe it will expire or maybe it will not) whereas "expiring lock" means "it will expire" (it's 100% sure that this lock will expire).

single: Components; Lock

The Lock Component
====================
Copy link
Member

Choose a reason for hiding this comment

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

Too many==

$lock->acquire(true);

Expiring Locks
---------------
Copy link
Member

Choose a reason for hiding this comment

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

extra-

If you want to share a lock in several services. You have to share the
instance of Lock returned by the ``Factory::createLock`` method.

Blocking locks
Copy link
Member

Choose a reason for hiding this comment

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

Missing cap tolocks

Expiring Locks
---------------

Working with a remote ``Store`` is hard. There is now way for the remote
Copy link
Member

Choose a reason for hiding this comment

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

no way?

---------------

Working with a remote ``Store`` is hard. There is now way for the remote
``Store`` to know if the locker process is till alive.
Copy link
Member

Choose a reason for hiding this comment

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

still?

``release()`` method will be called, which would cause a ``resource`` to be locked
infinitely.

To fill this gap, the remote ``Stores`` provide an expiration mechanism: The
Copy link
Member

Choose a reason for hiding this comment

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

Store?


To fill this gap, the remote ``Stores`` provide an expiration mechanism: The
lock is acquired for a defined amount of time (named TTL for Time To Live).
When the timeout occurred, the lock is automatically released even if the locker
Copy link
Member

Choose a reason for hiding this comment

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

occurs?

FlockStore
~~~~~~~~~~

The FlockStore use the fileSystem on the local computer to lock and store the
Copy link
Member

Choose a reason for hiding this comment

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

uses

~~~~~~~~~~

The FlockStore use the fileSystem on the local computer to lock and store the
``resource``. It does not supports expiration, but the lock is automatically
Copy link
Member

Choose a reason for hiding this comment

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

support


.. caution::

Beware, some filesystem (like some version of NFS) does not support locking.
Copy link
Member

Choose a reason for hiding this comment

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

filesystems do not

~~~~~~~~~~~~~~

The MemcachedStore stores state of ``resource`` in a Memcached server. This
``Store`` does not support blocking, and expect a TLL to avoid infinity locks.
Copy link
Member

Choose a reason for hiding this comment

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

expects


.. note::

Memcached does not supports TTL lower than 1 seconds.
Copy link
Member

Choose a reason for hiding this comment

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

support

Copy link
Member

Choose a reason for hiding this comment

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

1 second

@jderusse
Copy link
MemberAuthor

Comment addressed.
Thank you@fabpot

@jderussejderusse changed the title[WIP][WCM] Add docs for the Lock component[WCM] Add docs for the Lock componentFeb 17, 2017
Copy link
Contributor

@HeahDudeHeahDude left a comment

Choose a reason for hiding this comment

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

Thank you for this great component and docs, I'm looking forward to have a use case to play with this.
I'm sorry again as I've left many minor comments here too, I've made some suggestions to avoid using "you" as much as possible.

-----

Locks are used to guarantee exclusive access to some shared resource. In
Symfony applications, you can use locks for example to ensure that a command is
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 locks" => "locks can be used"

Copy link
MemberAuthor

Choose a reason for hiding this comment

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

It would be redundant with the first sentenceLocks are used... don't you think?

Symfony applications, you can use locks for example to ensure that a command is
not executed more than once at the same time (on the same or different servers).

In order to manage the state of locks, you first need to create a ``Store``
Copy link
Contributor

Choose a reason for hiding this comment

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

"you first need to create aStore" => "aStore needs to be created first"

Copy link
MemberAuthor

Choose a reason for hiding this comment

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

With this change, I've the feeling that the rest of the sentence is weird:a Store needs to be created first and then use the Symfony\Component\Lock\Factory class ... WDYT?

$store = new SemaphoreStore();
$factory = new Factory($store);

Then, call to the :method:`Symfony\\Component\\Lock\\LockInterface::acquire`
Copy link
Contributor

Choose a reason for hiding this comment

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

"Then, a call ... will try to"

$lock->release();
}

If the lock can not be acquired, the method returns ``false``. You can safely
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 safely call theacquire() method repeatedly" => "Theacquire() method can be safely called repeatedly"

}

If the lock can not be acquired, the method returns ``false``. You can safely
call the ``acquire()`` method repeatedly, even if you already acquired it.
Copy link
Contributor

Choose a reason for hiding this comment

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

"even if you already acquired it" => "even if the lock is already acquired"

.. caution::

Beware that some file systems (such as some types of NFS) do not support
locking. In those cases, it's better to use a local file or a remote store
Copy link
Contributor

Choose a reason for hiding this comment

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

a local file?

MemcachedStore
~~~~~~~~~~~~~~

The MemcachedStore saves locks on a Memcached server, so first you must create
Copy link
Contributor

Choose a reason for hiding this comment

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

"so first you must create a Memcached connection implements the\Memcached class."
=>
"it requires a Memcached connection implementing the\Memcached class."

RedisStore
~~~~~~~~~~

The RedisStore saves locks on a Redis server, so first you must create a Redis
Copy link
Contributor

Choose a reason for hiding this comment

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

Same as above.

manages several stores in sync (for example, several Redis servers). When a lock
is being acquired, it forwards the call to all the managed stores, and it
collects their responses. If a simple majority of stores have acquired the lock,
then the lock is considered as acquired; otherwise is not acquired::
Copy link
Contributor

Choose a reason for hiding this comment

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

otherwise as not acquired?


$store = new CombinedStore($stores, new ConsensusStrategy());

Instead of the simple majority strategy (``ConsensusStrategy``) you can use the
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 theUnanimousStrategy to require the lock" => "anUnanimousStrategy can be used to require the lock"

fabpot added a commit to symfony/symfony that referenced this pull requestMar 22, 2017
This PR was squashed before being merged into the 3.3-dev branch (closes#21093).Discussion----------[Lock] Create a lock component| Q             | A| ------------- | ---| Branch?       | master| Bug fix?      | no| New feature?  | yes| BC breaks?    | no| Deprecations? | no| Tests pass?   | they will| Fixed tickets |#20382| License       | MIT| Doc PR        |symfony/symfony-docs#7364This PR aim to add a new component Lock going further than the FileSystem\LockHandler by allowing remote backend (like Redis, memcache, etc)Inspired by## UsageThe simplest way to use lock is to inject an instance of a Lock in your service```phpclass MyService{    private $lock;    public function __construct(LockInterface $lock)    {        $this->lock = $lock;    }    public function run()    {        $this->lock->acquire(true);        // If I'm here, no exception had been raised. Lock is acquired        try {            // do my job        } finally {            $this->lock->release();        }    }}```Configured with something like```yamlservices:    app.my_service:        class: AppBundle\MyService        arguments:            - app.lock.my_service    app.lock.my_service:        class: Symfony\Component\Lock\Lock        factory: ['@locker', createLock]        arguments: ['my_service']```If you need to lock serveral resource on runtime, wou'll nneed to inject the LockFactory.```phpclass MyService{    private $lockFactory;    public function __construct(LockFactoryInterface $lockFactory)    {        $this->lockFactory = $lockFactory;    }    public function run()    {        foreach ($this->items as $item) {            $lock = $this->lockFactory->createLock((string) $item);            try {                $lock->acquire();            } catch (LockConflictedException $e) {                continue;            }            // When I'm here, no exception had been, raised. Lock is acquired            try {                // do my job            } finally {                $lock->release();            }        }    }}```Configured with something like```yamlservices:    app.my_service:        class: AppBundle\MyService        arguments:            - '@locker'```This component allow you to refresh an expirable lock.This is usefull, if you run a long operation split in several small parts.If you lock with a ttl for the overall operatoin time and your process crash, the lock will block everybody for the defined TTL.But thank to the refresh method, you're able to lock for a small TTL, and refresh it between each parts.```phpclass MyService{    private $lock;    public function __construct(LockInterface $lock)    {        $this->lock = $lock;    }    public function run()    {        $this->lock->acquire(true);        try {            do {                $finished = $this->performLongTask();                // Increase the expire date by 300 more seconds                $this->lock->refresh();            } while (!$finished)            // do my job        } finally {            $this->lock->release();        }    }}```## Naming anc implementation choise```$lock->acquire()vs$lock->lock()```Choose to use acquire, because this component is full of `lock` Symfony\Component\Lock\Lock::Lock` raised a E_TOO_MANY_LOCK in my head.```$lock->acquire(false);$lock->acquire(true);vs$lock->aquire()$lock->waitAndAquire()```Not a big fan of flag feature and 2. But I choose to use the blocking flag to offer a simple (and common usecase) implementation```$lock = $factory->createLock($key);$lock->acquire();vs$lock->aquire($key)```I choose to a the pool of locks implementation. It allow the user to create 2 instances and use cross lock even in the same process.```interface LockInterfacefinal class Lock implements LockInterfacevsfinal class Lock```I choose to use a Interface even if there is only one implementaiton to offer an extension point here# TODO## In this PR* [x] tests* [x] add logs* [x] offer several redis connectors* [x] try other store implementation to validate the architecture/interface## In other PR* documentation* add configuration in framework bundle* add stop watch in the debug bar* improve the combined store (takes the drift into account and elapsed time between each store)* implement other stores (memcache, ...)* use this component in session manipulation (fixes#4976)Commits-------018e0fc [Lock] Create a lock component

Instead of the simple majority strategy (``ConsensusStrategy``) an
``UnanimousStrategy`` can be used to require the lock to be acquired in all
he stores.

Choose a reason for hiding this comment

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

Should bethe instead ofhe.

@javiereguiluzjaviereguiluz changed the title[WCM] Add docs for the Lock componentAdd docs for the Lock componentMar 26, 2017
@javiereguiluz
Copy link
Member

A note to mergers: I propose to merge this as is, so we can have the docs for the Lock component as soon as possible. The integration of Lock inside the Symfony framework is still pending, so let's not wait until that is finished (we'll do that in a separate PR).

Copy link
Member

@javiereguiluzjaviereguiluz left a comment

Choose a reason for hiding this comment

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

👍

@javiereguiluz
Copy link
Member

Jérémy, what a great work you did contributing these docs and the related component code. Thanks a lot!

HeahDude reacted with thumbs up emoji

@javiereguiluzjaviereguiluz merged commit3035fe9 intosymfony:masterApr 24, 2017
javiereguiluz added a commit that referenced this pull requestApr 24, 2017
This PR was merged into the master branch.Discussion----------Add docs for the Lock componentSeesymfony/symfony#21093Commits-------3035fe9 Rename quorum into strategyd4326c0 Reduce usage of "you"d6a218c Rename quorum strategy17248e1 Remove codeblock6b6d865 Final review and some minor rewords/simplifications2498ccd Fix typod1d3b71 Fixed minor typos and syntax issues60bfe03 Fix typo6469016 Add the Lock Component
@jderussejderusse deleted the lock-component branchApril 18, 2020 10:09
Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment

Reviewers

@fabpotfabpotfabpot left review comments

@javiereguiluzjaviereguiluzjaviereguiluz approved these changes

+2 more reviewers

@WironeWironeWirone left review comments

@HeahDudeHeahDudeHeahDude approved these changes

Reviewers whose approvals may not affect merge requirements

Assignees

No one assigned

Projects

None yet

Milestone

3.3

Development

Successfully merging this pull request may close these issues.

7 participants

@jderusse@javiereguiluz@fabpot@Wirone@HeahDude@xabbuh@carsonbot

[8]ページ先頭

©2009-2025 Movatter.jp