Gary Kotton e95db00149 NSXv: ensure that locking is done with flag 'external=True'
All opertaions that are menat to be atomic should be done across
multiple API workers. This patch ensure that this is done globally.

In general the plugin can and should run with multiple API workers.

Change-Id: Ifdd4aa7b4254d4a35783d9749085405c17b038ce
2015-09-15 10:47:30 -07:00

63 lines
2.2 KiB
Python

# Copyright 2015 VMware, Inc.
# All Rights Reserved
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import os
from oslo_concurrency import lockutils
from oslo_config import cfg
from oslo_log import log
from tooz import coordination
LOG = log.getLogger(__name__)
class LockManager:
_coordinator = None
_coordinator_pid = None
_connect_string = cfg.CONF.nsxv.locking_coordinator_url
def __init__(self):
LOG.debug('LockManager initialized!')
@staticmethod
def get_lock(name, **kwargs):
if cfg.CONF.nsxv.locking_coordinator_url:
return LockManager._get_lock_distributed(name)
else:
# Ensure that external=True
kwargs['external'] = True
return LockManager._get_lock_local(name, **kwargs)
@staticmethod
def _get_lock_local(name, **kwargs):
return lockutils.lock(name, **kwargs)
@staticmethod
def _get_lock_distributed(name):
if LockManager._coordinator_pid != os.getpid():
# We should use a per-process coordinator. If PID is different
# start a new coordinator.
# While the API workers are spawned, we have to re-initialize
# a coordinator, so we validate that the PID is still the same.
LockManager._coordinator_pid = os.getpid()
LOG.debug('Initialized coordinator with connect string %s',
LockManager._connect_string)
LockManager._coordinator = coordination.get_coordinator(
LockManager._connect_string, 'vmware-neutron-plugin')
LockManager._coordinator.start()
LOG.debug('Retrieved lock for %s', name)
return LockManager._coordinator.get_lock(name)