-
Notifications
You must be signed in to change notification settings - Fork 897
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add token-bucket based rate limiting for falco notifications. The token bucket is implemented in token_bucket.cpp and maintains a current count of tokens (i.e. right to send a notification). Its main method is claim(), which attemps to claim a token and returns true if one was claimed successfully. It has a configurable configurable max burst size and rate. The token bucket gains "rate" tokens per second, up to a maximum of max_burst tokens. These parameters are configurable in falco.yaml via the config options (defaults shown): outputs: rate: 1 max_burst: 1000 In falco_outputs::handle_event(), try to claim a token, and if unsuccessful log a debug message and return immediately.
- Loading branch information
Showing
9 changed files
with
182 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
/* | ||
Copyright (C) 2016 Draios inc. | ||
This file is part of falco. | ||
falco is free software; you can redistribute it and/or modify | ||
it under the terms of the GNU General Public License version 2 as | ||
published by the Free Software Foundation. | ||
falco is distributed in the hope that it will be useful, | ||
but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
GNU General Public License for more details. | ||
You should have received a copy of the GNU General Public License | ||
along with falco. If not, see <http://www.gnu.org/licenses/>. | ||
*/ | ||
|
||
#include <cstddef> | ||
#include <sys/time.h> | ||
|
||
#include "token_bucket.h" | ||
|
||
token_bucket::token_bucket() | ||
{ | ||
init(1, 1); | ||
} | ||
|
||
token_bucket::~token_bucket() | ||
{ | ||
} | ||
|
||
void token_bucket::init(uint32_t rate, uint32_t max_tokens) | ||
{ | ||
m_rate = rate; | ||
m_max_tokens = max_tokens; | ||
m_tokens = max_tokens; | ||
m_last_seen = get_epoch_ns(); | ||
} | ||
|
||
bool token_bucket::claim() | ||
{ | ||
// Determine the number of tokens gained. Delta between | ||
// last_seen and now, divided by the rate. | ||
uint64_t now = get_epoch_ns(); | ||
uint64_t tokens_gained = (now - m_last_seen) / (m_rate * 1000000000); | ||
m_last_seen = now; | ||
|
||
m_tokens += tokens_gained; | ||
|
||
// | ||
// Cap at max_tokens | ||
// | ||
if(m_tokens > m_max_tokens) | ||
{ | ||
m_tokens = m_max_tokens; | ||
} | ||
|
||
// | ||
// If tokens is < 1, can't claim. | ||
// | ||
if(m_tokens < 1) | ||
{ | ||
return false; | ||
} | ||
|
||
m_tokens--; | ||
|
||
return true; | ||
} | ||
|
||
uint64_t token_bucket::get_epoch_ns() | ||
{ | ||
struct timeval tv; | ||
gettimeofday(&tv, NULL); | ||
|
||
return tv.tv_sec * (uint64_t) 1000000000 + (tv.tv_usec * 1000); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
/* | ||
Copyright (C) 2016 Draios inc. | ||
This file is part of falco. | ||
falco is free software; you can redistribute it and/or modify | ||
it under the terms of the GNU General Public License version 2 as | ||
published by the Free Software Foundation. | ||
falco is distributed in the hope that it will be useful, | ||
but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
GNU General Public License for more details. | ||
You should have received a copy of the GNU General Public License | ||
along with falco. If not, see <http://www.gnu.org/licenses/>. | ||
*/ | ||
|
||
#pragma once | ||
|
||
#include <cstdint> | ||
|
||
// A simple token bucket that accumulates tokens at a fixed rate and allows | ||
// for limited bursting in the form of "banked" tokens. | ||
class token_bucket | ||
{ | ||
public: | ||
token_bucket(); | ||
virtual ~token_bucket(); | ||
|
||
// | ||
// Initialize the token bucket and start accumulating tokens | ||
// | ||
void init(uint32_t rate, uint32_t max_tokens); | ||
|
||
// | ||
// Returns true if a token can be claimed. Also updates | ||
// internal metrics. | ||
// | ||
bool claim(); | ||
private: | ||
|
||
// Utility function to get the time in nanoseconds since the epoch. | ||
uint64_t get_epoch_ns(); | ||
|
||
// | ||
// The number of tokens generated per second. | ||
// | ||
uint64_t m_rate; | ||
|
||
// | ||
// The maximum number of tokens that can be banked for future | ||
// claim()s. | ||
// | ||
uint64_t m_max_tokens; | ||
|
||
// | ||
// The current number of tokens | ||
// | ||
uint64_t m_tokens; | ||
|
||
// | ||
// The last time claim() was called (or the object was created). | ||
// Nanoseconds since the epoch. | ||
// | ||
uint64_t m_last_seen; | ||
}; | ||
|