J'essaye de limiter mon taux d'envoi d'application à 900kbps mais le problème est que le protocole que j'utilise est orienté message et que les messages ont des tailles très différentes. Je peux avoir des messages de 40 octets jusqu'à 125000 octets et tous les messages sont envoyés comme unités atomiques.Seau à jetons ou seau fuyard pour les messages
J'ai essayé d'implémenter un tampon de seau de jetons mais si je définis une taille de seau faible, les gros paquets ne seront jamais envoyés et un seau plus grand produira une grande salve sans aucune limitation de débit.
Ceci est ma petite implémentation en C:
typedef struct token_buffer {
size_t capacity;
size_t tokens;
double rate;
uint64_t timestamp;
} token_buffer;
static uint64_t time_now()
{
struct timeval ts;
gettimeofday(&ts, NULL);
return (uint64_t)(ts.tv_sec * 1000 + ts.tv_usec/1000);
}
static int token_buffer_init(token_buffer *tbf, size_t max_burst, double rate)
{
tbf->capacity = max_burst;
tbf->tokens = max_burst;
tbf->rate = rate;
tbf->timestamp = time_now();
}
static size_t token_buffer_consume(token_buffer *tbf, size_t bytes)
{
// Update the tokens
uint64_t now = time_now();
size_t delta = (size_t)(tbf->rate * (now - tbf->timestamp));
tbf->tokens = (tbf->capacity < tbf->tokens+delta)?tbf->capacity:tbf->tokens+delta;
tbf->timestamp = now;
fprintf(stdout, "TOKENS %d bytes: %d\n", tbf->tokens, bytes);
if(bytes <= tbf->tokens) {
tbf->tokens -= bytes;
} else {
return -1;
}
return 0;
}
Ensuite, quelque part dans le principal():
while(1) {
len = read_msg(&msg, file);
// Loop until we have enough tokens.
// if len is larger than the bucket capacity the loop never ends.
// if the capacity is too large then no rate limit occurs.
while(token_buffer_consume(&tbf,msg, len) != 0) {}
send_to_net(&msg, len);
}