Repository navigation
Conversation
vszakats
left a comment
There was a problem hiding this comment.
I suggest moving the 3 new functions within tool_operate.c as static ones.
And remove the double newlines (nit).
I put them in there because of this sentence in the CONTRIBUTE.md
I'll move them.
What exactly do you mean with this? What is "nit"? |
It's a minor issue, e.g. whitespace. |
e546506 to
61ea829
Compare
|
It's all in tool_operate.c now and no more double new line between functions. |
a048e91 to
f69d70b
Compare
|
It's using origin now instead of host as per your request. |
fd2ec2f to
3098f22
Compare
|
Issues fixed. Can I pull the http response out of the if/else or is there a deeper reason why it's declared in both those blocks instead of outside? |
|
It is helpful if you select "resolve conversation" for the remarks you think are are addressed. Otherwise it looks like all remarks are still pending... |
4de7304 to
9c93701
Compare
|
Resolved all conversations and it's using curl_msnprintf() now. No checks for the return value of this function as I've seen it done plenty of times in other places like that. |
bagder
left a comment
There was a problem hiding this comment.
A primary reason for the revert was the complaint on lifetime management. The 429 list may live longer than the individual transfers so the origin pointers might then point to freed memory. Won't they?
| goto clean; | ||
|
|
||
| urlerr: | ||
| origin = curlx_strdup("-/-/-"); |
There was a problem hiding this comment.
Can you elaborate on why it sets a dummy origin if one of the URL API functions fail? When is that useful?
There was a problem hiding this comment.
It's useful when the URL is invalid. This will be handled at a later stage and with a dummy it will get to that later stage where other valid URLs will still be processed.
There was a problem hiding this comment.
I think this needs a test case to prove that this is the best way. It does not make sense to me.
The list is cleaned up right after the transfers are cleaned up, I don't see where the list items would be used after the transfers are over. |
|
I changed it so the list is using a copy of the origin from the transfers. |
bagder
left a comment
There was a problem hiding this comment.
We need a test or two for this feature to make sure it works now and to make sure we don't accidentally break it the future.
| goto clean; | ||
|
|
||
| urlerr: | ||
| origin = curlx_strdup("-/-/-"); |
There was a problem hiding this comment.
I think this needs a test case to prove that this is the best way. It does not make sense to me.
| break; | ||
|
|
||
| /* store the origin in the per transfer struct for 429 delay checks */ | ||
| result = set_per_transfer_origin(per->url, &per->origin); |
There was a problem hiding this comment.
Why create this unconditionally and use lots of allocations for all transfers unconditionally when it is only needed for 429 responses? Why not wait and create the origin once and if it is needed?
There was a problem hiding this comment.
If I return an error at this point instead of creating a generic host/port/scheme curl will exit with the error instead of processing the valid URL after the invalid one.
For example if I give a list like this:
https://example.com
htps:exampl.com
http://not-an-example.com
Nothing will be downloaded despite 2 of the 3 URLs being valid.
I created this unconditionally because otherwise the URL will be parsed all the time. I had it initially like that, I can go back to that one.
If I have to redo this, then I also have to update the translate of URL errors to general curl errors as I ran into such an issue when I had it like that. So please tell me clearly which way you want it so I don't have to then redo it again.
There was a problem hiding this comment.
I created this unconditionally because otherwise the URL will be parsed all the time.
Why would it? if you get a 429 and ->origin is a NULL, you can populate the ->origin then. If it would come back to that condition later, ->origin would already be populated and you don't need to parse the URL again.
The point being that you avoid URL parsing for all the URLs that never get a 429.
There was a problem hiding this comment.
Oh I understand now. So still use the per struct but only fill it on 429 error. Yeah, that makes sense. I didn't use the per struct at all before that's why there was a ton of URL parsing which rubbed me the wrong way.
I will change it that way, but as I said to do this properly and to get rid of the "-/-/-" thingy which rubbed you the wrong way 😝 I need to redo the URLerror to CURLerror translation function because some errors are not translated properly and just result in CURLE_OK.
| len_origin = strlen(host) + strlen(port) + strlen(scheme) + 3; | ||
| origin = curlx_malloc(len_origin); |
There was a problem hiding this comment.
avoid strlen, malloc and snprintf by:
| len_origin = strlen(host) + strlen(port) + strlen(scheme) + 3; | |
| origin = curlx_malloc(len_origin); | |
| origin = curl_maprintf("%s/%s/%s", host, port, scheme); | |
| if(!origin) { |
There was a problem hiding this comment.
You told me to use msnprintf, that's why I used it.
what do you think about using curl_msnprintf() instead to avoid three memcpy()s ?
What about this in docs/examples/.checksrc:
# Use of curl printf functions is discouraged
banfunc curl_maprintf
There was a problem hiding this comment.
What about this in docs/examples/.checksrc:
This applies to example code. It's built differently and reflects
different practices than core/test code.
There was a problem hiding this comment.
You told me to use msnprintf, that's why I used it.
Then the conditions were different or I didn't understand what you were asking. We prefer avoiding "raw" allocs + fiddling and rather use functions that handle it themselves.
|
As for the test. We discussed this in the IRC and it's non trivial to test this. This is why I wrote a small test script for myself on my server and local machine to check if the behaviour is how I expect it to be. |
We still need tests. I think its worth spending some extra effort on that. A test that first returns a 429 and then a 200 shouldn't be too hard to add and would at least confirm that the basics do what they're supposed to do. |
That doesn't properly test it. The test needs to check if others are still going through while the 429 one is blocked for a certain amount of time otherwise the code isn't really tested. Because of the async and parallel nature of it, the output of the test isn't trivial to check. I'll be gone for the weekend, but after that I can show how I "manually" tested it so far. Maybe you can then add a testcase to your server that will properly test this, I wasn't able to get anything done with the existing functions, I tried several months ago. |
It would be a first miniature attempt to at least exercise some of the code. I won't stop you from doing better ones. |
the list's lifetime is tied to the pre->transfers, so when the origin living in per-transfer will be freed the list is freed too.
The HTTP error 429 delay list needs some extra allocs. The limit is increased in tests: 142,440,445,767
|
|
||
| /* The retry delay for 429 applies to all requests to the same origin. | ||
| Update the global 429 delay list for this origin. */ | ||
| if(http_error == 429) { |
There was a problem hiding this comment.
If curl is not doing parallel downloads, this PR does nothing for the 429 responses so it seems unnecessary to add them to a list that is never used. Doesn't it?
| if(item && (time(NULL) < item->startat)) { | ||
| per->startat = item->startat; | ||
| per->added = FALSE; | ||
| sleeping = TRUE; |
There was a problem hiding this comment.
Should this also log something to the output to help explain to users what's going on ?
| </protocol> | ||
| <limits> | ||
| Allocations: 180 | ||
| Allocations: 190 |
There was a problem hiding this comment.
None of these Allocations changes should be needed anymore, right?
|
They way it currently is, is broken. It is how I initially said. Either you use memory or you do the calculation every time. Now it's only using memory when the error happens but all the transfers who are about to fire do not have the information and therefore fire away. So every transfer still needs the URL to be parsed and then checked against the list for it to work this way. As I said, I don't want to run from Pontius to Pilatus and back all the time, that's why I didn't change anything further. |
|
There's been almost three months and this now merge-conflicts. Are you still working on this @htasta2 ? Please do not think that conversations on IRC is better than here. They are ephemeral and hard for people to join in, while discussions here stick to this particular PR. |
|
Abandoned |
Don't start new transfers to the same host if this host has returned a 429 error.
The --retry-delay setting is used for all transfers to the same host on error 429.