diff options
Diffstat (limited to 'lib/top_block_query.cpp')
-rw-r--r-- | lib/top_block_query.cpp | 101 |
1 files changed, 59 insertions, 42 deletions
diff --git a/lib/top_block_query.cpp b/lib/top_block_query.cpp index 29d3bb0..9d8afbe 100644 --- a/lib/top_block_query.cpp +++ b/lib/top_block_query.cpp @@ -4,15 +4,13 @@ #include <gras/top_block.hpp> #include <boost/foreach.hpp> #include <boost/property_tree/ptree.hpp> -#include <boost/property_tree/json_parser.hpp> -#include <boost/property_tree/xml_parser.hpp> -#include <boost/regex.hpp> #include <Theron/DefaultAllocator.h> #include <algorithm> -#include <sstream> using namespace gras; +using namespace boost::property_tree; + ThreadPool get_active_thread_pool(void); struct GetStatsReceiver : Theron::Receiver @@ -30,39 +28,47 @@ struct GetStatsReceiver : Theron::Receiver std::vector<GetStatsMessage> messages; }; -//http://stackoverflow.com/questions/13464383/boost-property-write-json-incorrect-behaviour -static std::string my_write_json(const boost::property_tree::ptree &pt) -{ - boost::regex exp("\"(null|true|false|[0-9]+(\\.[0-9]+)?)\""); - std::stringstream ss; - boost::property_tree::json_parser::write_json(ss, pt); - std::string rv = boost::regex_replace(ss.str(), exp, "$1"); - - return rv; -} - -static std::string query_blocks(ElementImpl *self, const boost::property_tree::ptree &) +static ptree query_blocks(ElementImpl *self, const ptree &) { - boost::property_tree::ptree root; - boost::property_tree::ptree e; + ptree root; + ptree e; BOOST_FOREACH(Apology::Worker *worker, self->executor->get_workers()) { - boost::property_tree::ptree t; - t.put_value(dynamic_cast<BlockActor *>(worker)->block_ptr->to_string()); - e.push_back(std::make_pair("", t)); + BlockActor *block = dynamic_cast<BlockActor *>(worker); + ptree prop_e; + typedef std::pair<std::string, PropertyRegistryPair> PropRegistryKVP; + BOOST_FOREACH(const PropRegistryKVP &p, block->property_registry) + { + ptree prop_attrs; + if (p.second.setter) + { + ptree type; + type.put_value(p.second.setter->type().name()); + prop_attrs.push_back(std::make_pair("setter", type)); + } + if (p.second.getter) + { + ptree type; + type.put_value(p.second.getter->type().name()); + prop_attrs.push_back(std::make_pair("getter", type)); + } + ptree block_attrs; + block_attrs.push_back(std::make_pair(p.first, prop_attrs)); + prop_e.push_back(std::make_pair("props", block_attrs)); + } + e.push_back(std::make_pair(block->block_ptr->to_string(), prop_e)); } root.push_back(std::make_pair("blocks", e)); - return my_write_json(root); + return root; } -static std::string query_stats(ElementImpl *self, const boost::property_tree::ptree &query) +static ptree query_stats(ElementImpl *self, const ptree &query) { - //parse list of block ids needed in this query std::vector<std::string> block_ids; - BOOST_FOREACH(const boost::property_tree::ptree::value_type &v, query.get_child("args")) + if (query.count("blocks") != 0) { - if (v.first.data() == std::string("block")) + BOOST_FOREACH(const ptree::value_type &v, query.get_child("blocks")) { block_ids.push_back(v.second.get<std::string>("")); } @@ -86,7 +92,7 @@ static std::string query_stats(ElementImpl *self, const boost::property_tree::pt while (outstandingCount) outstandingCount -= receiver.Wait(outstandingCount); //create root level node - boost::property_tree::ptree root; + ptree root; root.put("now", time_now()); root.put("tps", time_tps()); @@ -110,11 +116,11 @@ static std::string query_stats(ElementImpl *self, const boost::property_tree::pt } //iterate through blocks - boost::property_tree::ptree blocks; + ptree blocks; BOOST_FOREACH(const GetStatsMessage &message, receiver.messages) { const BlockStats &stats = message.stats; - boost::property_tree::ptree block; + ptree block; block.put("tps", time_tps()); block.put("stats_time", message.stats_time); block.put("init_time", stats.init_time); @@ -129,9 +135,9 @@ static std::string query_stats(ElementImpl *self, const boost::property_tree::pt block.put("total_time_output", stats.total_time_output); block.put("actor_queue_depth", stats.actor_queue_depth); #define my_block_ptree_append(l) { \ - boost::property_tree::ptree e; \ + ptree e; \ for (size_t i = 0; i < stats.l.size(); i++) { \ - boost::property_tree::ptree t; t.put_value(stats.l[i]); \ + ptree t; t.put_value(stats.l[i]); \ e.push_back(std::make_pair("", t)); \ } \ block.push_back(std::make_pair(#l, e)); \ @@ -151,22 +157,33 @@ static std::string query_stats(ElementImpl *self, const boost::property_tree::pt blocks.push_back(std::make_pair(message.block_id, block)); } root.push_back(std::make_pair("blocks", blocks)); + return root; +} - return my_write_json(root); +static ptree query_props(ElementImpl *self, const ptree &query) +{ + ptree root; + const std::string block_id = query.get<std::string>("block"); + const std::string prop_key = query.get<std::string>("key"); + const std::string action = query.get<std::string>("action"); + const std::string value = query.get<std::string>("value"); + //TODO :-) + return root; } +ptree json_to_ptree(const std::string &s); +std::string ptree_to_json(const ptree &p); + std::string TopBlock::query(const std::string &args) { - //why the fuck does no OS ever patch boost when there is a bug - //https://svn.boost.org/trac/boost/ticket/6785 - //serialize the path args into xml -- but I just wanted json - std::stringstream query_args_ss(args); - boost::property_tree::ptree query_args_pt; - boost::property_tree::xml_parser::read_xml(query_args_ss, query_args_pt); + //convert json args into property tree + const ptree query = json_to_ptree(args); //dispatch based on path arg - std::string path = query_args_pt.get<std::string>("args.path"); - if (path == "/blocks.json") return query_blocks(this->get(), query_args_pt); - if (path == "/stats.json") return query_stats(this->get(), query_args_pt); - return ""; + std::string path = query.get<std::string>("path"); + ptree result; + if (path == "/blocks.json") result = query_blocks(this->get(), query); + if (path == "/stats.json") result = query_stats(this->get(), query); + if (path == "/props.json") result = query_props(this->get(), query); + return ptree_to_json(result); } |