From bb0bb0de8abf9a2e947b9a6ec1e2642b591052b0 Mon Sep 17 00:00:00 2001
From: Simon Oehrl <simon.oehrl@rwth-aachen.de>
Date: Sat, 4 Apr 2020 23:27:14 +0200
Subject: [PATCH] Add current simulation time endpoint

---
 data_storage.cpp             | 14 +++++++
 data_storage.hpp             |  6 +++
 http_server.cpp              | 11 ++++++
 http_server.hpp              |  2 +
 recording_backend_insite.cpp | 73 ++++++++++++++++++------------------
 5 files changed, 70 insertions(+), 36 deletions(-)

diff --git a/data_storage.cpp b/data_storage.cpp
index 8c2660b..daef44f 100644
--- a/data_storage.cpp
+++ b/data_storage.cpp
@@ -1,6 +1,7 @@
 #include "data_storage.hpp"
 
 #include <algorithm>
+#include <cstring>
 
 namespace insite {
 
@@ -141,4 +142,17 @@ std::unordered_map<std::uint64_t, std::unordered_map<std::string,
   return measurements;
 }
 
+void DataStorage::SetCurrentSimulationTime(double simulation_time) {
+  uint64_t simulation_time_int;
+  memcpy(&simulation_time_int, &simulation_time, sizeof(simulation_time_int));
+  current_simulation_time_ = simulation_time_int;
+}
+
+double DataStorage::GetCurrentSimulationTime() const {
+  const uint64_t simulation_time_int =current_simulation_time_;
+  double simulation_time;
+  memcpy(&simulation_time, &simulation_time_int, sizeof(simulation_time));
+  return simulation_time;
+}
+
 }  // namespace insite
diff --git a/data_storage.hpp b/data_storage.hpp
index 2f9de3c..0ecdbef 100644
--- a/data_storage.hpp
+++ b/data_storage.hpp
@@ -7,6 +7,7 @@
 #include <string>
 #include <unordered_map>
 #include <vector>
