(pointing to a resolve function) and almost-expired specific stats.
const bool almostExpired = ttl <= deadline;
if (almostExpired) {
iter->d_submitted = true;
- pushTask(qname, qtype, iter->d_ttd);
+ pushAlmostExpiredTask(qname, qtype, iter->d_ttd);
}
}
*responsePacket = iter->d_packet;
return -1;
} else {
if (!entry->d_submitted) {
- pushTask(qname, qtype, entry->d_ttd);
+ pushAlmostExpiredTask(qname, qtype, entry->d_ttd);
entry->d_submitted = true;
}
}
sortlist.cc sortlist.hh \
sstuff.hh \
stable-bloom.hh \
+ stats_t.hh \
svc-records.cc svc-records.hh \
syncres.cc syncres.hh \
taskqueue.cc taskqueue.hh \
*/
#include "rec-taskqueue.hh"
#include "taskqueue.hh"
+#include "logger.hh"
+#include "stat_t.hh"
#include "syncres.hh"
static thread_local pdns::TaskQueue t_taskQueue;
+static pdns::stat_t s_almost_expired_tasks_pushed;
+static pdns::stat_t s_almost_expired_tasks_run;
+static pdns::stat_t s_almost_expired_tasks_exceptions;
+
+static void resolve(const struct timeval &now, bool logErrors, const pdns::ResolveTask& task)
+{
+ ++s_almost_expired_tasks_run;
+ const string msg = "Exception while running a background ResolveTask";
+ SyncRes sr(now);
+ vector<DNSRecord> ret;
+ sr.setRefreshAlmostExpired(task.d_refreshMode);
+ try {
+ g_log << Logger::Debug << "TaskQueue: resolving " << task.d_qname.toString() << '|' << QType(task.d_qtype).toString() << endl;
+ int res = sr.beginResolve(task.d_qname, QType(task.d_qtype), QClass::IN, ret);
+ g_log << Logger::Debug << "TaskQueue: DONE resolving " << task.d_qname.toString() << '|' << QType(task.d_qtype).toString() << ": " << res << endl;
+ }
+ catch (const std::exception& e) {
+ ++s_almost_expired_tasks_exceptions;
+ g_log << Logger::Error << msg << ": " << e.what() << endl;
+ }
+ catch (const PDNSException& e) {
+ ++s_almost_expired_tasks_exceptions;
+ g_log << Logger::Notice << msg << ": " << e.reason << endl;
+ }
+ catch (const ImmediateServFailException& e) {
+ ++s_almost_expired_tasks_exceptions;
+ if (logErrors) {
+ g_log << Logger::Notice << msg << ": " << e.reason << endl;
+ }
+ }
+ catch (const PolicyHitException& e) {
+ ++s_almost_expired_tasks_exceptions;
+ if (logErrors) {
+ g_log << Logger::Notice << msg << ": PolicyHit" << endl;
+ }
+ }
+ catch (...) {
+ ++s_almost_expired_tasks_exceptions;
+ g_log << Logger::Error << msg << endl;
+ }
+}
void runTaskOnce(bool logErrors)
{
t_taskQueue.runOnce(logErrors);
}
-void pushTask(const DNSName& qname, uint16_t qtype, time_t deadline)
+void pushAlmostExpiredTask(const DNSName& qname, uint16_t qtype, time_t deadline)
{
- t_taskQueue.push({qname, qtype, deadline, true});
+ ++s_almost_expired_tasks_pushed;
+ t_taskQueue.push({qname, qtype, deadline, true, resolve});
}
uint64_t getTaskPushes()
{
return broadcastAccFunction<uint64_t>([] { return t_taskQueue.getSize(); });
}
+
+uint64_t getAlmostExpiredTasksPushed()
+{
+ return s_almost_expired_tasks_pushed;
+}
+
+uint64_t getAlmostExpiredTasksRun()
+{
+ return s_almost_expired_tasks_run;
+}
+
+uint64_t getAlmostExpiredTaskExceptions()
+{
+ return s_almost_expired_tasks_exceptions;
+}
+
#include "dnsname.hh"
void runTaskOnce(bool logErrors);
-void pushTask(const DNSName& qname, uint16_t qtype, time_t deadline);
+void pushAlmostExpiredTask(const DNSName& qname, uint16_t qtype, time_t deadline);
+// General task stats
uint64_t getTaskPushes();
uint64_t getTaskExpired();
uint64_t getTaskSize();
+
+// Almost expired specific stats
+uint64_t getAlmostExpiredTasksPushed();
+uint64_t getAlmostExpiredTasksRun();
+uint64_t getAlmostExpiredTaskExceptions();
--- /dev/null
+../stat_t.hh
\ No newline at end of file
return d_queue.size();
}
-void TaskQueue::push(const ResolveTask&& task)
+void TaskQueue::push(ResolveTask&& task)
{
// Insertion fails if it's already there, no problem since we're already scheduled
// and the deadline would remain the same anyway.
struct timeval now;
gettimeofday(&now, 0);
if (task.d_deadline >= now.tv_sec) {
- SyncRes sr(now);
- vector<DNSRecord> ret;
- sr.setRefreshAlmostExpired(task.d_refreshMode);
- try {
- g_log << Logger::Debug << "TaskQueue: resolving " << task.d_qname.toString() << '|' << QType(task.d_qtype).toString() << endl;
- int res = sr.beginResolve(task.d_qname, QType(task.d_qtype), QClass::IN, ret);
- g_log << Logger::Debug << "TaskQueue: DONE resolving " << task.d_qname.toString() << '|' << QType(task.d_qtype).toString() << ": " << res << endl;
- }
- catch (const std::exception& e) {
- g_log << Logger::Error << "Exception while running the background task queue: " << e.what() << endl;
- }
- catch (const PDNSException& e) {
- g_log << Logger::Notice << "Exception while running the background task queue: " << e.reason << endl;
- }
- catch (const ImmediateServFailException& e) {
- if (logErrors) {
- g_log << Logger::Notice << "Exception while running the background task queue: " << e.reason << endl;
- }
- }
- catch (const PolicyHitException& e) {
- if (logErrors) {
- g_log << Logger::Notice << "Policy hit while running the background task queue" << endl;
- }
- }
- catch (...) {
- g_log << Logger::Error << "Exception while running the background task queue" << endl;
- }
+ task.func(now, logErrors, task);
}
else {
// Deadline passed
namespace pdns
{
+// ATM we have one task type, if we get more, the unique key in the index needs to be adapted
struct ResolveTask
{
DNSName d_qname;
uint16_t d_qtype;
time_t d_deadline;
bool d_refreshMode; // Whether to run this task in regular mode (false) or in the mode that refreshes almost expired tasks
+ void (*func)(const struct timeval&, bool logErrors, const ResolveTask&);
};
struct HashTag
public:
bool empty() const;
size_t size() const;
- void push(const ResolveTask&& task);
+ void push(ResolveTask&& task);
ResolveTask pop();
bool runOnce(bool logErrors); // Run one task if the queue is not empty
void runAll(bool logErrors);
pdns::TaskQueue g_test_tasks;
-void pushTask(const DNSName& qname, uint16_t qtype, time_t deadline)
+void pushAlmostExpiredTask(const DNSName& qname, uint16_t qtype, time_t deadline)
{
- g_test_tasks.push({qname, qtype, deadline, true});
+ g_test_tasks.push({qname, qtype, deadline, true, nullptr});
}