-> temporary failure: e.g. increase idle period for that service.
- Add curl HTTP headers to disable proxy caching
+
+- On too many update errors: Configurable block period and error threshold counter
/**
* Update method for specified service was called.
- * @param service The service for which is the update running.
+ * @param service The service for which the update is running.
*/
void Logger::print_update_service(const string& service) const
{
}
}
+/**
+ * Service is blocked for update because of too many errors
+ * @param service The service for which the update is running.
+ * @param remaining_seconds Remaining seconds this service is blocked
+ */
+void Logger::print_update_service_is_blocked(const std::string& service, int remaining_seconds) const
+{
+ int level = 1;
+ if ( level <= Loglevel )
+ {
+ ostringstream msg;
+ msg << "Service " << service << " is blocked for " << remaining_seconds << " seconds because of too many errors" << endl;
+ log_notice(msg.str());
+ }
+}
+
+
+/**
+ * Service will be blocked because of update errors
+ * @param service The service for which the update is running.
+ * @param block_seconds Number of seconds this service is blocked
+ */
+void Logger::print_block_service(const std::string& service, int block_seconds) const
+{
+ int level = 0;
+ if ( level <= Loglevel )
+ {
+ ostringstream msg;
+ msg << "Service " << service << " will be blocked for " << block_seconds << " seconds because of too many errors" << endl;
+ log_notice(msg.str());
+ }
+}
+
/**
* An unknown option on the command line was detected.
void print_update_service(const std::string& service) const;
+ void print_update_service_is_blocked(const std::string& service, int remaining_seconds) const;
+
+ void print_block_service(const std::string& service, int block_seconds) const;
+
void print_unknown_cmd_option(const std::string& unknown_option) const;
void print_unknown_protocol(const std::string& protocol) const;
using namespace std;
+/// Number of update errors until a service will be blocked
+const int MaxErrorCount = 3;
+/// Number of seconds a service will be blocked if MaxErrorCount is reached
+const int ErrorBlockServiceSeconds = 15 * 60;
/**
* Default Constructor
, UpdateInterval(0)
, MaxUpdatesWithinInterval(0)
, DNSCacheTTL(0)
+ , ErrorCount(0)
+ , ErrorServiceBlockedUntil(0)
, Log(new Logger())
{
}
*/
void Service::update(const string& ip, const time_t current_time)
{
- Log->print_update_service(get_service_name());
+ const std::string service_name = get_service_name();
+
+ // Check if service is blocked for a short period of time (because of update errors)
+ if (ErrorServiceBlockedUntil && current_time < ErrorServiceBlockedUntil)
+ {
+ Log->print_update_service_is_blocked(service_name, ErrorServiceBlockedUntil - current_time);
+ return;
+ }
+
+ Log->print_update_service(service_name);
// test if update is permitted by UpdateInterval Status
if ( update_allowed(current_time) )
// if update was successful, we need to set the Lastupdated and ActualIP base member.
set_last_update(current_time);
ActualIP = ip;
- Log->print_update_service_successful(get_service_name());
+ Log->print_update_service_successful(service_name);
+
+ ErrorCount = 0;
+ ErrorServiceBlockedUntil = 0;
}
else
{
// problem while trying to update service
- Log->print_update_service_failure(get_service_name());
+ Log->print_update_service_failure(service_name);
+
+ ++ErrorCount;
+ if (ErrorCount >= MaxErrorCount)
+ {
+ Log->print_block_service(service_name, ErrorBlockServiceSeconds);
+
+ ErrorServiceBlockedUntil = time(NULL) + ErrorBlockServiceSeconds;
+ ErrorCount = 0;
+ }
}
}
}
std::list<time_t> LastUpdates;
+ int ErrorCount;
+ time_t ErrorServiceBlockedUntil;
+
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive & ar, const unsigned int version)