Re: [PATCH 57300] mod_session save optimization

2015-09-24 Thread Paul Spangler

On 8/20/2015 4:58 PM, Paul Spangler wrote:

Hello,

The bug report contains a more detailed explanation of the patch, but
there are some points I thought might lead to some discussion.

First a quick summary of the issue: mod_session writes out the session
every request even if there aren't any changes to the data. This makes
some sense when the session has a max age and the expiry value needs to
be refreshed. However, there isn't likely to be much benefit in
repeatedly refreshing the expiry by a few milliseconds, possibly
generating database traffic each time. This patch proposes a new
directive to define an interval of time where the expiry doesn't need to
be refreshed if there are no session data changes.

1. We had a hard time coming up with a name for the directive. The patch
goes with SessionExpiryUpdateInterval, being the interval of time that
may pass before updating the expiry value is required. I don't know if
there are any existing directives with a similar function that we should
mimic instead.

2. The patch includes a behavior change independent of the new directive
when using sessions without a max age: if the data hasn't changed, don't
write out the session. Most noticeably, this means new sessions that
never get data are discarded without being saved.

3. I wasn't sure how best to add tests for a new directive since the
test server won't start if the directive is missing. The patch that
includes the test changes look for the 2.5 version to know the new
directive is there, and will require a modification if/when the
directive is back-ported to 2.4 to enable the new tests.

https://bz.apache.org/bugzilla/show_bug.cgi?id=57300

Thanks for your consideration.


Quick ping on this.
--
Paul Spangler
LabVIEW R&D
National Instruments


logio problem with SSL

2015-09-24 Thread Eric Covener
I am seeing that small responses over SSL get logged before they're
flushed, couldn't this flushing be done when we see the EOR bucket in
the SSL output filter (which will cause log_transaction to run)?


