Browse Source

[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.
Michal 'vorner' Vaner 12 years ago
parent
commit
1e763b3d48

+ 1 - 0
src/bin/resolver/bench/Makefile.am

@@ -15,4 +15,5 @@ CLEANFILES = *.gcno *.gcda
 noinst_PROGRAMS = resolver-bench
 noinst_PROGRAMS = resolver-bench
 
 
 resolver_bench_SOURCES = main.cc
 resolver_bench_SOURCES = main.cc
+resolver_bench_SOURCES += fake_resolution.h
 resolver_bench_LDADD  = $(GTEST_LDADD)
 resolver_bench_LDADD  = $(GTEST_LDADD)

+ 165 - 0
src/bin/resolver/bench/fake_resolution.h

@@ -0,0 +1,165 @@
+// 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

+ 16 - 0
src/bin/resolver/bench/main.cc

@@ -1,3 +1,19 @@
+// 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**) {
 int main(int, const char**) {
     return 0;
     return 0;
 }
 }