Merge "Identity plugin thread safety"
This commit is contained in:
@@ -235,3 +235,10 @@ can be retrieved.
|
|||||||
|
|
||||||
The most simple example of a plugin is the
|
The most simple example of a plugin is the
|
||||||
:py:class:`keystoneclient.auth.token_endpoint.Token` plugin.
|
:py:class:`keystoneclient.auth.token_endpoint.Token` plugin.
|
||||||
|
|
||||||
|
When writing a plugin you should ensure that any fetch operation is thread
|
||||||
|
safe. A common pattern is for a service to hold a single service authentication
|
||||||
|
plugin globally and re-use that between all threads. This means that when a
|
||||||
|
token expires there may be multiple threads that all try to fetch a new plugin
|
||||||
|
at the same time. It is the responsibility of the plugin to ensure that this
|
||||||
|
case is handled in a way that still results in correct reauthentication.
|
||||||
|
@@ -12,6 +12,7 @@
|
|||||||
|
|
||||||
import abc
|
import abc
|
||||||
import logging
|
import logging
|
||||||
|
import threading
|
||||||
import warnings
|
import warnings
|
||||||
|
|
||||||
from oslo_config import cfg
|
from oslo_config import cfg
|
||||||
@@ -54,6 +55,7 @@ class BaseIdentityPlugin(base.BaseAuthPlugin):
|
|||||||
self.reauthenticate = reauthenticate
|
self.reauthenticate = reauthenticate
|
||||||
|
|
||||||
self._endpoint_cache = {}
|
self._endpoint_cache = {}
|
||||||
|
self._lock = threading.Lock()
|
||||||
|
|
||||||
self._username = username
|
self._username = username
|
||||||
self._password = password
|
self._password = password
|
||||||
@@ -236,6 +238,12 @@ class BaseIdentityPlugin(base.BaseAuthPlugin):
|
|||||||
:returns: Valid AccessInfo
|
:returns: Valid AccessInfo
|
||||||
:rtype: :py:class:`keystoneclient.access.AccessInfo`
|
:rtype: :py:class:`keystoneclient.access.AccessInfo`
|
||||||
"""
|
"""
|
||||||
|
# Hey Kids! Thread safety is important particularly in the case where
|
||||||
|
# a service is creating an admin style plugin that will then proceed
|
||||||
|
# to make calls from many threads. As a token expires all the threads
|
||||||
|
# will try and fetch a new token at once, so we want to ensure that
|
||||||
|
# only one thread tries to actually fetch from keystone at once.
|
||||||
|
with self._lock:
|
||||||
if self._needs_reauthenticate():
|
if self._needs_reauthenticate():
|
||||||
self.auth_ref = self.get_auth_ref(session)
|
self.auth_ref = self.get_auth_ref(session)
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user