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

Re: [Libevent-users] out-of-order writes in an evbuffer



You can do a couple of things:

* you can hack up the serialisation and buffering stuff so yes, it
injects that length value into an already-queued buffer;
* you can use iovec style setups to populate the _rest_ of the buffer,
then setup the header iovec with the type/length, then send the whole
thing to bufferevent;
* you can use a chunked encoding style stream block encoding from
HTTP, where each chunk has a length prefixing it, but there's no
global length for the whole object that's specified up front.



Adrian

On 21 May 2013 11:35, Mark Marchukov <march@xxxxxx> wrote:
> I have a problem that should be fairly common for app-level protocol
> implementations over libevent. I need to send a stream of messages of
> different types and sizes over a TCP connection managed by a bufferevent.
> The format of each message on the wire is <length><type><body>, where
> <length> is a 4-byte length of the message, <type> is a single-byte message
> type, <body> is the rest of the message. Every message object in my code
> knows how to serialize itself into an evbuffer, calculating and returning
> the length of serialized content in the process. However, the length of the
> message must appear in the evbuffer *before* the body of message. What’s the
> recommended way to do this with libevent 2.1?
>
>
>
> I do not want to require every message object to have a function that
> returns <length> for that message, in addition to the serialization
> function. This will increase code complexity, and will somewhat reduce its
> efficiency, since for complex payloads calculating <length> may take about
> as much CPU as actually serializing the message. So far I looked at the
> following options:
>
>
>
> 1) evbuffer_reserve_space()/evbuffer_commit_space() looked promising, but
> the docs say appending data to evbuffer may invalidate the pointers I get
> back. Is it true even if I pass an iovec of size 1?
>
> 2) evbuffer_add_reference() will allocate a new chain, which seems too
> expensive for reserving 5 bytes on the critical path
>
> 3) serializing <body> into a separate evbuffer, then adding it to the
> bufferevent’s output buffer by reference also looks expensive for 5 bytes
>
>
>
> Ideally, what I need is evbuffer_[reserve/commit]_space() that gives me a
> pointer to a small (5-bytes) reserved segment of evbuffer, which will remain
> valid after one or more subsequent calls  to evbuffer_add() that will
> compose the body of message.
>
>
>
> -Mark
***********************************************************************
To unsubscribe, send an e-mail to majordomo@xxxxxxxxxxxxx with
unsubscribe libevent-users    in the body.