changeset 134:3dcf0394971d

Debug output improvements, and make the checker actually attempt to call the descriptor function for known plugin types
author Chris Cannam <c.cannam@qmul.ac.uk>
date Wed, 16 Nov 2016 16:12:42 +0000
parents 74a7c2a8d6b6
children 1f09f29526bf
files vamp-client/AutoPlugin.h vamp-client/CapnpRRClient.h vamp-client/ProcessQtTransport.h vamp-client/SynchronousTransport.h vamp-support/LoaderRequests.h
diffstat 5 files changed, 92 insertions(+), 37 deletions(-) [+]
line wrap: on
line diff
--- a/vamp-client/AutoPlugin.h	Fri Nov 04 10:43:49 2016 +0000
+++ b/vamp-client/AutoPlugin.h	Wed Nov 16 16:12:42 2016 +0000
@@ -50,10 +50,12 @@
     AutoPlugin(std::string serverName,
                std::string pluginKey,
                float inputSampleRate,
-               int adapterFlags) :
+               int adapterFlags,
+               LogCallback *logger) : // logger may be nullptr for cerr
         Vamp::Plugin(inputSampleRate),
-        m_transport(serverName, "capnp"),
-        m_client(&m_transport)
+        m_logger(logger),
+        m_transport(serverName, "capnp", logger),
+        m_client(&m_transport, logger)
     {
         LoadRequest req;
         req.pluginKey = pluginKey;
@@ -63,7 +65,7 @@
             LoadResponse resp = m_client.loadPlugin(req);
             m_plugin = resp.plugin;
         } catch (ServerCrashed c) {
-            std::cerr << c.what() << std::endl;
+            log(std::string("AutoPlugin: Server crashed: ") + c.what());
             m_plugin = 0;
         }
     }
@@ -168,16 +170,22 @@
     }
 
 private:
+    LogCallback *m_logger;
     ProcessQtTransport m_transport;
     CapnpRRClient m_client;
     Vamp::Plugin *m_plugin;
     Vamp::Plugin *getPlugin() const {
         if (!m_plugin) {
-            throw std::logic_error
-                ("Plugin load failed (should have called AutoPlugin::isOK)");
+            log("AutoPlugin: getPlugin() failed (caller should have called AutoPlugin::isOK)");
+            throw std::logic_error("Plugin load failed");
         }
         return m_plugin;
     }
+
+    void log(std::string message) const {
+        if (m_logger) m_logger->log(message);
+        else std::cerr << message << std::endl;
+    }
 };
 
 }
--- a/vamp-client/CapnpRRClient.h	Fri Nov 04 10:43:49 2016 +0000
+++ b/vamp-client/CapnpRRClient.h	Wed Nov 16 16:12:42 2016 +0000
@@ -44,6 +44,8 @@
 #include "vamp-support/AssignedPluginHandleMapper.h"
 #include "vamp-capnp/VampnProto.h"
 
+#include <sstream>
+
 #include <capnp/serialize.h>
 
 namespace piper_vamp {
@@ -80,7 +82,9 @@
     };
     
 public:
