https://mooseframework.inl.gov
WebServerControl.h
Go to the documentation of this file.
1 //* This file is part of the MOOSE framework
2 //* https://mooseframework.inl.gov
3 //*
4 //* All rights reserved, see COPYRIGHT for full restrictions
5 //* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6 //*
7 //* Licensed under LGPL 2.1, please see LICENSE for details
8 //* https://www.gnu.org/licenses/lgpl-2.1.html
9 
10 #pragma once
11 
12 #include "Control.h"
13 
15 
16 #include "tinyhttp/http.h"
17 
18 #include <atomic>
19 #include <memory>
20 #include <thread>
21 
26 class WebServerControl : public Control
27 {
28 public:
30 
33 
34  virtual void execute() override;
35 
39  static std::string stringifyJSONType(const miniJson::JsonType & json_type);
40 
45  template <typename T, miniJson::JsonType json_type>
46  static T getScalarJSONValue(const miniJson::Json & json_value);
47 
49 
53  template <typename T>
54  class TypedValueBase : public ValueBase
55  {
56  public:
57  TypedValueBase(const std::string & name, const std::string & type) : ValueBase(name, type) {}
58  TypedValueBase(const std::string & name, const std::string & type, const T & value)
60  {
61  }
62 
66  const T & value() const { return _value; }
67 
68  virtual void setControllableValue(WebServerControl & control) override final
69  {
70  control.comm().broadcast(_value);
71  control.setControllableValueByName<T>(name(), value());
72  }
73 
74  private:
76  T _value;
77  };
78 
82  template <typename T, miniJson::JsonType json_type>
83  class ScalarValue : public TypedValueBase<T>
84  {
85  public:
86  ScalarValue(const std::string & name, const std::string & type) : TypedValueBase<T>(name, type)
87  {
88  }
89  ScalarValue(const std::string & name,
90  const std::string & type,
91  const miniJson::Json & json_value)
92  : TypedValueBase<T>(name, type, getScalarJSONValue<T, json_type>(json_value))
93  {
94  }
95  };
96 
100  template <typename T, miniJson::JsonType json_type>
101  class VectorValue : public TypedValueBase<std::vector<T>>
102  {
103  public:
104  VectorValue(const std::string & name, const std::string & type)
105  : TypedValueBase<std::vector<T>>(name, type)
106  {
107  }
108  VectorValue(const std::string & name,
109  const std::string & type,
110  const miniJson::Json & json_value)
111  : TypedValueBase<std::vector<T>>(name, type, getVectorJSONValue(json_value))
112  {
113  }
114 
115  static std::vector<T> getVectorJSONValue(const miniJson::Json & json_value)
116  {
117  const auto from_json_type = json_value.getType();
118  if (from_json_type != miniJson::JsonType::kArray)
119  throw ValueBase::Exception("The value '" + json_value.serialize() + "' of type " +
120  stringifyJSONType(from_json_type) + " is not an array");
121 
122  const auto & array_value = json_value.toArray();
123  std::vector<T> value(array_value.size());
124  for (const auto i : index_range(array_value))
125  value[i] = getScalarJSONValue<T, json_type>(array_value[i]);
126  return value;
127  }
128  };
129 
133  template <typename T, miniJson::JsonType json_type>
134  static char registerScalarType(const std::string type_name)
135  {
137  }
141  template <typename T, miniJson::JsonType json_type>
142  static char registerVectorType(const std::string type_name)
143  {
145  type_name + ">");
146  }
147 
148 private:
152  void startServer();
153 
157  bool currentlyWaiting() const { return _currently_waiting.load(); }
158 
160  std::atomic<bool> _currently_waiting;
161 
163  std::unique_ptr<HttpServer> _server;
165  std::unique_ptr<std::thread> _server_thread;
166 
168  std::vector<std::unique_ptr<ValueBase>> _controlled_values;
171 };
172 
173 template <typename T, miniJson::JsonType json_type>
174 T
175 WebServerControl::getScalarJSONValue(const miniJson::Json & json_value)
176 {
177  const auto from_json_type = json_value.getType();
178  if (from_json_type != json_type)
179  throw ValueBase::Exception("The value " + json_value.serialize() + " of JSON type " +
180  stringifyJSONType(from_json_type) +
181  " is not of the expected JSON type " + stringifyJSONType(json_type));
182 
183  if constexpr (json_type == miniJson::JsonType::kBool)
184  return json_value.toBool();
185  else if constexpr (json_type == miniJson::JsonType::kNumber)
186  return json_value.toDouble();
187  else if constexpr (json_type == miniJson::JsonType::kString)
188  return json_value.toString();
189  ::mooseError("WebServerControl::getScalarJSONValue(): Not configured for parsing type ",
190  stringifyJSONType(from_json_type));
191 }
std::atomic< bool > _currently_waiting
Whether or not the Control is currently waiting.
static char registerScalarType(const std::string type_name)
Registers a scalar parameter type to be controlled.
Starts a webserver that an external process can connect to in order to send JSON messages to control ...
void startServer()
Internal method for starting the server.
Class that stores a scalar controllable value to be set.
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
WebServerControl(const InputParameters &parameters)
The base class for a value that is produced by this registry.
Common exception for parsing related errors in converting JSON to a value.
T _value
The underlying value.
static char registerVectorType(const std::string type_name)
Registers a vector parameter type to be controlled.
A static registry used to register and build values of different types for the WebServerControl.
Base class for a controllable value with a given type and name.
std::vector< std::unique_ptr< ValueBase > > _controlled_values
The values received to control; filled on rank 0 from the server and then broadcast.
TypedValueBase(const std::string &name, const std::string &type)
VectorValue(const std::string &name, const std::string &type)
std::mutex _controlled_values_mutex
Mutex to prevent threaded writes to _controlled_values.
static T getScalarJSONValue(const miniJson::Json &json_value)
Class that stores a vector controllable value to be set.
ScalarValue(const std::string &name, const std::string &type, const miniJson::Json &json_value)
static std::string stringifyJSONType(const miniJson::JsonType &json_type)
TypedValueBase(const std::string &name, const std::string &type, const T &value)
std::unique_ptr< std::thread > _server_thread
The server thread.
Base class for Control objects.
Definition: Control.h:33
virtual void execute() override
Execute the control.
virtual void setControllableValue(WebServerControl &control) override final
Sets the controllable value given the name and type via the controllable interface in control...
void mooseError(Args &&... args) const
Emits an error prefixed with object name and type.
const InputParameters & parameters() const
Get the parameters of the object.
ScalarValue(const std::string &name, const std::string &type)
static InputParameters validParams()
static char add(const std::string &type_name)
Registers a type with string name type_name and the given derived type.
static std::vector< T > getVectorJSONValue(const miniJson::Json &json_value)
auto index_range(const T &sizable)
bool currentlyWaiting() const
std::unique_ptr< HttpServer > _server
The server.
VectorValue(const std::string &name, const std::string &type, const miniJson::Json &json_value)