Willy Tarreau | a482746 | 2014-10-30 16:07:16 +0100 | [diff] [blame] | 1 | 2014/10/30 - dynamic buffer management |
| 2 | |
| 3 | Since HTTP/2 processing will significantly increase the need for buffering, it |
| 4 | becomes mandatory to be able to support dynamic buffer allocation. This also |
| 5 | means that at any moment some buffer allocation will fail and that a task or an |
| 6 | I/O operation will have to be paused for the time needed to allocate a buffer. |
| 7 | |
| 8 | There are 3 places where buffers are needed : |
| 9 | |
| 10 | - receive side of a stream interface. A connection notifies about a pending |
| 11 | recv() and the SI calls the receive function to put the data into a buffer. |
| 12 | Here the buffer will have to be picked from a pool first, and if the |
| 13 | allocation fails, the I/O will have to temporarily be disabled, the |
| 14 | connection will have to subscribe for buffer release notification to be |
| 15 | woken up once a buffer is available again. It's important to keep in mind |
| 16 | that buffer availability doesn't necessarily mean a desire to enable recv |
| 17 | again, just that recv is not paused anymore for resource reasons. |
| 18 | |
| 19 | - receive side of a stream interface when the other end point is an applet. |
| 20 | The applet wants to write into the buffer and for this the buffer needs to |
| 21 | be allocated as well. It is the same as above except that it is the applet |
| 22 | which is put to a pause. Since the applet might be at the core of the task |
| 23 | itself, it could become tricky to handle the situation correctly. Stats and |
| 24 | peers are in this situation. |
| 25 | |
| 26 | - Tx of a task : some tasks perform spontaneous writes to a buffer. Checks |
| 27 | are an example of this. The checks will have to be able to sleep while a |
| 28 | buffer is being awaited. |
| 29 | |
| 30 | One important point is that such pauses must not prevent the task from timing |
| 31 | out. There it becomes difficult because in the case of a time out, we could |
| 32 | want to emit a timeout error message and for this, require a buffer. So it is |
| 33 | important to keep the ability not to send messages upon error processing, and |
| 34 | to be able to give up and stop waiting for buffers. |
| 35 | |
| 36 | The refill mechanism needs to be designed in a thread-safe way because this |
| 37 | will become one of the rare cases of inter-task activity. Thus it is important |
| 38 | to ensure that checking the state of the task and passing of the freshly |
| 39 | released buffer are performed atomically, and that in case the task doesn't |
| 40 | want it anymore, it is responsible for passing it to the next one. |
| 41 | |