)]}'
{"shade/openstackcloud.py":[{"author":{"_account_id":1,"name":"James E. Blair","email":"jim@acmegating.com","username":"corvus"},"change_message_id":"739ba8cbbfe104239fea13cd185231fa6d485a2d","unresolved":false,"context_lines":[{"line_number":1465,"context_line":"            # a lock, and the non-blocking acquire method will cause"},{"line_number":1466,"context_line":"            # subsequent threads to just skip this and use the old"},{"line_number":1467,"context_line":"            # data until it succeeds."},{"line_number":1468,"context_line":"            # Initially when we never got data, block to retrieve some data."},{"line_number":1469,"context_line":"            if self._ports_lock.acquire(self._ports is None):"},{"line_number":1470,"context_line":"                try:"},{"line_number":1471,"context_line":"                    self._ports \u003d self._list_ports(filters)"}],"source_content_type":"text/x-python","patch_set":2,"id":"fa6399be_f87fcd63","line":1468,"updated":"2016-10-19 14:04:33.000000000","message":"# Save whether we think this is the first run or not.\n            first_run \u003d self._ports is None","commit_id":"53c305f304df7388545f0d2bcad94452493f5d8e"},{"author":{"_account_id":1,"name":"James E. Blair","email":"jim@acmegating.com","username":"corvus"},"change_message_id":"739ba8cbbfe104239fea13cd185231fa6d485a2d","unresolved":false,"context_lines":[{"line_number":1466,"context_line":"            # subsequent threads to just skip this and use the old"},{"line_number":1467,"context_line":"            # data until it succeeds."},{"line_number":1468,"context_line":"            # Initially when we never got data, block to retrieve some data."},{"line_number":1469,"context_line":"            if self._ports_lock.acquire(self._ports is None):"},{"line_number":1470,"context_line":"                try:"},{"line_number":1471,"context_line":"                    self._ports \u003d self._list_ports(filters)"},{"line_number":1472,"context_line":"                    self._ports_time \u003d time.time()"}],"source_content_type":"text/x-python","patch_set":2,"id":"fa6399be_18972191","line":1469,"updated":"2016-10-19 14:04:33.000000000","message":"if self._ports_lock.acquire(first_run):","commit_id":"53c305f304df7388545f0d2bcad94452493f5d8e"},{"author":{"_account_id":1,"name":"James E. Blair","email":"jim@acmegating.com","username":"corvus"},"change_message_id":"739ba8cbbfe104239fea13cd185231fa6d485a2d","unresolved":false,"context_lines":[{"line_number":1467,"context_line":"            # data until it succeeds."},{"line_number":1468,"context_line":"            # Initially when we never got data, block to retrieve some data."},{"line_number":1469,"context_line":"            if self._ports_lock.acquire(self._ports is None):"},{"line_number":1470,"context_line":"                try:"},{"line_number":1471,"context_line":"                    self._ports \u003d self._list_ports(filters)"},{"line_number":1472,"context_line":"                    self._ports_time \u003d time.time()"},{"line_number":1473,"context_line":"                finally:"}],"source_content_type":"text/x-python","patch_set":2,"id":"fa6399be_389225a0","line":1470,"updated":"2016-10-19 14:04:33.000000000","message":"# If we entered the lock thinking that we had to because this was\n                    # the first run, self._ports will either be None if it is *still*\n                    # the first run, or it will be not-None if some other thread beat\n                    # us to it.\n                    if first_run and self._ports is not None:\n                        # Some other thread beat us to it, so just return its result.\n                        return self._ports\n                    # We are still the first run, so carry on.\n\nWe don\u0027t need to update the first_run variable -- it is only used to decide among all of the threads in the initial thundering herd which will be the one to actually run.\n\nWe *do* need to check the status of self._ports again once we have the lock to see if that condition is still valid (ie, see if we are the real first run, or if we actually ended up as the second or later).","commit_id":"53c305f304df7388545f0d2bcad94452493f5d8e"},{"author":{"_account_id":1,"name":"James E. Blair","email":"jim@acmegating.com","username":"corvus"},"change_message_id":"0e3c447873a715a1cb9c9f7d2de1ab364f64e00f","unresolved":false,"context_lines":[{"line_number":1467,"context_line":"            # data until it succeeds."},{"line_number":1468,"context_line":"            # Initially when we never got data, block to retrieve some data."},{"line_number":1469,"context_line":"            if self._ports_lock.acquire(self._ports is None):"},{"line_number":1470,"context_line":"                try:"},{"line_number":1471,"context_line":"                    self._ports \u003d self._list_ports(filters)"},{"line_number":1472,"context_line":"                    self._ports_time \u003d time.time()"},{"line_number":1473,"context_line":"                finally:"}],"source_content_type":"text/x-python","patch_set":2,"id":"fa6399be_8d2b2333","line":1470,"updated":"2016-10-18 14:38:26.000000000","message":"If we save self._ports is None into a variable, say \u0027first_run\u0027, we can say here:\n  if first_run and self._ports is not None:\n    return self._ports\nThat way we avoid a thundering herd of lists on startup.","commit_id":"53c305f304df7388545f0d2bcad94452493f5d8e"},{"author":{"_account_id":2,"name":"Monty Taylor","email":"mordred@inaugust.com","username":"mordred"},"change_message_id":"8d9a09e6894432a86719a6e2abd50f8574894520","unresolved":false,"context_lines":[{"line_number":1467,"context_line":"            # data until it succeeds."},{"line_number":1468,"context_line":"            # Initially when we never got data, block to retrieve some data."},{"line_number":1469,"context_line":"            if self._ports_lock.acquire(self._ports is None):"},{"line_number":1470,"context_line":"                try:"},{"line_number":1471,"context_line":"                    self._ports \u003d self._list_ports(filters)"},{"line_number":1472,"context_line":"                    self._ports_time \u003d time.time()"},{"line_number":1473,"context_line":"                finally:"}],"source_content_type":"text/x-python","patch_set":2,"id":"fa6399be_cfd4f6be","line":1470,"in_reply_to":"fa6399be_138aa2bf","updated":"2016-10-19 16:53:42.000000000","message":"Alright - I tried this:\n\nhttp://paste.openstack.org/show/586432/\n\nWhich is an application of Jim\u0027s logic from above and it works as expected for me with your test code (adding a call to shade.simple_logging(debug\u003dTrue) at the top) - with only one actual API call:\n\nmordred@camelot:~/src/openstack-infra/shade$ python jordan.py \nManager vexxhost:ca-ymq-1 running task ServerList\nManager vexxhost:ca-ymq-1 ran task ServerList in 1.31819009781s\nManager vexxhost:ca-ymq-1 running task NetworkList\nManager vexxhost:ca-ymq-1 ran task NetworkList in 0.511332035065s\nManager vexxhost:ca-ymq-1 running task SubnetList\nManager vexxhost:ca-ymq-1 ran task SubnetList in 0.199084997177s\n\nIt\u0027s important to note that these caches are controlled on a per-resource basis in the clouds.yaml config:\n\ncache:\n  expiration:\n    server: 5\n    port: 5\n    floating-ip: 5\n\nIs in mine.","commit_id":"53c305f304df7388545f0d2bcad94452493f5d8e"},{"author":{"_account_id":7350,"name":"Jordan Pittier","email":"jordan.pittier@gmail.com","username":"JordanP"},"change_message_id":"ce45b24222a9c80190ad9e18a1ae0267add055d3","unresolved":false,"context_lines":[{"line_number":1467,"context_line":"            # data until it succeeds."},{"line_number":1468,"context_line":"            # Initially when we never got data, block to retrieve some data."},{"line_number":1469,"context_line":"            if self._ports_lock.acquire(self._ports is None):"},{"line_number":1470,"context_line":"                try:"},{"line_number":1471,"context_line":"                    self._ports \u003d self._list_ports(filters)"},{"line_number":1472,"context_line":"                    self._ports_time \u003d time.time()"},{"line_number":1473,"context_line":"                finally:"}],"source_content_type":"text/x-python","patch_set":2,"id":"fa6399be_138aa2bf","line":1470,"in_reply_to":"fa6399be_389225a0","updated":"2016-10-19 14:31:47.000000000","message":"I tried your suggestion and run:\n\npython -c \"\nimport os_client_config, shade, concurrent.futures\n\ncloud \u003d os_client_config.make_shade(cloud\u003d\u0027devstack\u0027)   \nwith concurrent.futures.ThreadPoolExecutor(8) as exec:\n    for i in range(8):\n        exec.submit(lambda: print(len(cloud.list_servers())))\n\"\n\nThis command will make 8 queries to Nova API, so the \"storm\" effect is still here.","commit_id":"53c305f304df7388545f0d2bcad94452493f5d8e"},{"author":{"_account_id":7350,"name":"Jordan Pittier","email":"jordan.pittier@gmail.com","username":"JordanP"},"change_message_id":"c91419b4ea190771fccefa634c4573ad496d0e31","unresolved":false,"context_lines":[{"line_number":1467,"context_line":"            # data until it succeeds."},{"line_number":1468,"context_line":"            # Initially when we never got data, block to retrieve some data."},{"line_number":1469,"context_line":"            if self._ports_lock.acquire(self._ports is None):"},{"line_number":1470,"context_line":"                try:"},{"line_number":1471,"context_line":"                    self._ports \u003d self._list_ports(filters)"},{"line_number":1472,"context_line":"                    self._ports_time \u003d time.time()"},{"line_number":1473,"context_line":"                finally:"}],"source_content_type":"text/x-python","patch_set":2,"id":"fa6399be_61730c16","line":1470,"in_reply_to":"fa6399be_3abb2410","updated":"2016-10-19 13:01:07.000000000","message":"if self_ports is *not* none, self._ports is never updated then ?","commit_id":"53c305f304df7388545f0d2bcad94452493f5d8e"},{"author":{"_account_id":7350,"name":"Jordan Pittier","email":"jordan.pittier@gmail.com","username":"JordanP"},"change_message_id":"fdde399d3fa651d333e9de96ab4e00f39f56cfe5","unresolved":false,"context_lines":[{"line_number":1467,"context_line":"            # data until it succeeds."},{"line_number":1468,"context_line":"            # Initially when we never got data, block to retrieve some data."},{"line_number":1469,"context_line":"            if self._ports_lock.acquire(self._ports is None):"},{"line_number":1470,"context_line":"                try:"},{"line_number":1471,"context_line":"                    self._ports \u003d self._list_ports(filters)"},{"line_number":1472,"context_line":"                    self._ports_time \u003d time.time()"},{"line_number":1473,"context_line":"                finally:"}],"source_content_type":"text/x-python","patch_set":2,"id":"fa6399be_f6b9c0ed","line":1470,"in_reply_to":"fa6399be_8d2b2333","updated":"2016-10-18 21:54:22.000000000","message":"I am not I understand. How/where would you update this \u0027first_run\u0027 variable in a non-racy way ?","commit_id":"53c305f304df7388545f0d2bcad94452493f5d8e"},{"author":{"_account_id":2,"name":"Monty Taylor","email":"mordred@inaugust.com","username":"mordred"},"change_message_id":"d56b95accbfe61c4213208e2e47309cf444b60b7","unresolved":false,"context_lines":[{"line_number":1467,"context_line":"            # data until it succeeds."},{"line_number":1468,"context_line":"            # Initially when we never got data, block to retrieve some data."},{"line_number":1469,"context_line":"            if self._ports_lock.acquire(self._ports is None):"},{"line_number":1470,"context_line":"                try:"},{"line_number":1471,"context_line":"                    self._ports \u003d self._list_ports(filters)"},{"line_number":1472,"context_line":"                    self._ports_time \u003d time.time()"},{"line_number":1473,"context_line":"                finally:"}],"source_content_type":"text/x-python","patch_set":2,"id":"fa6399be_3abb2410","line":1470,"in_reply_to":"fa6399be_8d2b2333","updated":"2016-10-19 11:53:10.000000000","message":"I think it can be easier, in fact. Leave self._ports is None as the check, and put a check inside the lock of \"if self._ports is None: self._ports \u003d self._list_ports(filters)\"","commit_id":"53c305f304df7388545f0d2bcad94452493f5d8e"}]}
