Skip to content

Commit 247b879

Browse files
Improve concurrency handling for deleting networks
1 parent 7895aec commit 247b879

2 files changed

Lines changed: 33 additions & 28 deletions

File tree

meraki/rest_session.py

Lines changed: 33 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,22 @@ def user_agent_extended(be_geo_id, caller):
5555

5656

5757
# Main module interface
58+
def check_python_version():
59+
# Check minimum Python version
60+
version_warning_string = f'This library requires Python 3.7 at minimum. Python versions 3.6 and below ' \
61+
f'are end of life and end of support per the Python maintainers, and your ' \
62+
f'interpreter version details are: \n' \
63+
f'platform.python_version_tuple()[0] = {platform.python_version_tuple()[0]}\n' \
64+
f'platform.python_version_tuple()[1] = {platform.python_version_tuple()[1]}\n' \
65+
f'platform.python_version is {platform.python_version()}\n' \
66+
f'Please consult the readme at your convenience: ' \
67+
f'https://github.com/meraki/dashboard-api-python'
68+
if int(platform.python_version_tuple()[0]) != 3:
69+
sys.exit(version_warning_string)
70+
elif int(platform.python_version_tuple()[1]) < 7:
71+
sys.exit(version_warning_string)
72+
73+
5874
class RestSession(object):
5975
def __init__(
6076
self,
@@ -99,7 +115,7 @@ def __init__(
99115
self._req_session = requests.session()
100116
self._req_session.encoding = 'utf-8'
101117

102-
self.check_python_version()
118+
check_python_version()
103119

104120
# Check base URL
105121
if 'v0' in self._base_url:
@@ -126,21 +142,6 @@ def __init__(
126142
if self._logger:
127143
self._logger.info(f'Meraki dashboard API session initialized with these parameters: {self._parameters}')
128144

129-
def check_python_version(self):
130-
# Check minimum Python version
131-
version_warning_string = f'This library requires Python 3.7 at minimum. Python versions 3.6 and below ' \
132-
f'are end of life and end of support per the Python maintainers, and your ' \
133-
f'interpreter version details are: \n' \
134-
f'platform.python_version_tuple()[0] = {platform.python_version_tuple()[0]}\n' \
135-
f'platform.python_version_tuple()[1] = {platform.python_version_tuple()[1]}\n' \
136-
f'platform.python_version is {platform.python_version()}\n' \
137-
f'Please consult the readme at your convenience: ' \
138-
f'https://github.com/meraki/dashboard-api-python'
139-
if int(platform.python_version_tuple()[0]) != 3:
140-
sys.exit(version_warning_string)
141-
elif int(platform.python_version_tuple()[1]) < 7:
142-
sys.exit(version_warning_string)
143-
144145
@property
145146
def use_iterator_for_get_pages(self):
146147
return self._use_iterator_for_get_pages
@@ -268,14 +269,28 @@ def request(self, metadata, method, url, **kwargs):
268269
else:
269270
try:
270271
message = response.json()
272+
message_is_dict = True
271273
except ValueError:
272274
message = response.content[:100]
275+
message_is_dict = False
273276

274-
# Check specifically for action batch concurrency error
277+
# Check for specific concurrency errors
278+
network_delete_concurrency_error_text = 'This may be due to concurrent requests to delete networks.'
275279
action_batch_concurrency_error = {'errors': [
276280
'Too many concurrently executing batches. Maximum is 5 confirmed but not yet executed batches.']
277281
}
278-
if message == action_batch_concurrency_error:
282+
# Check specifically for network delete concurrency error
283+
if message_is_dict and 'errors' in message.keys() \
284+
and network_delete_concurrency_error_text in message['errors'][0]:
285+
wait = self._action_batch_retry_wait_time
286+
if self._logger:
287+
self._logger.warning(f'{tag}, {operation} - {status} {reason}, retrying in {wait} seconds')
288+
time.sleep(wait)
289+
retries -= 1
290+
if retries == 0:
291+
raise APIError(metadata, response)
292+
# Check specifically for action batch concurrency error
293+
elif message == action_batch_concurrency_error:
279294
wait = self._action_batch_retry_wait_time
280295
if self._logger:
281296
self._logger.warning(f'{tag}, {operation} - {status} {reason}, retrying in {wait} seconds')

tests/test_dashboard_api_python_library.py

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -208,14 +208,4 @@ def test_delete_policy_objects(dashboard, org_id, version_salt):
208208

209209
def test_delete_network(dashboard, network):
210210
response = dashboard.networks.deleteNetwork(network['id'])
211-
212-
total_wait = 0
213-
max_wait = 120
214-
215-
while response is not None and total_wait <= max_wait:
216-
wait_time = random.randint(1, 20)
217-
time.sleep(wait_time)
218-
response = dashboard.networks.deleteNetwork(network['id'])
219-
total_wait += wait_time
220-
221211
assert response is None

0 commit comments

Comments
 (0)