-    CapnpRRClient(SynchronousTransport *transport) : //!!! ownership? shared ptr?
+    CapnpRRClient(SynchronousTransport *transport, //!!! ownership? shared ptr?
+                  LogCallback *logger) : // logger may be nullptr for cerr
+        m_logger(logger),
         m_transport(transport),
         m_completenessChecker(new CompletenessChecker) {
         transport->setCompletenessChecker(m_completenessChecker);
@@ -102,6 +106,7 @@
     listPluginData(const ListRequest &req) override {
 
         if (!m_transport->isOK()) {
+            log("Piper server crashed or failed to start (caller should have checked this)");
             throw std::runtime_error("Piper server crashed or failed to start");
         }
 
@@ -111,7 +116,7 @@
         ReqId id = getId();
         builder.getId().setNumber(id);
 
-        auto karr = call(message, true);
+        auto karr = call(message, "list", true);
 
         capnp::FlatArrayMessageReader responseMessage(karr);
         piper::RpcResponse::Reader reader = responseMessage.getRoot<piper::RpcResponse>();
@@ -127,6 +132,7 @@
     loadPlugin(const LoadRequest &req) override {
 
         if (!m_transport->isOK()) {
+            log("Piper server crashed or failed to start (caller should have checked this)");
             throw std::runtime_error("Piper server crashed or failed to start");
         }
 
@@ -158,6 +164,7 @@
               PluginConfiguration config) override {
 
         if (!m_transport->isOK()) {
+            log("Piper server crashed or failed to start (caller should have checked this)");
             throw std::runtime_error("Piper server crashed or failed to start");
         }
 
@@ -172,7 +179,7 @@
         ReqId id = getId();
         builder.getId().setNumber(id);
 
-        auto karr = call(message, true);
+        auto karr = call(message, "configure", true);
 
         capnp::FlatArrayMessageReader responseMessage(karr);
         piper::RpcResponse::Reader reader = responseMessage.getRoot<piper::RpcResponse>();
@@ -196,6 +203,7 @@
             Vamp::RealTime timestamp) override {
 
         if (!m_transport->isOK()) {
+            log("Piper server crashed or failed to start (caller should have checked this)");
             throw std::runtime_error("Piper server crashed or failed to start");
         }
 
@@ -210,7 +218,7 @@
         ReqId id = getId();
         builder.getId().setNumber(id);
 
-        auto karr = call(message, false);
+        auto karr = call(message, "process", false);
 
         capnp::FlatArrayMessageReader responseMessage(karr);
         piper::RpcResponse::Reader reader = responseMessage.getRoot<piper::RpcResponse>();
@@ -231,6 +239,7 @@
     finish(PluginStub *plugin) override {
 
         if (!m_transport->isOK()) {
+            log("Piper server crashed or failed to start (caller should have checked this)");
             throw std::runtime_error("Piper server crashed or failed to start");
         }
 
@@ -244,7 +253,7 @@
         ReqId id = getId();
         builder.getId().setNumber(id);
         
-        auto karr = call(message, true);
+        auto karr = call(message, "finish", true);
 
         capnp::FlatArrayMessageReader responseMessage(karr);
         piper::RpcResponse::Reader reader = responseMessage.getRoot<piper::RpcResponse>();
@@ -271,8 +280,11 @@
           PluginConfiguration config) override {
 
         // Reload the plugin on the server side, and configure it as requested
+
+        log("CapnpRRClient: reset() called, plugin will be closed and reloaded");
         
         if (!m_transport->isOK()) {
+            log("Piper server crashed or failed to start (caller should have checked this)");
             throw std::runtime_error("Piper server crashed or failed to start");
         }
 
@@ -319,25 +331,27 @@
                       ReqId id) {
         
         if (r.getResponse().which() != type) {
-            std::cerr << "checkResponseType: wrong response type (received "
-                      << int(r.getResponse().which()) << ", expected "
-                      << int(type) << ")"
-                      << std::endl;
+            std::ostringstream s;
+            s << "checkResponseType: wrong response type (received "
+              << int(r.getResponse().which()) << ", expected " << int(type) << ")";
+            log(s.str());
             throw std::runtime_error("Wrong response type");
         }
         if (ReqId(r.getId().getNumber()) != id) {
-            std::cerr << "checkResponseType: wrong response id (received "
-                      << r.getId().getNumber() << ", expected " << id << ")"
-                      << std::endl;
+            std::ostringstream s;
+            s << "checkResponseType: wrong response id (received "
+              << r.getId().getNumber() << ", expected " << id << ")";
+            log(s.str());
             throw std::runtime_error("Wrong response id");
         }
     }
 
     kj::Array<capnp::word>
-    call(capnp::MallocMessageBuilder &message, bool slow) {
+    call(capnp::MallocMessageBuilder &message, std::string type, bool slow) {
         auto arr = capnp::messageToFlatArray(message);
         auto responseBuffer = m_transport->call(arr.asChars().begin(),
                                                 arr.asChars().size(),
+                                                type,
                                                 slow);
         return toKJArray(responseBuffer);
     }
@@ -359,7 +373,7 @@
         ReqId id = getId();
         builder.getId().setNumber(id);
 
-        auto karr = call(message, false);
+        auto karr = call(message, "load", false);
 
         //!!! ... --> will also need some way to kill this process
         //!!! (from another thread)
@@ -378,8 +392,14 @@
     };     
 
 private:
+    LogCallback *m_logger;
     SynchronousTransport *m_transport; //!!! I don't own this, but should I?
     CompletenessChecker *m_completenessChecker; // I own this
+    
+    void log(std::string message) const {
+        if (m_logger) m_logger->log(message);
+        else std::cerr << message << std::endl;
+    }
 };
 
 }
--- a/vamp-client/ProcessQtTransport.h	Fri Nov 04 10:43:49 2016 +0000
+++ b/vamp-client/ProcessQtTransport.h	Wed Nov 16 16:12:42 2016 +0000
@@ -63,7 +63,10 @@
 class ProcessQtTransport : public SynchronousTransport
 {
 public:
-    ProcessQtTransport(std::string processName, std::string formatArg) :
+    ProcessQtTransport(std::string processName,
+                       std::string formatArg,
+                       LogCallback *logger) : // logger may be nullptr for cerr
+        m_logger(logger),
         m_completenessChecker(0),
         m_crashed(false) {
 
@@ -78,20 +81,22 @@
             if (m_process->state() == QProcess::NotRunning) {
                 QProcess::ProcessError err = m_process->error();
                 if (err == QProcess::FailedToStart) {
-                    std::cerr << "Unable to start server process "
-                              << processName << std::endl;
+                    log("Unable to start server process " + processName);
                 } else if (err == QProcess::Crashed) {
-                    std::cerr << "Server process " << processName
-                              << " crashed on startup" << std::endl;
+                    log("Server process " + processName + " crashed on startup");
                 } else {
-                    std::cerr << "Server process " << processName
-                              << " failed on startup with error code "
-                              << err << std::endl;
+                    QString e = QString("%1").arg(err);
+                    log("Server process " + processName +
+                        " failed on startup with error code " + e.toStdString());
                 }
                 delete m_process;
                 m_process = nullptr;
             }
         }
+
+        if (m_process) {
+            log("Server process " + processName + " started OK");
+        }
     }
 
     ~ProcessQtTransport() {
@@ -101,9 +106,7 @@
                 m_process->waitForFinished(200);
                 m_process->close();
                 m_process->waitForFinished();
-#ifdef DEBUG_TRANSPORT
-                std::cerr << "server exited" << std::endl;
-#endif
+                log("Server process exited normally");
             }
             delete m_process;
         }
