Branch: Tag:

1999-09-04

1999-09-04 22:40:45 by Francesco Chemolli <li@kinkie.it>

First useable implementation of the bandwidth throttling subsystem.

Rev: server/base_server/configuration.pike:1.206
Rev: server/base_server/fastpipe.pike:1.1
Rev: server/base_server/roxen.pike:1.322
Rev: server/base_server/slowpipe.pike:1.1
Rev: server/base_server/smartpipe.pike:1.29
Rev: server/base_server/throttler.pike:1.1
Rev: server/modules/throttling/baseline_throttling.pike:1.1
Rev: server/modules/throttling/throttling_bytype.pike:1.1
Rev: server/protocols/http.pike:1.152

1:   // This is a roxen module. + // Modified by Francesco Chemolli to add throttling capabilities.   // Copyright © 1996 - 1998, Idonex AB. -  + // $Id: http.pike,v 1.152 1999/09/04 22:40:45 kinkie Exp $      #define MAGIC_ERROR      #ifdef MAGIC_ERROR   inherit "highlight_pike";   #endif - constant cvs_version = "$Id: http.pike,v 1.151 1999/08/17 18:37:51 grubba Exp $"; + constant cvs_version = "$Id: http.pike,v 1.152 1999/09/04 22:40:45 kinkie Exp $";   // HTTP protocol module.   #include <config.h>   private inherit "roxenlib";
41:   constant find_supports = roxen.find_supports;   constant version = roxen.version;   constant _query = roxen.query; - constant thepipe = roxen.pipe; + //constant thepipe = roxen.pipe; //can be removed   constant _time = predef::time;      private static array(string) cache;
102:      void end(string|void a,int|void b);    - #if constant(Stdio.sendfile) - object pipe; // Always 0. + object pipe;    - static array(string) result_headers = ({}); - static object result_file; - static int result_f_len; + int throttle=0; //if nonzero, we're throttling. + int rate=0; //the throttling rate. + object throttler;//the inter-request throttling object.    - void send(string|object what, int|void len) + /* Pipe-using send functions */ +  + // FIXME: + //I'm choosing the pipe type upon setup. Thus I'm assuming that all headers + //have been defined before then. This is actually not true in case + //of throttling and keep-alive. We'll take care of that later. + private void setup_pipe()   { -  if (stringp(what)) { -  result_headers += ({ what }); +  if(!my_fd) { +  end(); +  return; +  } +  if (!conf || !conf->query("req_throttle")) +  throttle=0; +  if(!pipe) { +  if (throttle || (conf && conf->throttler)) { +  pipe=((program)"slowpipe")();    } else { -  if (result_file) { -  error("HTTP: Multiple result files are not supported!\n"); +  pipe=((program)"fastpipe")();    } -  result_file = what; -  result_f_len = len; +     } -  +  if (throttle) { +  rate=max(rate,conf->query("req_throttle_min")); //if conf=0 => throttle=0 +  pipe->throttle(rate,(int)(rate*conf->query("req_throttle_depth_mult")),0);    } -  - static void send_done(int bytes, function callback, array(mixed) args) - { -  file->len = bytes; -  callback(@args); +  if (conf && conf->throttler) { +  pipe->assign_throttler(conf->throttler);    } -  - void start_sender(function callback, mixed ... args) - { -  array(string) headers = result_headers; -  object file = result_file; -  int len = result_f_len; -  -  result_headers = 0; -  result_file = 0; -  result_f_len = 0; -  -  // FIXME: Timeout handling! -  -  Stdio.sendfile(headers, file, -1, len, 0, my_fd, send_done, callback, args); +    }    - #else /* !constant(Stdio.sendfile) */ - object pipe; +     - private void setup_pipe() + void send (string|object what, int|void len)   { -  if(!my_fd) -  { -  end(); -  return; -  } -  if(!pipe) pipe=thepipe(); - } -  - void send(string|object what, int|void len) - { +    #ifdef REQUEST_DEBUG    roxen_perror(sprintf("send(%O, %O)\n", what, len));   #endif /* REQUEST_DEBUG */
169:    else pipe->input(what,len);   }    - void start_sender(function callback, mixed ... args) + void start_sender (function callback, mixed ... args)   {    if (pipe) {    MARK_FD("HTTP really handled, piping "+not_query);
185:    }   }    - #endif /* constant(Stdio.sendfile) */ -  +    string scan_for_query( string f )   {    if(sscanf(f,"%s?%s", f, query) == 2)