-
Notifications
You must be signed in to change notification settings - Fork 12
Retry when safe #41
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Retry when safe #41
Changes from all commits
45d0a19
47917c5
54a5087
7f19194
b2e6b6e
74d3315
8d2aad5
ae62add
c575f84
accc697
c24086f
b00f3a7
b67dbf2
fb09bf6
7c5c938
3d591b1
25f9767
fa8dce2
cd6b318
c484269
dd80468
cb3b0a4
d370178
ea9d165
7180fd8
33768c8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,13 +21,11 @@ def __init__(self, client, key, auth=None): | |
def _iter_lines(self, _path, **kwargs): | ||
kwargs['url'] = urlpathjoin(self.url, _path) | ||
kwargs.setdefault('auth', self.auth) | ||
kwargs.setdefault('timeout', self.client.connection_timeout) | ||
if 'jl' in kwargs: | ||
kwargs['data'] = jlencode(kwargs.pop('jl')) | ||
r = self.client.session.request(**kwargs) | ||
if not r.ok: | ||
logger.debug('%s: %s', r, r.content) | ||
r.raise_for_status() | ||
|
||
r = self.client.request(**kwargs) | ||
|
||
return r.iter_lines() | ||
|
||
def apirequest(self, _path=None, **kwargs): | ||
|
@@ -37,9 +35,11 @@ def apipost(self, _path=None, **kwargs): | |
return self.apirequest(_path, method='POST', **kwargs) | ||
|
||
def apiget(self, _path=None, **kwargs): | ||
kwargs.setdefault('is_idempotent', True) | ||
return self.apirequest(_path, method='GET', **kwargs) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd set is_idempotent for GET requests here using There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I disagree, we should set the I fixed the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Interesting thinking, you accept to set idempotent on apidelete() for DELETE method, but doesn't on apiget() for GET. For me the "late as possible" is apirequest(), iter_lines() should transparently forward the idempotent kwarg to self.client.request() (a single method, not two, using same api dialect than others: a keyword argument) and callers of _iter_lines() should choose to set idempotent if needed.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
But the current use of I do see the thinking behind "let _iter_lines just forward the request parameters to the client.request". My only last, tiny, concern, if we think like that: we should set the request timeout in the client.request, not in _iter_lines, it's not the role of the resource to setup this value. I'll do as you say, we'll come back later to |
||
|
||
def apidelete(self, _path=None, **kwargs): | ||
kwargs.setdefault('is_idempotent', True) | ||
return self.apirequest(_path, method='DELETE', **kwargs) | ||
|
||
|
||
|
@@ -186,10 +186,11 @@ def save(self): | |
self._deleted.clear() | ||
if self._cached: | ||
if not self.ignore_fields: | ||
self.apipost(jl=self._data) | ||
self.apipost(jl=self._data, is_idempotent=True) | ||
else: | ||
self.apipost(jl=dict((k, v) for k, v in self._data.iteritems() | ||
if k not in self.ignore_fields)) | ||
if k not in self.ignore_fields), | ||
is_idempotent=True) | ||
|
||
def __getitem__(self, key): | ||
return self._data[key] | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,2 @@ | ||
requests>=1.0 | ||
retrying>=1.3.3 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can this conditional run into an updated urllib3 (or httplib) that got fixed with Python 3.5 ? Do we need to handle
RemoteDisconnected
error, too?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
RemoteDisconnected inherits from BadStatusLine their should be no difference,
but actually, after testing the code in python3 it appears that it triggers a different structure for the same error. Catching it would look like:
This is terrible, I'm looking at an idiomatic way to check the list of chained exception, something like:
if BadStatusLineError in all_chained_errors(err)
Thanks for the note!