Breakpoint 2, ap_logio_add_bytes_out (c=0x7fc688005428, bytes=249) at
mod_logio.c:66
66  logio_config_t *cf = ap_get_module_config(c->conn_config,
&logio_module);
(gdb) where
#0  ap_logio_add_bytes_out (c=0x7fc688005428, bytes=249) at mod_logio.c:66
#1  0x00456875 in writev_nonblocking (s=0x7fc688005210,
vec=0x7fc68cbe1590, nvec=1, bb=0x7fc678003198,
cumulative_bytes_written=0x7fc674003758, c=0x7fc688005428)
at core_filters.c:848
#2  0x00456393 in send_brigade_nonblocking (s=0x7fc688005210,
bb=0x7fc678003198, bytes_written=0x7fc674003758, c=0x7fc688005428) at
core_filters.c:738
#3  0x00456495 in send_brigade_blocking (s=0x7fc688005210,
bb=0x7fc678003198, bytes_written=0x7fc674003758, c=0x7fc688005428) at
core_filters.c:767
#4  0x00455a4c in ap_core_output_filter (f=0x7fc6740036b0,
new_bb=0x7fc678003198) at core_filters.c:556
#5  0x0043a78e in ap_pass_brigade (next=0x7fc6740036b0,
bb=0x7fc678003198) at util_filter.c:590
#6  0x7fc6929c19c3 in bio_filter_out_pass (outctx=0x7fc678003178)
at ssl_engine_io.c:139
#7  0x7fc6929c1ada in bio_filter_out_flush (bio=0x7fc6740014e0) at
ssl_engine_io.c:160
#8  0x7fc6929c2438 in bio_filter_in_read (bio=0x7fc674004570,
in=0x7fc670009ea3 "", inlen=5) at ssl_engine_io.c:477
#9  0x7fc6923f49db in BIO_read () from
/home/covener/SRC/openssl/built/lib/libcrypto.so.1.0.0
#10 0x7fc692760bfc in ssl3_read_n () from
/home/covener/SRC/openssl/built/lib/libssl.so.1.0.0
#11 0x7fc692762a0d in ssl3_read_bytes () from
/home/covener/SRC/openssl/built/lib/libssl.so.1.0.0
#12 0x7fc69275f0db in ssl3_read () from
/home/covener/SRC/openssl/built/lib/libssl.so.1.0.0
#13 0x7fc6929c2b43 in ssl_io_input_read (inctx=0x7fc674001588,
buf=0x7fc6740015d0 "GET /index.shtml HTTP/1.1\r\nUser-Agent:
curl/7.35.0\r\nHost: localhost\r\nAccept: */*\r\n\r\n", '\356'
, ...,
len=0x7fc68cbe1b10) at ssl_engine_io.c:647
#14 0x7fc6929c4c8f in ssl_io_filter_input (f=0x7fc6740035e0,
bb=0x7fc674004118, mode=AP_MODE_SPECULATIVE, block=APR_NONBLOCK_READ,
readbytes=1) at ssl_engine_io.c:1443
#15 0x0043a6c9 in ap_get_brigade (next=0x7fc6740035e0,
bb=0x7fc674004118, mode=AP_MODE_SPECULATIVE, block=APR_NONBLOCK_READ,
readbytes=1) at util_filter.c:553
#16 0x004851f0 in check_pipeline (c=0x7fc688005428,
bb=0x7fc674004118) at http_request.c:237
#17 0x00485307 in ap_process_request_after_handler
(r=0x7fc6780129f0) at http_request.c:282
#18 0x0048564e in ap_process_async_request (r=0x7fc6780129f0)
at http_request.c:363
#19 0x00485679 in ap_process_request (r=0x7fc6780129f0) at
http_request.c:373
#20 0x0048190f in ap_process_http_sync_connection
(c=0x7fc688005428) at http_core.c:210
#21 0x00481a1b in ap_process_http_connection
(c=0x7fc688005428) at http_core.c:251
#22 0x00474977 in ap_run_process_connection (c=0x7fc688005428)
at connection.c:41
#23 0x00474ea9 in ap_process_connection (c=0x7fc688005428,
csd=0x7fc688005210) at connection.c:206
#24 0x7fc6916c9742 in process_socket (thd=0x18d09f8,
p=0x7fc688005188, sock=0x7fc688005210, my_child_num=0,
my_thread_num=2, bucket_alloc=0x7fc6780008e8) at worker.c:632
#25 0x7fc6916ca534 in worker_thread (thd=0x18d09f8,
dummy=0x7fc688000b80) at worker.c:992
#26 0x7fc6a1e8cfe3 in dummy_worker (opaque=0x18d09f8) at
threadproc/unix/thread.c:142
#27 0x7fc6a1c47182 in start_thread (arg=0x7fc68cbe2700) at
pthread_create.c:312
#28 0x7fc6a197447d in clone () at
../sysdeps/unix/sysv/linux/x86_64/clone.S:111
(gdb) cont
Continuing.

-- 
Eric Covener
cove...@gmail.com


Re: logio problem with SSL

2015-09-24 Thread Eric Covener
On Thu, Sep 24, 2015 at 11:00 AM, Eric Covener  wrote:
> I am seeing that small responses over SSL get logged before they're
> flushed, couldn't this flushing be done when we see the EOR bucket in
> the SSL output filter (which will cause log_transaction to run)?


Or maybe when the EOR is added, slip a flush bucket in front of it?

-- 
Eric Covener
cove...@gmail.com


Re: logio problem with SSL

2015-09-24 Thread Yann Ylavic
On Thu, Sep 24, 2015 at 5:06 PM, Eric Covener  wrote:
> On Thu, Sep 24, 2015 at 11:00 AM, Eric Covener  wrote:
>> I am seeing that small responses over SSL get logged before they're
>> flushed, couldn't this flushing be done when we see the EOR bucket in
>> the SSL output filter (which will cause log_transaction to run)?
>
>
> Or maybe when the EOR is added, slip a flush bucket in front of it?

Wouldn't disable pipelining (and EOR purpose)?
It seems that the culprit is rather bio_filter_out_flush() called from
bio_filter_in_read()...

Regards,
Yann.


Re: logio problem with SSL

2015-09-24 Thread Eric Covener
On Thu, Sep 24, 2015 at 11:14 AM, Yann Ylavic  wrote:
> Wouldn't disable pipelining (and EOR purpose)?

Didn't consider it / never understood it well. After doing the minimum
amt of homework --  maybe check_pipeline could somehow be called early
in the EOR cleanup so this kind of flush would occur before the
transaction is logged, rather than in
ap_process_request_after_handler?


Re: logio problem with SSL

2015-09-24 Thread Yann Ylavic
On Thu, Sep 24, 2015 at 5:32 PM, Eric Covener  wrote:
> On Thu, Sep 24, 2015 at 11:14 AM, Yann Ylavic  wrote:
>> Wouldn't disable pipelining (and EOR purpose)?
>
> Didn't consider it / never understood it well. After doing the minimum
> amt of homework --  maybe check_pipeline could somehow be called early
> in the EOR cleanup so this kind of flush would occur before the
> transaction is logged, rather than in
> ap_process_request_after_handler?

How about:
Index: modules/ssl/ssl_engine_io.c
===
--- modules/ssl/ssl_engine_io.c (revision 1704850)
+++ modules/ssl/ssl_engine_io.c (working copy)
@@ -474,7 +474,8 @@
  * output is buffered) so the performance impact of doing it
  * unconditionally should be minimal.
  */
