On 2/06/2013 11:08 p.m., Amos Jeffries wrote:
On 7/04/2013 5:48 p.m., Amos Jeffries wrote:
What this does is convert ErrorState object to using the generic
libformat.la parser and macro expansions instead of its own rather
limited custom ones for error pages and deny_info URL creation.
Alex: If possible could you guys throw this through WebPolygraph to
see if the different in parsing shows up at all?
I'm checking the performance variance for error-only workload now.
FTR: Testing on a 1.4GHz CPU with configuration of only "http_access
deny all" and flooding requests at it using ApacheBench with 1000, 5000,
and 10000 requests at concurrency 1, 5, 10, and 20. With and without the
patch.
That very basic test indicates that the extra lag added by this is on
the order of 0.15-0.2 ms per request. Raising the response time in a
DoS-like flood of rejected traffic from 2.11ms to 2.25ms average (some
6% speed reduction) and the req/sec capacity limit drops by 1.5 req/sec
for each N of concurrent requests. Since the only critical case affected
is DoS error responses this does seem to be acceptible for merging as-is
provided teh code passed audit. But long-term I still think we can do
better than 2ms response time by implementing the optimizations outlined
below which should grab back the capacity loss and then some.
Change Summary:
1) register the 1-byte error page macros as libformat codes
2) convert the ErrorState::Convert macro expander to use those codes
instead of char literals
3) extend the libformat to handle several process-wide informational
macros and a human-readabhe RFC1123 time format
4) extend the Format::assemble method to call the adapted
ErrorState::Convert function when it encounters byte codes requiring
ErrorState special handling
5) convert the ErrorState::ConvertText and
ErrorState::DenyInfoLocation methods to use the libformat API to
parse and assemble the output page
NOTES on problems remaining:
*a) Several of the error page macros are better served by other
logformat macro expansions. However on some the interaction between
deny_info and ERR_* template usages has required that the
ErrorState::Convert logics be used for now.
*b) Doing a whole parse cycle for every error response is very
costly. We are already loading the text page files on every error
response. This adds the un-optimized libformat parser lag on top of
that. To avoid this we really need to add a cache for error page
templates and strings, such that each one is only loaded and parsed
once. From that we can more speedily assemble the expansions final
output.
*c) For now AccessLogEntry required by the libformat API is generated
by ErrorState just before use. Ideally the code creating the
ErrorState should pass it an already filled out ALE object for the
transaction. This way we will get a lot more of the libformat macros
filled out. That is done in a few places where easily possible, but
many places still cannot do it. This restricts the format codes which
will work on any given error.
Amos