Cadabra
Computer algebra system for field theory problems
Server.hh
Go to the documentation of this file.
1 
2 #pragma once
3 
4 #include <websocketpp/server.hpp>
5 #include <websocketpp/config/asio_no_tls.hpp>
6 #include <websocketpp/common/functional.hpp>
7 #include <string>
8 #include <signal.h>
9 #include <boost/uuid/uuid.hpp>
10 #include <future>
11 #include <pybind11/pybind11.h>
12 #include <pybind11/embed.h>
13 #include "nlohmann/json.hpp"
14 
15 #include "Stopwatch.hh"
16 
32 
33 class Server {
34  public:
35  Server();
36  Server(const Server&)=delete;
37  Server(const std::string& socket);
38  virtual ~Server();
39 
46 
47  void run(int port=0, bool exit_on_disconnect=true);
48 
49 
54 
55  class CatchOutput {
56  public:
57  CatchOutput();
58  CatchOutput(const CatchOutput&);
59 
60  void write(const std::string& txt);
61  void clear();
62  std::string str() const;
63  private:
64  std::string collect;
65  };
66 
68 
71 
93 
94  virtual uint64_t send(const std::string& output, const std::string& msg_type,
95  uint64_t parent_id=0, uint64_t cell_id=0, bool last_in_sequence=false);
96 // virtual void send_completion(uint64_t id, int pos, int alternative, std::string original, std::string completed);
97 
98  void send_progress_update(const std::string& msg, int n, int total);
99  void send_json(const std::string&);
100 
101  bool handles(const std::string& otype) const;
102  std::string architecture() const;
103 
107  void wait_for_job();
108 
111  void wait_for_websocket();
112 
113  protected:
114  void init();
115 
116  // WebSocket++ dependent parts below.
117  typedef websocketpp::server<websocketpp::config::asio> WebsocketServer;
118  void on_socket_init(websocketpp::connection_hdl hdl, boost::asio::ip::tcp::socket & s);
119  void on_message(websocketpp::connection_hdl hdl, WebsocketServer::message_ptr msg);
120  void on_open(websocketpp::connection_hdl hdl);
121  void on_close(websocketpp::connection_hdl hdl);
123  std::string socket_name;
124 
125  // Connection tracking. There can be multiple connections to
126  // the server, but they all have access to the same Python
127  // scope. With multiple connections, one can inspect the Python
128  // stack from a different client (e.g. for debugging purposes).
129  // All connections share the same authentication token.
130 
131  class Connection {
132  public:
133  Connection();
134 
135  websocketpp::connection_hdl hdl;
136  boost::uuids::uuid uuid;
137  };
138  typedef std::map<websocketpp::connection_hdl, Connection,
139  std::owner_less<websocketpp::connection_hdl>> ConnectionMap;
141 
142  // Authentication token, needs to be sent along with any message.
143  // Gets set when the server announces its port.
144  std::string authentication_token;
145 
146  // Mutex to be able to use the websocket layer from both the
147  // main loop and the python-running thread.
148  std::mutex ws_mutex;
149 
150 
151  // Basics for the working thread that processes blocks.
152  std::thread runner;
154  std::condition_variable block_available;
157  unsigned long main_thread_id;
158 
159  // Data and connection info for a single block of code.
160  class Block {
161  public:
162  Block(websocketpp::connection_hdl, const std::string&, uint64_t id, const std::string& msg_type);
163  websocketpp::connection_hdl hdl; // FIXME: decouple from websocket?
164  std::string msg_type;
165  std::string input;
166  std::string output;
167  std::string error;
168  uint64_t cell_id;
169 
170  // Response message, partially filled in when the
171  // request comes in.
172  nlohmann::json response;
173  };
174  std::queue<Block> block_queue;
175  websocketpp::connection_hdl current_hdl;
176  uint64_t current_id; // id of the block given to us by the client.
177 
178  // Run a piece of Python code. This is called from a separate
179  // thread constructed by on_message().
180  std::string run_string(const std::string&, bool handle_output=true);
181 
188 
189  virtual void on_block_finished(Block);
190  virtual void on_block_error(Block);
191  virtual void on_kernel_fault(Block);
192 
193 // uint64_t return_cell_id; // serial number of cells generated by us.
194 
197  void stop_block();
198  bool started;
199  std::future<std::string> job;
200 
204 
205  void dispatch_message(websocketpp::connection_hdl, const std::string& json_string);
206 
207  // Python global info.
208  pybind11::scoped_interpreter guard;
209  pybind11::module main_module;
210  pybind11::object main_namespace;
211 
212  // int cells_ran;
213  };
websocketpp::config::asio_client::message_type::ptr message_ptr
Definition: ComputeThread.hh:14
Definition: Server.hh:160
Block(websocketpp::connection_hdl, const std::string &, uint64_t id, const std::string &msg_type)
Definition: Server.cc:449
std::string input
Definition: Server.hh:165
uint64_t cell_id
Definition: Server.hh:168
websocketpp::connection_hdl hdl
Definition: Server.hh:163
std::string output
Definition: Server.hh:166
std::string msg_type
Definition: Server.hh:164
std::string error
Definition: Server.hh:167
nlohmann::json response
Definition: Server.hh:172
Python output catching.
Definition: Server.hh:55
void clear()
Definition: Server.cc:72
std::string str() const
Definition: Server.cc:78
CatchOutput()
Definition: Server.cc:58
std::string collect
Definition: Server.hh:64
void write(const std::string &txt)
Definition: Server.cc:66
Definition: Server.hh:131
boost::uuids::uuid uuid
Definition: Server.hh:136
websocketpp::connection_hdl hdl
Definition: Server.hh:135
Connection()
Definition: Server.cc:288
Object representing a Cadabra server, capable of receiving messages on a websocket,...
Definition: Server.hh:33
websocketpp::server< websocketpp::config::asio > WebsocketServer
Definition: Server.hh:117
void send_progress_update(const std::string &msg, int n, int total)
Definition: Server.cc:629
void init()
Definition: Server.cc:141
websocketpp::connection_hdl current_hdl
Definition: Server.hh:175
CatchOutput catchErr
Definition: Server.hh:67
virtual void on_block_error(Block)
Definition: Server.cc:659
virtual void on_block_finished(Block)
Called by the run_block() thread upon completion of the task.
Definition: Server.cc:552
pybind11::object main_namespace
Definition: Server.hh:210
std::thread runner
Definition: Server.hh:152
std::string authentication_token
Definition: Server.hh:144
pybind11::module main_module
Definition: Server.hh:209
virtual void on_kernel_fault(Block)
Definition: Server.cc:688
ConnectionMap connections
Definition: Server.hh:140
std::future< std::string > job
Definition: Server.hh:199
std::string socket_name
Definition: Server.hh:123
virtual ~Server()
Definition: Server.cc:53
Stopwatch sympy_stopwatch
Definition: Server.hh:70
std::mutex ws_mutex
Definition: Server.hh:148
WebsocketServer wserver
Definition: Server.hh:122
CatchOutput catchOut
Definition: Server.hh:67
virtual uint64_t send(const std::string &output, const std::string &msg_type, uint64_t parent_id=0, uint64_t cell_id=0, bool last_in_sequence=false)
Raw code to send a string (which must be JSON formatted) as a message to the client.
Definition: Server.cc:588
unsigned long main_thread_id
Definition: Server.hh:157
void on_close(websocketpp::connection_hdl hdl)
Definition: Server.cc:302
void wait_for_job()
Thread entry point for the code that waits for blocks to appear on the block queue,...
Definition: Server.cc:349
void on_message(websocketpp::connection_hdl hdl, WebsocketServer::message_ptr msg)
Definition: Server.cc:458
bool handles(const std::string &otype) const
Definition: Server.cc:582
std::map< websocketpp::connection_hdl, Connection, std::owner_less< websocketpp::connection_hdl > > ConnectionMap
Definition: Server.hh:139
int run_on_port
Definition: Server.hh:156
void run(int port=0, bool exit_on_disconnect=true)
The only user-visible part: just instantiate a server object and start it with run().
Definition: Server.cc:717
Server(const Server &)=delete
std::string architecture() const
Definition: Server.cc:83
void on_open(websocketpp::connection_hdl hdl)
Definition: Server.cc:293
std::mutex block_available_mutex
Definition: Server.hh:153
pybind11::scoped_interpreter guard
Definition: Server.hh:208
std::string run_string(const std::string &, bool handle_output=true)
Definition: Server.cc:214
std::queue< Block > block_queue
Definition: Server.hh:174
Server()
Definition: Server.cc:36
bool exit_on_disconnect
Definition: Server.hh:155
std::condition_variable block_available
Definition: Server.hh:154
void stop_block()
Halt the currently running block and prevent execution of any further blocks that may still be on the...
Definition: Server.cc:432
void send_json(const std::string &)
Definition: Server.cc:652
void dispatch_message(websocketpp::connection_hdl, const std::string &json_string)
Takes a JSON encoded message and performs the required action to process it.
Definition: Server.cc:475
Stopwatch server_stopwatch
Definition: Server.hh:69
void on_socket_init(websocketpp::connection_hdl hdl, boost::asio::ip::tcp::socket &s)
Definition: Server.cc:281
void wait_for_websocket()
Thread entry point for code that sets up and runs the websocket listener.
Definition: Server.cc:321
uint64_t current_id
Definition: Server.hh:176
bool started
Definition: Server.hh:198
The Stopwach class provides a simple interace to allow timing function calls etc.....
Definition: Stopwatch.hh:107