[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

Re: Re: [Libevent-users] unsend data in output buffer when closeconnection



On Thu, Jan 22, 2015 at 10:01:27AM +0800, slump wrote:
> 
> yes, free and create new bufferevent won't affect the performance   because the connection close event is rare
>  the reason why I want to reuse bufferevent is  that I want to resend the data in bufferevent's output buffer 
> and don't want store data twice (one in output buffer and one in my code)
> 

Just how much pending data are we talking about here on average? I'm
only asking because there may be some hacks to assist with this, but
would only suggest if we're dealing with huge amounts of data. 

But not quite sure what or why's of your application, it's hard to say 
which method would be best for you.

If you have multiple connections that come in, and some that need the 
data resent, you need some way to identify those. In other words, a 
handshake needs to happen.

From there, if a client disconnects, you know its id (which hopefully
the server assigned, kinda like tls rfc5077). Upon reconnecting, the
handshake will now include the id. Look it up in a table/tree/whatever,
and if exists, you can send it data it missed.

Something like this (not including handshakes, just some pseudocode):

struct client {
    uint32_t          client_id;
    struct evbuffer * pending_data;
};

static void
my_bufferevent_eventcb(struct bufferevent * bev, short events, void * arg) {
    struct client   * client;
    struct evbuffer * output_buf;
    size_t            pending;

    client     = (struct client *)arg;
    output_buf = bufferevent_get_output(bev);
    pending    = evbuffer_get_length(output_buf);

    if (pending > 0) {
       /* this effeciently moves the pending data into the client
        * structures evbuffer */
       evbuffer_remove_buffer(output_buf, client->pending_data, pending)
       HASH_INSERT(table, client);
    } else {
        FREE_CLIENT_SINCE_IT_HAS_ALL_DATA(client);
    }

    bufferevent_free(bev);
}
    
Once the client reconnects and the handshake reveals it has pending
data, simply do a bufferevent_write_buffer(bev, client->pending_data);
before anything else.

> now I see I must store message in my code and wait confirm message from server (I don't how many data was sent by bufferevent)
> or I must allow some data loss 
> 

- If you set the write callback on a bufferevent, it will executed when
  all of the data has been sent.

- When the event callback is executed for a bufferevent, and contains an
  error, you can always do:

    size_t bytes_pending = evbuffer_get_length(bufferevent_get_output(bev)); 

> Thank you , Mark!
> 
> 
> 2015-01-22 
> 
> 
> 
> slump 
> 
> 
> 
> ???????? Mark Ellzey 
> ?????????? 2015-01-22  03:29:36 
> ???????? libevent-users 
> ?????? 
> ?????? Re: [Libevent-users] unsend data in output buffer when closeconnection 
>  
> On Wed, Jan 21, 2015 at 06:11:19PM +0800, slump wrote:
> > So, it seems that the best I can do is free the bufferevent and create new one
> This is how I would do it, with CLOSE_ON_FREE set. I'm going to take a
> wild guess and say it will not affect the performance of your
> application, and in the meantime make things easier.
> ***********************************************************************
> To unsubscribe, send an e-mail to majordomo@xxxxxxxxxxxxx with
> unsubscribe libevent-users    in the body.
***********************************************************************
To unsubscribe, send an e-mail to majordomo@xxxxxxxxxxxxx with
unsubscribe libevent-users    in the body.