summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJenkins <jenkins@review.openstack.org>2012-11-03 16:04:23 +0000
committerGerrit Code Review <review@openstack.org>2012-11-03 16:04:23 +0000
commitc008557b9f9acb278085683cfaafeb67e1eba8d9 (patch)
tree3b292aad094a0666a79fb8567aa594a072e5c31a
parent3a6a67f6a374142cece7190b5ddfa4444208c13e (diff)
parent94560ab57d9fc23673f42017e6f2a78cb2b66b7a (diff)
downloadnova-c008557b9f9acb278085683cfaafeb67e1eba8d9.tar.gz
nova-c008557b9f9acb278085683cfaafeb67e1eba8d9.tar.xz
nova-c008557b9f9acb278085683cfaafeb67e1eba8d9.zip
Merge "Eliminates simultaneous schedule race."
-rw-r--r--nova/scheduler/host_manager.py43
-rw-r--r--nova/tests/scheduler/fakes.py8
-rw-r--r--nova/tests/scheduler/test_filter_scheduler.py2
-rw-r--r--nova/tests/scheduler/test_host_manager.py3
4 files changed, 35 insertions, 21 deletions
diff --git a/nova/scheduler/host_manager.py b/nova/scheduler/host_manager.py
index 4727c4706..fc9f3c8cc 100644
--- a/nova/scheduler/host_manager.py
+++ b/nova/scheduler/host_manager.py
@@ -96,15 +96,8 @@ class HostState(object):
def __init__(self, host, topic, capabilities=None, service=None):
self.host = host
self.topic = topic
+ self.update_capabilities(topic, capabilities, service)
- # Read-only capability dicts
-
- if capabilities is None:
- capabilities = {}
- self.capabilities = ReadOnlyDict(capabilities.get(topic, None))
- if service is None:
- service = {}
- self.service = ReadOnlyDict(service)
# Mutable available resources.
# These will change as resources are virtually "consumed".
self.total_usable_disk_gb = 0
@@ -130,8 +123,22 @@ class HostState(object):
# Resource oversubscription values for the compute host:
self.limits = {}
+ self.updated = None
+
+ def update_capabilities(self, topic, capabilities=None, service=None):
+ # Read-only capability dicts
+
+ if capabilities is None:
+ capabilities = {}
+ self.capabilities = ReadOnlyDict(capabilities.get(topic, None))
+ if service is None:
+ service = {}
+ self.service = ReadOnlyDict(service)
+
def update_from_compute_node(self, compute):
"""Update information about a host from its compute_node info."""
+ if self.updated and self.updated > compute['updated_at']:
+ return
all_ram_mb = compute['memory_mb']
# Assume virtual size is all consumed by instances if use qcow2 disk.
@@ -148,6 +155,7 @@ class HostState(object):
self.free_disk_mb = free_disk_mb
self.vcpus_total = compute['vcpus']
self.vcpus_used = compute['vcpus_used']
+ self.updated = compute['updated_at']
stats = compute.get('stats', [])
statmap = self._statmap(stats)
@@ -191,6 +199,7 @@ class HostState(object):
self.free_ram_mb -= ram_mb
self.free_disk_mb -= disk_mb
self.vcpus_used += vcpus
+ self.updated = timeutils.utcnow()
# Track number of instances on host
self.num_instances += 1
@@ -270,6 +279,7 @@ class HostManager(object):
def __init__(self):
self.service_states = {} # { <host> : { <service> : { cap k : v }}}
+ self.host_state_map = {}
self.filter_classes = filters.get_filter_classes(
FLAGS.scheduler_available_filters)
@@ -341,8 +351,6 @@ class HostManager(object):
raise NotImplementedError(_(
"host_manager only implemented for 'compute'"))
- host_state_map = {}
-
# Get resource usage across the available compute nodes:
compute_nodes = db.compute_node_get_all(context)
for compute in compute_nodes:
@@ -352,10 +360,15 @@ class HostManager(object):
continue
host = service['host']
capabilities = self.service_states.get(host, None)
- host_state = self.host_state_cls(host, topic,
- capabilities=capabilities,
- service=dict(service.iteritems()))
+ host_state = self.host_state_map.get(host)
+ if host_state:
+ host_state.update_capabilities(topic, capabilities,
+ dict(service.iteritems()))
+ else:
+ host_state = self.host_state_cls(host, topic,
+ capabilities=capabilities,
+ service=dict(service.iteritems()))
+ self.host_state_map[host] = host_state
host_state.update_from_compute_node(compute)
- host_state_map[host] = host_state
- return host_state_map
+ return self.host_state_map
diff --git a/nova/tests/scheduler/fakes.py b/nova/tests/scheduler/fakes.py
index 29466fbe1..ba255c32c 100644
--- a/nova/tests/scheduler/fakes.py
+++ b/nova/tests/scheduler/fakes.py
@@ -28,19 +28,19 @@ from nova.scheduler import host_manager
COMPUTE_NODES = [
dict(id=1, local_gb=1024, memory_mb=1024, vcpus=1,
disk_available_least=512, free_ram_mb=512, vcpus_used=1,
- free_disk_mb=512, local_gb_used=0,
+ free_disk_mb=512, local_gb_used=0, updated_at=None,
service=dict(host='host1', disabled=False)),
dict(id=2, local_gb=2048, memory_mb=2048, vcpus=2,
disk_available_least=1024, free_ram_mb=1024, vcpus_used=2,
- free_disk_mb=1024, local_gb_used=0,
+ free_disk_mb=1024, local_gb_used=0, updated_at=None,
service=dict(host='host2', disabled=True)),
dict(id=3, local_gb=4096, memory_mb=4096, vcpus=4,
disk_available_least=3072, free_ram_mb=3072, vcpus_used=1,
- free_disk_mb=3072, local_gb_used=0,
+ free_disk_mb=3072, local_gb_used=0, updated_at=None,
service=dict(host='host3', disabled=False)),
dict(id=4, local_gb=8192, memory_mb=8192, vcpus=8,
disk_available_least=8192, free_ram_mb=8192, vcpus_used=0,
- free_disk_mb=8192, local_gb_used=0,
+ free_disk_mb=8192, local_gb_used=0, updated_at=None,
service=dict(host='host4', disabled=False)),
# Broken entry
dict(id=5, local_gb=1024, memory_mb=1024, vcpus=1, service=None),
diff --git a/nova/tests/scheduler/test_filter_scheduler.py b/nova/tests/scheduler/test_filter_scheduler.py
index b6bdd359b..be6bc3317 100644
--- a/nova/tests/scheduler/test_filter_scheduler.py
+++ b/nova/tests/scheduler/test_filter_scheduler.py
@@ -224,7 +224,7 @@ class FilterSchedulerTestCase(test_scheduler.SchedulerTestCase):
hostinfo.update_from_compute_node(dict(memory_mb=1000,
local_gb=0, vcpus=1, disk_available_least=1000,
free_disk_mb=1000, free_ram_mb=872, vcpus_used=0,
- local_gb_used=0))
+ local_gb_used=0, updated_at=None))
self.assertEquals(872, fn(hostinfo, {}))
def test_max_attempts(self):
diff --git a/nova/tests/scheduler/test_host_manager.py b/nova/tests/scheduler/test_host_manager.py
index 5074d188a..74c24d56b 100644
--- a/nova/tests/scheduler/test_host_manager.py
+++ b/nova/tests/scheduler/test_host_manager.py
@@ -264,7 +264,8 @@ class HostStateTestCase(test.TestCase):
dict(key='io_workload', value='42'),
]
compute = dict(stats=stats, memory_mb=0, free_disk_gb=0, local_gb=0,
- local_gb_used=0, free_ram_mb=0, vcpus=0, vcpus_used=0)
+ local_gb_used=0, free_ram_mb=0, vcpus=0, vcpus_used=0,
+ updated_at=None)
host = host_manager.HostState("fakehost", "faketopic")
host.update_from_compute_node(compute)