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

Re: [Libevent-users] Seeking advice on handling a -1 return value from bufferevent_write()



On Tue, Apr 26, 2011 at 12:09 PM, Francoeur, Joseph A.
<jfrancoe@xxxxxxxxx> wrote:
> Hello,
>
> I'm successfully using bufferevent_write() to send message frames that are handled by bufferevent_read().  However, I'd like to handle a possible return value of -1 in the most optimal way (meaning, give the application the best of chance of succeeding on a retry of bufferevent_write()).
>
> A return value of -1 from bufferevent_write() can mean that either that a libevent-specific error has occurred, or malloc() has failed to add the frame to the linked list of chains.  Assuming that the latter has occurred, I'm thinking of either reconnecting (using sockets) and/or reallocating the frame before a retry, or breaking the frame in half, and trying to resend it in 2 pieces.

Hm!  Handling out-of-memory conditions isn't libevent-specific, and
the right approach for it isn't necessarily going to be the same on
all platforms.  (For instance, on many Linux setups, you can't rely on
getting an OOM error when memory is exhausted: instead, the kernel
overcommits when handing out memory and starts killing processes if
actually available memory is exhausted[1].)

If you _do_ get notified about an OOM error, though, one good appraoch
is to look around to see if you can find something that's eating
memory and kill it.  For instance, if there are slow connections that
have too much data queued in their buffers, you could close them.  If
you're cacheing anything, you could do an immediate cache cleanup to
free up some memory.  Other people have written more about handling
OOM conditions in general.

If you're concerned about bufferevent-related OOM conditions, it's a
good idea to conserve memory by setting a read high-water mark on each
bufferevent to limit the amount of incoming data it will queue for you
unprocessed.  Also, if you have lots of data to write out on each
connection, look into tricks to avoid queueing it all in RAM: add it
to output buffers a small piece at a time, and don't fill any buffer
more the than it can flush before you refill it.  Also you can look
into using add-by-reference functions to avoid duplicating data that
you want to add to more than one outgoing evbuffer at a time.

But to get back to your original question: if a buffervent_write
fails, I'd suggest that in general instead of retrying it immediately,
you make sure that you've capped read buffers on reading bufferevents,
and delay the write until after some writeable data has flushed and
you've processed any incoming data.  Of course, the right thing to do
will depend on your application's actual memory usage patterns.

hope this helps,
-- 
Nick
***********************************************************************
To unsubscribe, send an e-mail to majordomo@xxxxxxxxxxxxx with
unsubscribe libevent-users    in the body.