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

Reply via email to