Re: [haproxy/haproxy] OPTIM/MINOR: h2_settings_initial_window_size default 64k (PR #1732)

2022-06-07 Thread Glenn Strauss
On Tue, Jun 07, 2022 at 09:27:43AM -0700, Willy Tarreau wrote:
> Hello Glenn,
> 
> Thanks for your report, I understand the problem, that's very interesting. I 
> would say it's not even an optim, rather an approach trying to help the whole 
> ecosystem at a very low cost by preventing known degenerative cases from 
> happening (or helping them recover).

Reference to issue (for the list)
https://github.com/haproxy/haproxy/pull/1732
https://github.com/nghttp2/nghttp2/issues/1722
https://github.com/curl/curl/pull/8965

Summary: degenerative HTTP/2 client behavior sending mostly 1-byte DATA
frames for a fast client which continually exhausts the HTTP/2 send
window (e.g. for a large file upload) *and* for a simple client which
empties and reuses a single power-2 sized buffer.  A simple server
sending WINDOW_UPDATE for each DATA frame to replenish the window may
reflect back the exact size of the DATA frame.

> However I don't fully agree with the solution, it might just push the issue a 
> bit sidewards.

Changing the default SETTINGS_INITIAL_WINDOW_SIZE does push the issue a
bit sideways, but in doing so mitigates a demonstrated (not theoretical)
issue which might befall 6+ years of curl installations, a sizable
number of which might not be upgraded for a very long time.

> For example a client might already have worked around this issue by using a 
> 65537-bytes buffer and will now face issues again.

I do not follow.  How might that be?
Also, do you know of any such implementations?

For a slightly more intelligent client actively trying to avoid the
degenerative behavior, a simple approach is to avoid injecting tiny DATA
frames when the window is larger and there is more data to be sent.  I
have proposed a patch to curl in https://github.com/curl/curl/pull/8965

The default SETTINGS_MAX_FRAME_SIZE is 16384.

My proposed change in https://github.com/haproxy/haproxy/pull/1732
merely changes the default SETTINGS_INITIAL_WINDOW_SIZE in haproxy
from 65535 to be 64k, a multiple of the default SETTINGS_MAX_FRAME_SIZE.
This provides a general benefit and avoids the degenerative behavior
described in the links at top.

> Thus I'd first prefer to solve it at the core, then possibly merge this patch 
> later as an optimization but nor for the problem, rather to make sure clients 
> can make 4 full 16kB frames, and improve bandwidth and CPU efficiency.

Yes, having the server merge the sizes of small DATA frames into a
larger WINDOW_UPDATE might be useful, too, but is independent and
complimentary to my patch proposed in
https://github.com/haproxy/haproxy/pull/1732

> Given the nature of the problem, I don't imagine we'd meet this issue with 
> interleaved 1-byte frames from multiple streams over the same connection.

Actually, haproxy sets the session window size to be a very large
number, effectively removing HTTP/2 application-level flow-control
at the session level.  That leaves independent streams with the
default SETTINGS_INITIAL_WINDOW_SIZE of 65535, so multiple uploads
can independently exhaust the stream send window and run into this
degenerative behavior provided the client is fast enough, the bandwidth
delay product is large enough, and the client is fully emptying a
power-2 sized buffer before reusing it.

> I'm thinking how we could improve the situation on our side by sending less 
> common window updates. Right now we send the stream WU after reading a frame 
> because of the likelihood that the next frame is not for the same stream and 
> that we lose track of which stream needs to be updated. We can change this to 
> only send a single frame for a number of subsequent frames from the same 
> stream, it will solve the problem for the case you're facing and will be more 
> friendly to the client. Given the nature of the problem, I don't imagine we'd 
> meet this issue with interleaved 1-byte frames from multiple streams over the 
> same connection. If that were the case we'd then need to send less updates, 
> waiting for a sub-divider to be crossed (e.g. check when 1/16th of the max 
> frame size is crossed). But here I really don't think we'd need to go that 
> far and I think that sending grouped updates will be sufficient.

One approach might be to collect small DATA frames and send a
WINDOW_UPDATE once a threshold is reached.  The upcoming lighttpd 1.4.65
does just that, collecting updates until 16384 is reached, and then
sending a WINDOW_UPDATE for 16384.  Cost: a single 1-RTT delay in
sending a WINDOW_UPDATE to continue uploads larger than 112k-1.

Another approach might be to pre-emptively effectively double the
window size by sending WINDOW_UPDATE with the entire window size (65535)
back to the client upon receive of first DATA frame, and then keeping
track on server-side until that 65535 is exhausted before sending
another WINDOW_UPDATE.  Again, instead of 65535, I would recommend a
65536 or other multiple of SETTINGS_MAX_FRAME_SIZE.

Cheers, Glenn



INVITATION TO ATTEND A WORKSHOP ON RESEARCH DESIGN, MOBILE DATA COLLECTION AND MAPPING AND DATA ANALYSIS USING NVIVO AND R ON 4TH to 15TH JULY 2022

2022-06-07 Thread Skills for Africa Training Institute



WORKSHOP ON RESEARCH DESIGN, 
MOBILE DATA COLLECTION AND MAPPING AND DATA ANALYSIS USING NVIVO AND R ON 
4TH to 15TH JULY 2022


Register for 
online workshop attendance 
 


Register to attend the 
workshop


 


Calendar for 2022 
Workshops
 


Contact 
us
 


Whatapp
 
VENUE: 
WESTON HOTEL, NAIROBI, KENYA
Office 
Telephone: +254-702-249-449
Register 
as a group of 5 or more participants and get 25% discount on the course fee. 

Send 
us an email: 

train...@skillsforafrica.org or 
call +254-702-249-449
INTRODUCTION
New 
developments in data science offer a tremendous opportunity to improve 
decision-making. In the development world, there has been an increase in 
the number of data gathering initiative such as baseline surveys, 
Socio-Economic Surveys, Demographic and Health Surveys, Nutrition Surveys, Food 
Security Surveys, Program Evaluation Surveys, Employees, customers and vendor 
satisfaction surveys, and opinion polls among others, all intended to provide 
data for decision making.
It 
is essential that these efforts go beyond merely generating new insights from 
data but also to systematically enhance individual human judgment in real 
development contexts. How can organizations better manage the process of 
converting the potential of data science to real development outcomes. This ten 
days’ hands-on course is tailored to put all these important considerations 
into 
perspective. It is envisioned that upon completion, the participants will be 
empowered with the necessary skills to produce accurate and cost effective data 
and reports that are useful and friendly for decision making. It will be 
conducted using ODK, GIS, NVIVO and R.
COURSE 
OBJECTIVES
At 
the end of course participants should be able to:
·   Understand 
and appropriately use statistical terms and concepts
·   Design and 
Implement universally acceptable Surveys
·   Convert 
data into various formats using appropriate software
·   Use 
mobile data gathering tools such as Open Data 
Kit (ODK)
·   Use 
GIS software to plot and display data on basic maps
·   Qualitative 
data analysis using NVIVO
·   Analyze 
t data by applying appropriate statistical techniques using 
R
·   Interpret 
the statistical analysis using R
·   Identify 
statistical techniques a best suited to data and questions
·   Strong 
foundation in fundamental statistical concepts
·   Implement 
different statistical analysis in R and interpret the 
results
·   Build 
intuitive data visualizations
·   Carry 
out formalized hypothesis testing
·   Implement 
linear modelling techniques such multiple regressions and 
GLMs
·   Implement 
advanced regression analysis and multivariate analysis
·   Write 
reports from survey data
·   Put 
strategies to improve data demand and use in decision 
making
DURATION
10 
Days
WHO 
SHOULD ATTEND
This 
is a general course targeting participants with elementary knowledge of 
Statistics from Agriculture, Economics, Food Security and Livelihoods, 
Nutrition, Education, Medical or public health professionals among others who 
already have some statistical knowledge, but wish to be conversant with the 
concepts and applications of statistical 

[PR] OPTIM/MINOR: h2_settings_initial_window_size default 64k

2022-06-07 Thread PR Bot
Dear list!

Author: Glenn Strauss 
Number of patches: 1

This is an automated relay of the Github pull request:
   OPTIM/MINOR: h2_settings_initial_window_size default 64k

Patch title(s): 
   OPTIM/MINOR: h2_settings_initial_window_size default 64k

Link:
   https://github.com/haproxy/haproxy/pull/1732

Edit locally:
   wget https://github.com/haproxy/haproxy/pull/1732.patch && vi 1732.patch

Apply locally:
   curl https://github.com/haproxy/haproxy/pull/1732.patch | git am -

Description:
   OPTIM/MINOR: h2_settings_initial_window_size default 64k
   change from RFC 7540 default 65535 (64k-1)
   
   avoid some
   degenerative WINDOW_UPDATE behaviors in the wild
   https://github.com/nghttp2/nghttp2/issues/1722

Instructions:
   This github pull request will be closed automatically; patch should be
   reviewed on the haproxy mailing list (haproxy@formilux.org). Everyone is
   invited to comment, even the patch's author. Please keep the author and
   list CCed in replies. Please note that in absence of any response this
   pull request will be lost.



Re: Rate Limiting with token/leaky bucket algorithm

2022-06-07 Thread Seena Fallah
Got it!
Thanks. Works like a charm =)

