Browse Source

Fix the display of updated_at time when using memcache driver.

When using mc driver(set servicegroup_driver=mc), the service reports
state by memcache. but we use 'nova service-list' get the status of
services registered in nova, the 'update_at' time is not the last updated
time not as db driver. so we should get the time in memcache to update the
time in response.
Closes-Bug: #1647269

Change-Id: I1d4763436ad6de2483c39f5fe97fa6e8d283d8a3
tags/16.0.0.0b2
Tao Li 2 years ago
parent
commit
0df91a7f79

+ 3
- 1
nova/api/openstack/compute/services.py View File

@@ -71,13 +71,15 @@ class ServiceController(wsgi.Controller):
71 71
         active = 'enabled'
72 72
         if svc['disabled']:
73 73
             active = 'disabled'
74
+        updated_time = self.servicegroup_api.get_updated_time(svc)
75
+
74 76
         service_detail = {'binary': svc['binary'],
75 77
                           'host': svc['host'],
76 78
                           'id': svc['id'],
77 79
                           'zone': svc['availability_zone'],
78 80
                           'status': active,
79 81
                           'state': state,
80
-                          'updated_at': svc['updated_at'],
82
+                          'updated_at': updated_time,
81 83
                           'disabled_reason': svc['disabled_reason']}
82 84
 
83 85
         for field in additional_fields:

+ 4
- 0
nova/servicegroup/api.py View File

@@ -78,3 +78,7 @@ class API(object):
78 78
             return False
79 79
 
80 80
         return self._driver.is_up(member)
81
+
82
+    def get_updated_time(self, member):
83
+        """Get the updated time from drivers except db"""
84
+        return self._driver.updated_time(member)

+ 4
- 0
nova/servicegroup/drivers/base.py View File

@@ -27,3 +27,7 @@ class Driver(object):
27 27
     def is_up(self, member):
28 28
         """Check whether the given member is up."""
29 29
         raise NotImplementedError()
30
+
31
+    def updated_time(self, service_ref):
32
+        """Get the updated time"""
33
+        raise NotImplementedError()

+ 4
- 0
nova/servicegroup/drivers/db.py View File

@@ -79,6 +79,10 @@ class DbDriver(base.Driver):
79 79
                        'lhb': str(last_heartbeat), 'el': str(elapsed)})
80 80
         return is_up
81 81
 
82
+    def updated_time(self, service_ref):
83
+        """Get the updated time from db"""
84
+        return service_ref['updated_at']
85
+
82 86
     def _report_state(self, service):
83 87
         """Update the state of this service in the datastore."""
84 88
 

+ 16
- 0
nova/servicegroup/drivers/mc.py View File

@@ -17,6 +17,7 @@
17 17
 # See the License for the specific language governing permissions and
18 18
 # limitations under the License.
19 19
 
20
+import iso8601
20 21
 from oslo_log import log as logging
21 22
 from oslo_utils import timeutils
22 23
 
@@ -67,6 +68,21 @@ class MemcachedDriver(base.Driver):
67 68
 
68 69
         return is_up
69 70
 
71
+    def updated_time(self, service_ref):
72
+        """Get the updated time from memcache"""
73
+        key = "%(topic)s:%(host)s" % service_ref
74
+        updated_time_in_mc = self.mc.get(str(key))
75
+        updated_time_in_db = service_ref['updated_at']
76
+
77
+        if updated_time_in_mc:
78
+            # Change mc time to offset-aware time
79
+            updated_time_in_mc = \
80
+                updated_time_in_mc.replace(tzinfo=iso8601.iso8601.Utc())
81
+            if updated_time_in_db <= updated_time_in_mc:
82
+                return updated_time_in_mc
83
+
84
+        return updated_time_in_db
85
+
70 86
     def _report_state(self, service):
71 87
         """Update the state of this service in the datastore."""
72 88
         try:

+ 11
- 0
nova/tests/unit/servicegroup/test_api.py View File

@@ -60,3 +60,14 @@ class ServiceGroupApiTestCase(test.NoDBTestCase):
60 60
         result = self.servicegroup_api.service_is_up(member)
61 61
         self.assertIs(result, False)
62 62
         driver.is_up.assert_not_called()
63
+
64
+    def test_get_updated_time(self):
65
+        member = {"host": "fake-host",
66
+                  "topic": "compute",
67
+                  "forced_down": False}
68
+        retval = "2016-11-02T22:40:31.000000"
69
+
70
+        driver = self.servicegroup_api._driver
71
+        driver.updated_time = mock.MagicMock(return_value=retval)
72
+        result = self.servicegroup_api.get_updated_time(member)
73
+        self.assertEqual(retval, result)

+ 11
- 0
nova/tests/unit/servicegroup/test_db_servicegroup.py View File

@@ -106,3 +106,14 @@ class DBServiceGroupTestCase(test.NoDBTestCase):
106 106
 
107 107
     def test_report_state_unexpected_error(self):
108 108
         self._test_report_state_error(RuntimeError)
109
+
110
+    def test_get_updated_time(self):
111
+        retval = "2016-11-02T22:40:31.000000"
112
+        service_ref = {
113
+            'host': 'fake-host',
114
+            'topic': 'compute',
115
+            'updated_at': retval
116
+        }
117
+
118
+        result = self.servicegroup_api.get_updated_time(service_ref)
119
+        self.assertEqual(retval, result)

+ 28
- 0
nova/tests/unit/servicegroup/test_mc_servicegroup.py View File

@@ -15,10 +15,12 @@
15 15
 #    License for the specific language governing permissions and limitations
16 16
 #    under the License.
17 17
 
18
+import iso8601
18 19
 import mock
19 20
 
20 21
 from nova import servicegroup
21 22
 from nova import test
23
+from oslo_utils import timeutils
22 24
 
23 25
 
24 26
 class MemcachedServiceGroupTestCase(test.NoDBTestCase):
@@ -63,3 +65,29 @@ class MemcachedServiceGroupTestCase(test.NoDBTestCase):
63 65
         fn(service)
64 66
         self.mc_client.set.assert_called_once_with('compute:fake-host',
65 67
                                                    mock.ANY)
68
+
69
+    def test_get_updated_time(self):
70
+        updated_at_time = timeutils.parse_strtime("2016-04-18T02:56:25.198871")
71
+        service_ref = {
72
+            'host': 'fake-host',
73
+            'topic': 'compute',
74
+            'updated_at': updated_at_time.replace(tzinfo=iso8601.iso8601.Utc())
75
+        }
76
+
77
+        self.mc_client.get.return_value = None
78
+        self.assertEqual(service_ref['updated_at'],
79
+                         self.servicegroup_api.get_updated_time(service_ref))
80
+        self.mc_client.get.assert_called_once_with('compute:fake-host')
81
+        self.mc_client.reset_mock()
82
+        retval = timeutils.utcnow()
83
+        self.mc_client.get.return_value = retval
84
+        self.assertEqual(retval.replace(tzinfo=iso8601.iso8601.Utc()),
85
+                         self.servicegroup_api.get_updated_time(service_ref))
86
+        self.mc_client.get.assert_called_once_with('compute:fake-host')
87
+        self.mc_client.reset_mock()
88
+        service_ref['updated_at'] = \
89
+            retval.replace(tzinfo=iso8601.iso8601.Utc())
90
+        self.mc_client.get.return_value = updated_at_time
91
+        self.assertEqual(service_ref['updated_at'],
92
+                         self.servicegroup_api.get_updated_time(service_ref))
93
+        self.mc_client.get.assert_called_once_with('compute:fake-host')

Loading…
Cancel
Save