Hi,
Alvaro Lopez Ortega wrote:
Diego Giagio wrote:
> The throttler interface may be the following:
>
> throttler.h/throttler.c
> cherokee_throttler_new()
> cherokee_throttler_free()
> cherokee_throttler_check()
> cherokee_throttler_update(bytes_recvd)
Yeah, looks good :-)
Thanks, i'm just following cherokee's style (which is very good IMHO).
> To enable the throttler we could create wrapper functions around
> cherokee_write, cherokee_read, cherokee_socket_* on
> connection.c. Eg. Every time cherokee_write is called, the
> throttler is checked and if it's not okay we could return EAGAIN
> (ret_eagain). Otherwise we do the write and update the throttler.
I have not looked at it deeply, but I would do something
like.. where there was a cherokee_connection_send() call, do:
==========
do_send = true;
if (throttler != NULL) {
cherokee_throttler_check (throttler, ..., &do_send);
}
if (do_send)
cherokee_connection_send();
==========
What do you think? In this way, we can keep the socket class
independent of the bandwidth throttling thing.
That's a nice approach. The only downside I can think of is repeating
that piece of code every place a *_send or *_recv function is called.
Let me try explain a bit better what I was talking about. The wrapper
functions i proposed wouldn't be created on the socket class, but on the
connection class (connection.c) and they would be static. I mean, eg.
instead of writing:
ret = cherokee_write (cnt->socket, buf->buf, buf->len, &written);
We would write:
ret = conn_write_buf (cnt, buf, written);
The function conn_write_buf, would:
- Check the throttler
- Call cherokee_write
- Update the traffic counter (cherokee_connection_tx_add)
- Update the throttler
Example:
static ret_t
conn_write_buf (cherokee_connection_t *cnt,
cherokee_buffer_t *buf, size_t *written)
{
ret_t ret;
/* Check throttling
*/
ret = throttler_check (cnt);
if (ret != ret_ok)
return ret;
ret = cherokee_write (cnt->socket, buf->buf, buf->len, written);
if (ret == ret_ok) {
/* Add to the connection traffic counter
*/
cherokee_connection_tx_add (cnt, *written);
/* Update throttler
*/
throttler_update (cnt, *written);
}
return ret;
}
Below is throttler_check and throttler_update:
static ret_t
throttler_check (cherokee_connection_t *cnt)
{
cherokee_throttler_t *throttler;
ret_t ret;
/* Connection throttling
*/
throttler = CONN_THROTTLER(cnt);
if (throttler != NULL) {
ret = cherokee_throttler_check (throttler);
if (ret != ret_ok)
return ret_eagain;
}
return ret_ok;
}
static void inline
throttler_update (cherokee_connection_t *cnt, size_t n)
{
cherokee_throttler_t *throttler;
/* Update the throttler counter
*/
throttler = CONN_THROTTLER(cnt);
if (throttler != NULL)
cherokee_throttler_update (throttler, n);
}
Other similar functions would be created, eg.:
conn_write (cherokee_connection_t *cnt,
const char *buf, int buf_len, size_t *written);
conn_writev (cherokee_connection_t *cnt,
const struct iovec *vector, int vector_len,
size_t* written)
conn_read_buf (cherokee_connection_t *cnt,
cherokee_buffer_t *buf, size_t count, size_t *done)
What do you think about it ?
> I'm sure i'm missing a lot of things, but that should be enough for
> the list to start talking about. ;)
Sure! There will come up lot of these things. :-))
Diego Giagio
_______________________________________________
Cherokee mailing list
[email protected]
http://www.alobbs.com/cgi-bin/mailman/listinfo/cherokee