+#include <atomic>
 
 namespace insite {
 
@@ -45,6 +46,9 @@ class DataStorage {
   std::unordered_map<std::uint64_t, std::unordered_map<std::string, 
     MultimeterMeasurements>> GetMultimeterMeasurements();
 
+  void SetCurrentSimulationTime(double simulation_time);
+  double GetCurrentSimulationTime() const;
+
  private:
   // std::unique_ptr<H5::H5File> h5_file_;
 
@@ -54,6 +58,8 @@ class DataStorage {
   // H5::DataSet spikes_neurons_dataset_;
   std::mutex spike_mutex_;
 
+  std::atomic_uint64_t current_simulation_time_;
+
   // Device ID to attribute index to measurement map.
   std::unordered_map<std::uint64_t, std::unordered_map<std::string, 
     MultimeterMeasurements>> buffered_measurements_;
diff --git a/http_server.cpp b/http_server.cpp
index e8a3a31..7acd642 100644
--- a/http_server.cpp
+++ b/http_server.cpp
@@ -14,6 +14,9 @@ HttpServer::HttpServer(web::http::uri address, DataStorage* storage)
     } else if (request.method() == "GET" &&
         request.relative_uri().path() == "/multimeter_measurement") {
       request.reply(GetMultimeterMeasurement(request));
+    } else if (request.method() == "GET" &&
+        request.relative_uri().path() == "/current_simulation_time") {
+      request.reply(GetCurrentSimulationTime(request));
     } else {
       std::cerr << "Invalid request: " << request.to_string() << "\n";
       request.reply(web::http::status_codes::NotFound);
@@ -24,6 +27,14 @@ HttpServer::HttpServer(web::http::uri address, DataStorage* storage)
   std::cout << "HTTP server is listening...\n";
 }
 
+web::http::http_response HttpServer::GetCurrentSimulationTime(
+    const web::http::http_request& request) {
+  web::http::http_response response(web::http::status_codes::OK);
+  web::json::value simulation_time = storage_->GetCurrentSimulationTime();
+  response.set_body(simulation_time);
+  return response;
+}
+
 web::http::http_response HttpServer::GetSpikes(
     const web::http::http_request& request) {
   const auto parameters = web::uri::split_query(request.request_uri().query());
diff --git a/http_server.hpp b/http_server.hpp
index 74ae309..7e9a734 100644
--- a/http_server.hpp
+++ b/http_server.hpp
@@ -16,6 +16,8 @@ class HttpServer {
   web::http::experimental::listener::http_listener http_listener_;
   DataStorage* storage_;
 
+  web::http::http_response GetCurrentSimulationTime(const web::http::http_request& request);
+
   web::http::http_response GetSpikes(const web::http::http_request& request);
   
   web::http::http_response GetMultimeterMeasurement(
diff --git a/recording_backend_insite.cpp b/recording_backend_insite.cpp
index 3230485..7b80a00 100644
--- a/recording_backend_insite.cpp
+++ b/recording_backend_insite.cpp
@@ -128,18 +128,19 @@ void RecordingBackendInsite::post_run_hook() {
 }
 
 void RecordingBackendInsite::post_step_hook() {
-  // Send simulation time
-  {
-    pqxx::work txn(database_connection_);
-    txn.exec0(
-        "UPDATE nest_simulation_node "
-        "SET current_simulation_time = " +
-        std::to_string(latest_simulation_time_) +
-        ""
-        "WHERE id = " +
-        std::to_string(simulation_node_id_));
-    txn.commit();
-  }
+  // // Send simulation time
+  // {
+  //   pqxx::work txn(database_connection_);
+  //   txn.exec0(
+  //       "UPDATE nest_simulation_node "
+  //       "SET current_simulation_time = " +
+  //       std::to_string(latest_simulation_time_) +
+  //       ""
+  //       "WHERE id = " +
+  //       std::to_string(simulation_node_id_));
+  //   txn.commit();
+  // }
+  data_storage_.SetCurrentSimulationTime(latest_simulation_time_);
 
   if (new_neuron_infos_.size() > 0) {
     std::stringstream neuron_query;
@@ -190,30 +191,30 @@ void RecordingBackendInsite::post_step_hook() {
   }
 
   // Send multimeter info
-  for (auto& kvp : multimeter_infos_) {
-    auto& multimeter = kvp.second;
-    if (!multimeter.needs_update) continue;
-    multimeter.needs_update = false;
-
-    if (multimeter.gids.size() > 0) {
-      std::stringstream neuron_multimeter_query;
-      neuron_multimeter_query
-          << "INSERT INTO nest_neuron_multimeter (neuron_id, multimeter_id) "
-          << "VALUES ";
-
-      for (const auto& neuron_id : multimeter.gids) {
-        const bool first = neuron_id == multimeter.gids[0];
-        neuron_multimeter_query << (first ? "" : ",") << "(" << neuron_id << ","
-                                << multimeter.device_id << ")";
-      }
-
-      neuron_multimeter_query << " ON CONFLICT DO NOTHING;";
-
-      pqxx::work txn(database_connection_);
-      txn.exec0(neuron_multimeter_query.str());
-      txn.commit();
-    }
-  }
+  // for (auto& kvp : multimeter_infos_) {
+  //   auto& multimeter = kvp.second;
+  //   if (!multimeter.needs_update) continue;
+  //   multimeter.needs_update = false;
+
+  //   if (multimeter.gids.size() > 0) {
+  //     std::stringstream neuron_multimeter_query;
+  //     neuron_multimeter_query
+  //         << "INSERT INTO nest_neuron_multimeter (neuron_id, multimeter_id) "
+  //         << "VALUES ";
+
+  //     for (const auto& neuron_id : multimeter.gids) {
+  //       const bool first = neuron_id == multimeter.gids[0];
+  //       neuron_multimeter_query << (first ? "" : ",") << "(" << neuron_id << ","
+  //                               << multimeter.device_id << ")";
+  //     }
+
+  //     neuron_multimeter_query << " ON CONFLICT DO NOTHING;";
+
+  //     pqxx::work txn(database_connection_);
+  //     txn.exec0(neuron_multimeter_query.str());
+  //     txn.commit();
+  //   }
+  // }
 }
 
 void RecordingBackendInsite::write(const nest::RecordingDevice& device,
-- 
GitLab