Commit 1e763b3d authored by Michal 'vorner' Vaner's avatar Michal 'vorner' Vaner
Browse files

[2871] Interface of the fake query

Provide interface of the FakeQuery. That one will represent the work to
be done during a benchmark for single query.

Also provide interface for FakeInterface, which will generate the
queries and handle the event loop.
parent 146f2e6c
......@@ -15,4 +15,5 @@ CLEANFILES = *.gcno *.gcda
noinst_PROGRAMS = resolver-bench
resolver_bench_SOURCES = main.cc
resolver_bench_SOURCES += fake_resolution.h
resolver_bench_LDADD = $(GTEST_LDADD)
// Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
#ifndef FAKE_RESOLUTION_H
#define FAKE_RESOLUTION_H
#include <boost/function.hpp>
#include <boost/shared_ptr.hpp>
namespace isc {
namespace resolver {
namespace bench {
/// \brief The kind of task a FakeQuery might want to perform.
///
/// The benchmark should examine which kind of task the query needs to perform
/// to progress forward. According to the task, some resources might need to be
/// locked, something re-scheduled, or such.
enum Task {
/// \brief Some CPU-bound computation.
///
/// The query needs to do some computation without any shared resources.
/// This might be parsing or rendering of the query, verification of
/// signatures, etc.
Compute,
/// \brief The query needs to read data from cache.
CacheRead,
/// \brief The query needs to modify the cache.
CacheWrite,
/// \brief A response is to be sent.
///
/// This needs to access the interface/socket. If the socket is shared
/// between threads, it might need to lock it.
Send,
/// \brief An answer from upstream server is needed.
///
/// The query needs to send a query to some authoritative server and wait
/// for the answer. Something might need to be locked (or not, depending
/// on the architecture of the thing that sends and receives). Also, the
/// task will not complete immediately, the callback of performTask
/// will be called at later time.
Upstream
};
class FakeInterface;
/// \brief Imitation of the work done to resolve a query.
///
/// An object of this class represents some fake work that should look like
/// the work needed to perform resolution of one query. No real work is done,
/// but several steps are scheduled, with characteristics hopefully
/// corresponding to steps of the real query.
///
/// The idea is that benchmark will repeatedly check if the query is done.
/// If not, it examines the next task by calling nextTask(). Depending on
/// the result, it'd lock or prepare any shared resources. After that, it'd
/// call performTask() to do the task. Once the query calls the callback
/// passed, it can proceed to the next step.
///
/// See naive_resolver.cc for example code how this could be done.
class FakeQuery {
public:
/// \brief Callback to signify a task has been performed.
typedef boost::function<void()> StepCallback;
/// \brief Is work on the query completely done?
///
/// If this returns true, do not call performTask or nextTask any more.
/// The resolution is done.
///
/// \throw isc::InvalidOperation if upstream query is still in progress.
bool done() const;
/// \brief Perform next step in the resolution.
///
/// Do whatever is needed to be done for the next step of resolution.
/// Once the step is done, the callback is called.
///
/// The callback is usually called from within this call. However, in
/// the case when the nextTask() returned `Upstream`, the call to the
/// callback is delayed for some period of time after the method
/// returns.
///
/// \throw isc::InvalidOperation if it is called when done() is true, or
/// if an upstream query is still in progress (performTask was called
/// before and the callback was not called by the query yet).
void performTask(const StepCallback& callback);
/// \brief Examine the kind of the next resolution process.
///
/// Call this to know what kind of task will performTask do next.
///
/// \throw isc::InvalidOperation if it is called when done() is true, or
/// if an upstream query is still in progress (performTask was called
/// before and the callback was not called by the query yet).
Task nextTask() const;
/// \brief Move network communication to different interface.
///
/// By default, a query does all the "communication" on the interface
/// it was born on. This may be used to move a query from one interface
/// to another.
///
/// You don't have to lock either of the interfaces to do so, this
/// only switches the data in the query.
///
/// \throw isc::InvalidOperation if it is called while an upstream query
/// is in progress.
void migrateTo(FakeInterface& dst_interface);
};
typedef boost::shared_ptr<FakeQuery> FakeQueryPtr;
/// \brief An imitation of interface for receiving queries.
///
/// This is effectively a little bit smarter factory for queries. You can
/// request a new query from it, or let process events (incoming answers).
///
/// It contains its own event loop. If the benchmark has more threads, have
/// one in each of the threads (if the threads ever handles network
/// communication -- if it accepts queries, sends answers or does upstream
/// queries).
///
/// If the model simulated would share the same interface between multiple
/// threads, it is better to have one in each thread as well, but lock
/// access so only one is used at once (no idea what happens if ASIO loop is
/// accessed from multiple threads).
class FakeInterface {
public:
/// \brief Wait for answers from upstream servers.
///
/// Wait until at least one "answer" comes from the remote server. This
/// will effectively block the calling thread until it is time to call
/// a callback of performTask.
///
/// It is not legal to call it without any outstanding upstream queries
/// on this interface. However, the situation is not explicitly checked.
///
/// \note Due to internal implementation, it is not impossible no or more
/// than one callbacks to be called from within this method.
void processEvents();
/// \brief Accept another query.
///
/// Generate a new fake query to resolve.
///
/// This method might call callbacks of other queries waiting for upstream
/// answer.
///
/// This returns a NULL pointer when there are no more queries to answer
/// (the number designated for the benchmark was reached).
FakeQueryPtr receiveQuery();
};
}
}
}
#endif
// Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
#include <resolver/bench/fake_resolution.h>
int main(int, const char**) {
return 0;
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment