tidwall / evio

Fast event-loop networking for Go
MIT License
5.9k stars 492 forks source link

allow using custom buffer allocator #14

Closed patricksuo closed 6 years ago

patricksuo commented 6 years ago

https://github.com/tidwall/evio/blob/703dc170d8c0d4ed772b6bcfa45f48ac15427882/evio_loop.go#L583

I believe heavy traffic application can gain a lot from reusing packet buffer.

tidwall commented 6 years ago

I just pushed an update that adds the ReuseInputBuffer option. This option causes the server to pass the raw packet buffer to the Data event. Thus leaving the memory management of the in []byte slice up to the developer.

patricksuo commented 6 years ago

@tidwall
Impressed quick response! 👍

some background: In my proxy program, the usual working pattern is 1) read head and then body from one endpoint connected to the proxy 2) decode packet head and determine where the packet should route to 3) route the whole packet to other endpoint

I allocate buffer for packet from wired and enqueue to some outbound queue without data copying. When this packet is written to wired, buffer will be recycle to a buffer pool.

In evio , pre-allocated buffer [1] is used for receiving bytes from wired. Developers have to make a copy of the buffer, because evio will reuse the pre-allocated buffer.

My proposal is to have a more agile memory manage API, so that user can have more control over buffer:

allocate(fd int, size int) []byte
free(buffer []byte)

When evio need buffer for a Read, it asks the user provided allocate. When evio finish writing a packet, it uses user provided free to recycle the buffer.

And finally replace unixConn 's outbuf[4] with type [][]byte, so that we can achieve zero-copy and take the advance of writev system call

[1] https://github.com/tidwall/evio/blob/2856314c8fb295b8be5f5c5d8d5e16cbd2ddfba7/evio_loop.go#L326

[2] https://github.com/tidwall/evio/blob/2856314c8fb295b8be5f5c5d8d5e16cbd2ddfba7/evio_loop.go#L473

[3] https://github.com/tidwall/evio/blob/2856314c8fb295b8be5f5c5d8d5e16cbd2ddfba7/evio_loop.go#L580

[4] https://github.com/tidwall/evio/blob/2856314c8fb295b8be5f5c5d8d5e16cbd2ddfba7/evio_loop.go#L69