diff options
| author | Jamie Lennox <jamielennox@redhat.com> | 2015-09-09 22:38:04 +1000 |
|---|---|---|
| committer | Jamie Lennox <jamielennox@redhat.com> | 2015-09-10 10:18:36 +1000 |
| commit | 556c1a6633931207370106478fa2d155fbffb126 (patch) | |
| tree | 86c8d8bcc3f43220856f434c994a41a781c02856 /keystoneclient/auth | |
| parent | 28138b588224c6b0503620ac2e24bd37dad25370 (diff) | |
| download | python-keystoneclient-556c1a6633931207370106478fa2d155fbffb126.tar.gz | |
Identity plugin thread safety
A common case is for Nova (or other service) to create a service
authentication plugin from a configuration file and then have many
greenlet threads that want to reuse that authentication. If a token
expires then many threads all try and fetch a new token to use and can
step over each other.
I was hoping for a way to put a lock in so that all plugins were thread
safe however fixing it for identity plugins solves almost all real world
situations and anyone doing non-identity plugins will have to manage
threads themselves.
Change-Id: Ib6487de7de638abc69660c851bd048a8ec177109
Closes-Bug: #1493835
Diffstat (limited to 'keystoneclient/auth')
| -rw-r--r-- | keystoneclient/auth/identity/base.py | 12 |
1 files changed, 10 insertions, 2 deletions
diff --git a/keystoneclient/auth/identity/base.py b/keystoneclient/auth/identity/base.py index 57e1723..02c4fe6 100644 --- a/keystoneclient/auth/identity/base.py +++ b/keystoneclient/auth/identity/base.py @@ -12,6 +12,7 @@ import abc import logging +import threading import warnings from oslo_config import cfg @@ -54,6 +55,7 @@ class BaseIdentityPlugin(base.BaseAuthPlugin): self.reauthenticate = reauthenticate self._endpoint_cache = {} + self._lock = threading.Lock() self._username = username self._password = password @@ -236,8 +238,14 @@ class BaseIdentityPlugin(base.BaseAuthPlugin): :returns: Valid AccessInfo :rtype: :py:class:`keystoneclient.access.AccessInfo` """ - if self._needs_reauthenticate(): - self.auth_ref = self.get_auth_ref(session) + # 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(): + self.auth_ref = self.get_auth_ref(session) return self.auth_ref |