-if (bio_filter_out_flush(inctx->bio_out) < 0) {
+if (block == APR_BLOCK_READ &&
+bio_filter_out_flush(inctx->bio_out) < 0) {
 bio_filter_out_ctx_t *outctx = inctx->bio_out->ptr;
 inctx->rc = outctx->rc;
 return -1;
?


Re: logio problem with SSL

2015-09-24 Thread Eric Covener
On Thu, Sep 24, 2015 at 11:45 AM, Yann Ylavic  wrote:
> On Thu, Sep 24, 2015 at 5:32 PM, Eric Covener  wrote:
>> On Thu, Sep 24, 2015 at 11:14 AM, Yann Ylavic  wrote:
>>> Wouldn't disable pipelining (and EOR purpose)?
>>
>> Didn't consider it / never understood it well. After doing the minimum
>> amt of homework --  maybe check_pipeline could somehow be called early
>> in the EOR cleanup so this kind of flush would occur before the
>> transaction is logged, rather than in
>> ap_process_request_after_handler?
>
> How about:
> Index: modules/ssl/ssl_engine_io.c
> ===
> --- modules/ssl/ssl_engine_io.c (revision 1704850)
> +++ modules/ssl/ssl_engine_io.c (working copy)
> @@ -474,7 +474,8 @@
>   * output is buffered) so the performance impact of doing it
>   * unconditionally should be minimal.
>   */
> -if (bio_filter_out_flush(inctx->bio_out) < 0) {
> +if (block == APR_BLOCK_READ &&
> +bio_filter_out_flush(inctx->bio_out) < 0) {
>  bio_filter_out_ctx_t *outctx = inctx->bio_out->ptr;
>  inctx->rc = outctx->rc;
>  return -1;
> ?

I guess I understand your previous comment better, but wouldn't this
mean further delaying the flush, which makes it even farther away from
when the transaction was logged?


Re: logio problem with SSL

2015-09-24 Thread Yann Ylavic
On Thu, Sep 24, 2015 at 5:51 PM, Eric Covener  wrote:
> On Thu, Sep 24, 2015 at 11:45 AM, Yann Ylavic  wrote:
>>
>> How about:
>> Index: modules/ssl/ssl_engine_io.c
>> ===
>> --- modules/ssl/ssl_engine_io.c (revision 1704850)
>> +++ modules/ssl/ssl_engine_io.c (working copy)
>> @@ -474,7 +474,8 @@
>>   * output is buffered) so the performance impact of doing it
>>   * unconditionally should be minimal.
>>   */
>> -if (bio_filter_out_flush(inctx->bio_out) < 0) {
>> +if (block == APR_BLOCK_READ &&
>> +bio_filter_out_flush(inctx->bio_out) < 0) {
>>  bio_filter_out_ctx_t *outctx = inctx->bio_out->ptr;
>>  inctx->rc = outctx->rc;
>>  return -1;
>> ?
>
> I guess I understand your previous comment better, but wouldn't this
> mean further delaying the flush, which makes it even farther away from
> when the transaction was logged?

Yes, this is unrelated to the issue I guess (looks sensible, though).
What I think is destroying the EOR before the flush is the
first/leading remove_empty_buckets() in send_brigade_nonblocking().
Looking if we can get rid of it...


Re: logio problem with SSL

2015-09-24 Thread Eric Covener
On Thu, Sep 24, 2015 at 11:55 AM, Yann Ylavic  wrote:
> Yes, this is unrelated to the issue I guess (looks sensible, though).
> What I think is destroying the EOR before the flush is the
> first/leading remove_empty_buckets() in send_brigade_nonblocking().
> Looking if we can get rid of it...

I initially thought this as well, and it resembles something
potentially fishy I thought I saw in mod_h2, but I convinced myself
it's actually the EOR bucket being read/written in order (but our
response bytes are still buffered in openssl)

-- 
Eric Covener
cove...@gmail.com


Re: logio problem with SSL

2015-09-24 Thread Yann Ylavic
On Thu, Sep 24, 2015 at 5:57 PM, Eric Covener  wrote:
>
> I initially thought this as well, and it resembles something
> potentially fishy I thought I saw in mod_h2, but I convinced myself
> it's actually the EOR bucket being read/written in order (but our
> response bytes are still buffered in openssl)

The EOR is supposed to live until the response is flushed (all
buffered/previous buckets sent).
Until then, the request is still alive and waiting to be logged, yet
all its response bytes are accounted with ap_logio_add_bytes() *after*
the corresponding apr_socket_send*().

The problem is that mod_logio's cfg->r is not (anymore) reliable when
r is in the flush queue, since it may have been replaced by the next
request's post_read_request()...


Re: logio problem with SSL

2015-09-24 Thread Yann Ylavic
On Thu, Sep 24, 2015 at 6:57 PM, Yann Ylavic  wrote:
>
> The problem is that mod_logio's cfg->r is not (anymore) reliable when
> r is in the flush queue, since it may have been replaced by the next
> request's post_read_request()...

And likewise cf->r = NULL in the logio_transaction() of the
queued/destroyed request may kill the cfg->r set by the new request's
logio_post_read_request() in the meantime.


Re: logio problem with SSL

2015-09-24 Thread Eric Covener
On Thu, Sep 24, 2015 at 1:04 PM, Yann Ylavic  wrote:
> And likewise cf->r = NULL in the logio_transaction() of the
> queued/destroyed request may kill the cfg->r set by the new request's
> logio_post_read_request() in the meantime.

I guess this is broken without an output filter (vs re-using the
add_bytes optional function)


Re: logio problem with SSL

2015-09-24 Thread Eric Covener
First pass at removing having that stuff live in conn_rec by a filter
that removes itself the first time it's called:

http://people.apache.org/~covener/patches/logio-filter.c

Does not affect the status quo ordering problem where we might log a
transaction, then see the first bytes of the response go out.

On Thu, Sep 24, 2015 at 1:50 PM, Eric Covener  wrote:
> On Thu, Sep 24, 2015 at 1:04 PM, Yann Ylavic  wrote:
>> And likewise cf->r = NULL in the logio_transaction() of the
>> queued/destroyed request may kill the cfg->r set by the new request's
>> logio_post_read_request() in the meantime.
>
> I guess this is broken without an output filter (vs re-using the
> add_bytes optional function)



-- 
Eric Covener
cove...@gmail.com


Re: logio problem with SSL

2015-09-24 Thread Eric Covener
On Thu, Sep 24, 2015 at 2:07 PM, Eric Covener  wrote:
> First pass at removing having that stuff live in conn_rec by a filter
> that removes itself the first time it's called:
>
> http://people.apache.org/~covener/patches/logio-filter.c
>
> Does not affect the status quo ordering problem where we might log a
> transaction, then see the first bytes of the response go out.
>
> On Thu, Sep 24, 2015 at 1:50 PM, Eric Covener  wrote:
>> On Thu, Sep 24, 2015 at 1:04 PM, Yann Ylavic  wrote:
>>> And likewise cf->r = NULL in the logio_transaction() of the
>>> queued/destroyed request may kill the cfg->r set by the new request's
>>> logio_post_read_request() in the meantime.
>>
>> I guess this is broken without an output filter (vs re-using the
>> add_bytes optional function)

tried to improve here: http://svn.apache.org/viewvc?rev=1705134&view=rev


Re: logio problem with SSL

2015-09-24 Thread Yann Ylavic
On Thu, Sep 24, 2015 at 10:22 PM, Eric Covener  wrote:
> On Thu, Sep 24, 2015 at 2:07 PM, Eric Covener  wrote:
>> First pass at removing having that stuff live in conn_rec by a filter
>> that removes itself the first time it's called:
>>
>> http://people.apache.org/~covener/patches/logio-filter.c
>>
>> Does not affect the status quo ordering problem where we might log a
>> transaction, then see the first bytes of the response go out.
>>
>> On Thu, Sep 24, 2015 at 1:50 PM, Eric Covener  wrote:
>>> On Thu, Sep 24, 2015 at 1:04 PM, Yann Ylavic  wrote:
 And likewise cf->r = NULL in the logio_transaction() of the
 queued/destroyed request may kill the cfg->r set by the new request's
 logio_post_read_request() in the meantime.
>>>
>>> I guess this is broken without an output filter (vs re-using the
>>> add_bytes optional function)
>
> tried to improve here: http://svn.apache.org/viewvc?rev=1705134&view=rev

Nice patch, I was thinking: too bad we need a mutex here :)

How you measure things, network traces vs some custom log timestamp?
What does the following say?

Index: server/core_filters.c
===
--- server/core_filters.c(revision 1705125)
+++ server/core_filters.c(working copy)
@@ -792,6 +792,19 @@ static apr_status_t send_brigade_blocking(apr_sock
 return rv;
 }

+static request_rec *get_r(apr_bucket_brigade *bb)
+{
+apr_bucket *e;
+for (e = APR_BRIGADE_FIRST(bb);
+ e != APR_BRIGADE_SENTINEL(bb);
+ e = APR_BUCKET_NEXT(e)) {
+if (AP_BUCKET_IS_EOR(e)) {
+return e->data;
+}
+}
+return NULL;
+}
+
 static apr_status_t writev_nonblocking(apr_socket_t *s,
struct iovec *vec, apr_size_t nvec,
apr_bucket_brigade *bb,
@@ -819,6 +832,9 @@ static apr_status_t writev_nonblocking(apr_socket_
 while (bytes_written < bytes_to_write) {
 apr_size_t n = 0;
 rv = apr_socket_sendv(s, vec + offset, nvec - offset, &n);
+ap_log_cerror(APLOG_MARK, APLOG_NOTICE, 0, c,
+  "req:%pp: sent %" APR_SIZE_T_FMT " bytes",
+  get_r(bb), n);
 if (n > 0) {
 bytes_written += n;
 for (i = offset; i < nvec; ) {
Index: server/eor_bucket.c
===
--- server/eor_bucket.c(revision 1705125)
+++ server/eor_bucket.c(working copy)
@@ -32,6 +32,8 @@ static apr_status_t eor_bucket_cleanup(void *data)
 b->data = NULL;
 /* Update child status and log the transaction */
 ap_update_child_status(r->connection->sbh, SERVER_BUSY_LOG, r);
+ap_log_cerror(APLOG_MARK, APLOG_NOTICE, 0, r->connection,
+  "req:%pp: log_transaction", r);
 ap_run_log_transaction(r);
 if (ap_extended_status) {
 ap_increment_counts(r->connection->sbh, r);
--


Re: logio problem with SSL

2015-09-24 Thread Eric Covener
On Thu, Sep 24, 2015 at 5:13 PM, Yann Ylavic  wrote:
> On Thu, Sep 24, 2015 at 10:22 PM, Eric Covener  wrote:
>> On Thu, Sep 24, 2015 at 2:07 PM, Eric Covener  wrote:
>>> First pass at removing having that stuff live in conn_rec by a filter
>>> that removes itself the first time it's called:
>>>
>>> http://people.apache.org/~covener/patches/logio-filter.c
>>>
>>> Does not affect the status quo ordering problem where we might log a
>>> transaction, then see the first bytes of the response go out.
>>>
>>> On Thu, Sep 24, 2015 at 1:50 PM, Eric Covener  wrote:
 On Thu, Sep 24, 2015 at 1:04 PM, Yann Ylavic  wrote:
> And likewise cf->r = NULL in the logio_transaction() of the
> queued/destroyed request may kill the cfg->r set by the new request's
> logio_post_read_request() in the meantime.

 I guess this is broken without an output filter (vs re-using the
 add_bytes optional function)
>>
>> tried to improve here: http://svn.apache.org/viewvc?rev=1705134&view=rev
>
> Nice patch, I was thinking: too bad we need a mutex here :)
>
> How you measure things, network traces vs some custom log timestamp?
> What does the following say?
>
> Index: server/core_filters.c
> ===
> --- server/core_filters.c(revision 1705125)
> +++ server/core_filters.c(working copy)
> @@ -792,6 +792,19 @@ static apr_status_t send_brigade_blocking(apr_sock
>  return rv;
>  }
>
> +static request_rec *get_r(apr_bucket_brigade *bb)
> +{
> +apr_bucket *e;
> +for (e = APR_BRIGADE_FIRST(bb);
> + e != APR_BRIGADE_SENTINEL(bb);
> + e = APR_BUCKET_NEXT(e)) {
> +if (AP_BUCKET_IS_EOR(e)) {
> +return e->data;
> +}
> +}
> +return NULL;
> +}
> +
>  static apr_status_t writev_nonblocking(apr_socket_t *s,
> struct iovec *vec, apr_size_t nvec,
> apr_bucket_brigade *bb,
> @@ -819,6 +832,9 @@ static apr_status_t writev_nonblocking(apr_socket_
>  while (bytes_written < bytes_to_write) {
>  apr_size_t n = 0;
>  rv = apr_socket_sendv(s, vec + offset, nvec - offset, &n);
> +ap_log_cerror(APLOG_MARK, APLOG_NOTICE, 0, c,
> +  "req:%pp: sent %" APR_SIZE_T_FMT " bytes",
> +  get_r(bb), n);
>  if (n > 0) {
>  bytes_written += n;
>  for (i = offset; i < nvec; ) {
> Index: server/eor_bucket.c
> ===
> --- server/eor_bucket.c(revision 1705125)
> +++ server/eor_bucket.c(working copy)
> @@ -32,6 +32,8 @@ static apr_status_t eor_bucket_cleanup(void *data)
>  b->data = NULL;
>  /* Update child status and log the transaction */
>  ap_update_child_status(r->connection->sbh, SERVER_BUSY_LOG, r);
> +ap_log_cerror(APLOG_MARK, APLOG_NOTICE, 0, r->connection,
> +  "req:%pp: log_transaction", r);
>  ap_run_log_transaction(r);
>  if (ap_extended_status) {
>  ap_increment_counts(r->connection->sbh, r);
> --

two logs (http/https) sorted to top of autoindex here:
http://people.apache.org/~covener/

Narrow logio issue working good now, because our first filter
invocation is not delayed like the "addbytes" callback was.


Re: logio problem with SSL

2015-09-24 Thread Yann Ylavic
On Fri, Sep 25, 2015 at 12:22 AM, Eric Covener  wrote:
>
> two logs (http/https) sorted to top of autoindex here:
> http://people.apache.org/~covener/
>
> Narrow logio issue working good now, because our first filter
> invocation is not delayed like the "addbytes" callback was.

Looks like mod_ssl should also forward EOR buckets.

Does this work:
Index: modules/ssl/ssl_engine_io.c
===
--- modules/ssl/ssl_engine_io.c(revision 1705160)
+++ modules/ssl/ssl_engine_io.c(working copy)
@@ -1707,12 +1707,12 @@ static apr_status_t ssl_io_filter_output(ap_filter
 /* If it is a flush or EOS, we need to pass this down.
  * These types do not require translation by OpenSSL.
  */
-if (APR_BUCKET_IS_EOS(bucket)) {
+if (APR_BUCKET_IS_EOS(bucket) || AP_BUCKET_IS_EOR(bucket)) {
 /*
- * By definition, nothing can come after EOS.
+ * By definition, nothing can come after EOS/EOR.
  * which also means we can pass the rest of this brigade
  * without creating a new one since it only contains the
- * EOS bucket.
+ * EOS/EOR bucket.
  */

 if ((status = ap_pass_brigade(f->next, bb)) != APR_SUCCESS) {
?