BUG/MINOR: applet: Notify the other side if data were consumed by an applet
If an applet consumed output data (the amount of output data has changed between before and after the call to the applet), the producer is notified. It means CF_WRITE_PARTIAL and CF_WROTE_DATA are set on the output channel and the opposite stream interface is notified some room was made in its input buffer. This way, it is no longer the applet responsibility to take care of it. However, it doesn't matter if the applet does the same. Said like that, it looks like an improvement not a bug. But it really fixes a bug in the lua, for HTTP applets. Indeed, applet:receive() and applet:getline() are buggy for HTTP applets. Data are consumed but the producer is not notified. It means if the payload is not fully received in one time, the applet may be blocked because the producer remains blocked (it is time dependent). This patch must be backported as far as 2.0 (only for the HTX part).
This commit is contained in:
parent
260ec8e9a9
commit
1eedf9b4cb
10
src/applet.c
10
src/applet.c
|
@ -63,6 +63,7 @@ struct task *task_run_applet(struct task *t, void *context, unsigned int state)
|
|||
struct appctx *app = context;
|
||||
struct stream_interface *si = app->owner;
|
||||
unsigned int rate;
|
||||
size_t count;
|
||||
|
||||
if (app->state & APPLET_WANT_DIE) {
|
||||
__appctx_free(app);
|
||||
|
@ -85,8 +86,17 @@ struct task *task_run_applet(struct task *t, void *context, unsigned int state)
|
|||
if (!si_alloc_ibuf(si, &app->buffer_wait))
|
||||
si_rx_endp_more(si);
|
||||
|
||||
count = co_data(si_oc(si));
|
||||
app->applet->fct(app);
|
||||
|
||||
/* now check if the applet has released some room and forgot to
|
||||
* notify the other side about it.
|
||||
*/
|
||||
if (count != co_data(si_oc(si))) {
|
||||
si_oc(si)->flags |= CF_WRITE_PARTIAL | CF_WROTE_DATA;
|
||||
si_rx_room_rdy(si_opposite(si));
|
||||
}
|
||||
|
||||
/* measure the call rate and check for anomalies when too high */
|
||||
rate = update_freq_ctr(&app->call_rate, 1);
|
||||
if (rate >= 100000 && app->call_rate.prev_ctr && // looped more than 100k times over last second
|
||||
|
|
Loading…
Reference in New Issue