On Tue, 7 Jun 2022 at 17:50, Willy Tarreau  wrote:

> On Tue, Jun 07, 2022 at 01:51:06PM +0200, Seena Fallah wrote:
> > I also tried with this one but this will give me 20req/s 200 OK and the
> > rest of it 429 too many requests
> > ```
> > listen test
> > bind :8000
> > stick-table  type ip  size 100k expire 30s store http_req_rate(1s)
> > acl exceeds_limit src_http_req_rate gt 100
> > http-request track-sc0 src unless exceeds_limit
> > http-request deny deny_status 429 if exceeds_limit
> > http-request return status 200 content-type "text/plain" lf-string
> "200
> > OK"
> > ```
> >
> > Maybe the "1s" isn't handled correctly? when I fetch the current value
> for
> > the http_req_rate it is 100 so that makes sense other requests get 429
> but
> > actually, only 20req/s is responding "200" because the http_req_rate is
> not
> > decreasing in the correct intervals!
>
> There is a reason to this, which is subtle: the counter is updated when
> the track action is performed. As such, each new request refreshes the
> counter and the counter reports the total number of *received* requests
> and not the number of accepted requests.
>
> There are different ways to deal with this, usually they involve a check
> *before* the track. With your config it's trivial since you're already
> using src_http_req_rate which performs its own lookup. Just move the
> track_sc rule at the end and it should be OK.
>
> Willy
>