@@ -120,14 +123,16 @@
     }
     
     std::vector<char>
-    call(const char *ptr, size_t size, bool slow) override {
+    call(const char *ptr, size_t size, std::string type, bool slow) override {
 
         QMutexLocker locker(&m_mutex);
         
         if (!m_completenessChecker) {
+            log("call: No completeness checker set on transport");
             throw std::logic_error("No completeness checker set on transport");
         }
         if (!isOK()) {
+            log("call: Transport is not OK");
             throw std::logic_error("Transport is not OK");
         }
         
@@ -169,10 +174,11 @@
                     !m_process->bytesAvailable()) {
                     QProcess::ProcessError err = m_process->error();
                     if (err == QProcess::Crashed) {
-                        std::cerr << "Server crashed during request" << std::endl;
+                        log("Server crashed during " + type + " request");
                     } else {
-                        std::cerr << "Server failed during request with error code "
-                                  << err << std::endl;
+                        QString e = QString("%1").arg(err);
+                        log("Server failed during " + type
+                            + " request with error code " + e.toStdString());
                     }
                     m_crashed = true;
                     throw ServerCrashed();
@@ -189,10 +195,16 @@
     }
     
 private:
+    LogCallback *m_logger;
     MessageCompletenessChecker *m_completenessChecker; //!!! I don't own this (currently)
     QProcess *m_process; // I own this
     QMutex m_mutex;
     bool m_crashed;
+
+    void log(std::string message) const {
+        if (m_logger) m_logger->log(message);
+        else std::cerr << message << std::endl;
+    }
 };
 
 }
--- a/vamp-client/SynchronousTransport.h	Fri Nov 04 10:43:49 2016 +0000
+++ b/vamp-client/SynchronousTransport.h	Wed Nov 16 16:12:42 2016 +0000
@@ -47,7 +47,6 @@
 {
 public:
     virtual ~MessageCompletenessChecker() = default;
-    
     virtual bool isComplete(const std::vector<char> &message) const = 0;
 };
 
@@ -57,6 +56,13 @@
     ServerCrashed() : std::runtime_error("Piper server exited unexpectedly") {}
 };
 
+class LogCallback
+{
+public:
+    virtual ~LogCallback() { }
+    virtual void log(std::string) const = 0;
+};
+
 class SynchronousTransport // interface
 {
 public:
@@ -72,6 +78,8 @@
      * Make a synchronous call, passing a serialised request in the data array
      * of length bytes, and return the result.
      *
+     * The type field is only used for logging and debug output.
+     *
      * The slow flag is a hint that the recipient may take longer than usual
      * to process this request and so the caller may wish to be more relaxed
      * about idling to wait for the reply. (This shouldn't make any difference
@@ -81,7 +89,8 @@
      * call. Throws std::logic_error if isOK() is not true at the time of
      * calling, so check that before you call.
      */
-    virtual std::vector<char> call(const char *data, size_t bytes, bool slow) = 0;
+    virtual std::vector<char> call(const char *data, size_t bytes,
+                                   std::string type, bool slow) = 0;
 
     /**
      * Check whether the transport was initialised correctly and is working.
--- a/vamp-support/LoaderRequests.h	Fri Nov 04 10:43:49 2016 +0000
+++ b/vamp-support/LoaderRequests.h	Wed Nov 16 16:12:42 2016 +0000
@@ -44,6 +44,7 @@
 
 #include <map>
 #include <string>
+#include <iostream>
 
 namespace piper_vamp {
 
@@ -54,6 +55,8 @@
     listPluginData(ListRequest req) {
 
 	auto loader = Vamp::HostExt::PluginLoader::getInstance();
+
+        std::cerr << "listPluginData: about to ask loader to list plugins" << std::endl;
         
         std::vector<std::string> keys;
         if (req.from.empty()) {
@@ -62,8 +65,11 @@
             keys = loader->listPluginsIn(req.from);
         }
 
+        std::cerr << "listPluginData: loader listed " << keys.size() << " plugins" << std::endl;
+        
 	ListResponse response;
 	for (std::string key: keys) {
+            std::cerr << "listPluginData: loading plugin and querying static data: " << key << std::endl;
 	    Vamp::Plugin *p = loader->loadPlugin(key, 44100, 0);
 	    if (!p) continue;
 	    auto category = loader->getPluginCategory(key);