Re: Rate Limiting with token/leaky bucket algorithm

2022-06-07 Thread Willy Tarreau
On Tue, Jun 07, 2022 at 01:51:06PM +0200, Seena Fallah wrote:
> I also tried with this one but this will give me 20req/s 200 OK and the
> rest of it 429 too many requests
> ```
> listen test
> bind :8000
> stick-table  type ip  size 100k expire 30s store http_req_rate(1s)
> acl exceeds_limit src_http_req_rate gt 100
> http-request track-sc0 src unless exceeds_limit
> http-request deny deny_status 429 if exceeds_limit
> http-request return status 200 content-type "text/plain" lf-string "200
> OK"
> ```
> 
> Maybe the "1s" isn't handled correctly? when I fetch the current value for
> the http_req_rate it is 100 so that makes sense other requests get 429 but
> actually, only 20req/s is responding "200" because the http_req_rate is not
> decreasing in the correct intervals!

There is a reason to this, which is subtle: the counter is updated when
the track action is performed. As such, each new request refreshes the
counter and the counter reports the total number of *received* requests
and not the number of accepted requests.

There are different ways to deal with this, usually they involve a check
*before* the track. With your config it's trivial since you're already
using src_http_req_rate which performs its own lookup. Just move the
track_sc rule at the end and it should be OK.

Willy



Re: [PATCH] DOC/MINOR: Suggestions for percent encoding in param()

2022-06-07 Thread Tim Düsterhus

Thayne,

this patch should be squashed with the previous 2/2 patch.

On 6/4/22 06:46, astrotha...@gmail.com wrote:

+  Note that this converter doesn't do anything special with url encoded 
characters. If
+  you want to decode the value, you can use the url_dec converter on the 
output. If
+  the name of the paramater in the input might contain encoded characters, 
you'll probably


There's a typo here: paramater


+  want do normalize the input before calling param. This can be done using


You should quote "param" here to indicate that it's a keyword. This also 
applies to urlp above (which is part of the 2/2 patch).


Best regards
Tim Düsterhus



Re: Rate Limiting with token/leaky bucket algorithm

2022-06-07 Thread Seena Fallah
I also tried with this one but this will give me 20req/s 200 OK and the
rest of it 429 too many requests
```
listen test
bind :8000
stick-table  type ip  size 100k expire 30s store http_req_rate(1s)
acl exceeds_limit src_http_req_rate gt 100
http-request track-sc0 src unless exceeds_limit
http-request deny deny_status 429 if exceeds_limit
http-request return status 200 content-type "text/plain" lf-string "200
OK"
```

Maybe the "1s" isn't handled correctly? when I fetch the current value for
the http_req_rate it is 100 so that makes sense other requests get 429 but
actually, only 20req/s is responding "200" because the http_req_rate is not
decreasing in the correct intervals!

On Fri, 3 Jun 2022 at 17:44, Seena Fallah  wrote:

> Do you see any diff between my conf and the one in the link? :/
>
> On Fri, 3 Jun 2022 at 17:37, Aleksandar Lazic  wrote:
>
>> Hi.
>>
>> On Fri, 3 Jun 2022 17:12:25 +0200
>> Seena Fallah  wrote:
>>
>> > When using the below config to have 100req/s rate-limiting after passing
>> > the 100req/s all of the reqs will deny not reqs more than 100req/s!
>> > ```
>> > listen test
>> > bind :8000
>> > stick-table  type ip  size 100k expire 30s store http_req_rate(1s)
>> > http-request track-sc0 src
>> > http-request deny deny_status 429 if { sc_http_req_rate(0) gt 100 }
>> > http-request return status 200 content-type "text/plain" lf-string
>> "200
>> > OK"
>> > ```
>> >
>> > Is there a way to deny reqs more than 100 not all of them?
>> > For example, if we have 1000req/s, 100reqs get "200 OK" and the rest of
>> > them (900reqs) gets "429"?
>>
>> Yes.
>>
>> Here are some examples with explanation.
>> https://www.haproxy.com/blog/four-examples-of-haproxy-rate-limiting/
>>
>> Here some search outputs, maybe some of the examples helps you to.
>> https://html.duckduckgo.com/html?q=haproxy%20rate%20limiting
>>
>> Regards
>> Alex
>>
>