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 
14 #include "Stopwatch.hh"
15 
31 
32 class Server {
33  public:
34  Server();
35  Server(const Server&)=delete;
36  Server(const std::string& socket);
37  virtual ~Server();
38 
42  void run();
43 
44 
49 
50  class CatchOutput {
51  public:
52  CatchOutput();
53  CatchOutput(const CatchOutput&);
54 
55  void write(const std::string& txt);
56  void clear();
57  std::string str() const;
58  private:
59  std::string collect;
60  };
61 
63 
66 
84 
85  virtual uint64_t send(const std::string& output, const std::string& msg_type, uint64_t parent_id=0, bool last_in_sequence=false);
86 
87  void send_json(const std::string&);
88 
89  bool handles(const std::string& otype) const;
90  std::string architecture() const;
91 
94 
95  void wait_for_job();
96 
97  protected:
98  void init();
99 
100  // WebSocket++ dependent parts below.
101  typedef websocketpp::server<websocketpp::config::asio> WebsocketServer;
102  void on_socket_init(websocketpp::connection_hdl hdl, boost::asio::ip::tcp::socket & s);
103  void on_message(websocketpp::connection_hdl hdl, WebsocketServer::message_ptr msg);
104  void on_open(websocketpp::connection_hdl hdl);
105  void on_close(websocketpp::connection_hdl hdl);
107  std::string socket_name;
108 
109  // Connection tracking. There can be multiple connections to
110  // the server, but they all have access to the same Python
111  // scope. With multiple connections, one can inspect the Python
112  // stack from a different client (e.g. for debugging purposes).
113  // All connections share the same authentication token.
114 
115  class Connection {
116  public:
117  Connection();
118 
119  websocketpp::connection_hdl hdl;
120  boost::uuids::uuid uuid;
121  };
122  typedef std::map<websocketpp::connection_hdl, Connection,
123  std::owner_less<websocketpp::connection_hdl>> ConnectionMap;
125 
126  // Authentication token, needs to be sent along with any message.
127  // Gets set when the server announces its port.
128  std::string authentication_token;
129 
130  // Mutex to be able to use the websocket layer from both the
131  // main loop and the python-running thread.
132  std::mutex ws_mutex;
133 
134 
135  // Basics for the working thread that processes blocks.
136  std::thread runner;
138  std::condition_variable block_available;
139 
140  // Data and connection info for a single block of code.
141  class Block {
142  public:
143  Block(websocketpp::connection_hdl, const std::string&, uint64_t id);
144  websocketpp::connection_hdl hdl; // FIXME: decouple from websocket?
145  std::string input;
146  std::string output;
147  std::string error;
148  uint64_t cell_id;
149  };
150  std::queue<Block> block_queue;
151  websocketpp::connection_hdl current_hdl;
152  uint64_t current_id; // id of the block given to us by the client.
153 
154  // Run a piece of Python code. This is called from a separate
155  // thread constructed by on_message().
156  std::string run_string(const std::string&, bool handle_output=true);
157 
164 
165  virtual void on_block_finished(Block);
166  virtual void on_block_error(Block);
167  virtual void on_kernel_fault(Block);
168 
169 
170 
171 
172  uint64_t return_cell_id; // serial number of cells generated by us.
173 
176  void stop_block();
177  bool started;
178  std::future<std::string> job;
179 
183 
184  void dispatch_message(websocketpp::connection_hdl, const std::string& json_string);
185 
186  // Python global info.
187  pybind11::scoped_interpreter guard;
188  pybind11::module main_module;
189  pybind11::object main_namespace;
190 
191  // int cells_ran;
192  };
193 
void on_socket_init(websocketpp::connection_hdl hdl, boost::asio::ip::tcp::socket &s)
Definition: Server.cc:207
virtual void on_kernel_fault(Block)
Definition: Server.cc:483
Definition: Server.hh:141
Object representing a Cadabra server, capable of receiving messages on a websocket, running Python code, and sending output back to the client.
Definition: Server.hh:32
std::string error
Definition: Server.hh:147
pybind11::module main_module
Definition: Server.hh:188
std::string run_string(const std::string &, bool handle_output=true)
Definition: Server.cc:154
pybind11::object main_namespace
Definition: Server.hh:189
std::mutex ws_mutex
Definition: Server.hh:132
virtual ~Server()
Definition: Server.cc:48
void write(const std::string &txt)
Definition: Server.cc:61
websocketpp::config::asio_client::message_type::ptr message_ptr
Definition: ComputeThread.hh:13
virtual void on_block_error(Block)
Definition: Server.cc:457
void on_open(websocketpp::connection_hdl hdl)
Definition: Server.cc:219
virtual void on_block_finished(Block)
Called by the run_block() thread upon completion of the task.
Definition: Server.cc:406
std::thread runner
Definition: Server.hh:136
The Stopwach class provides a simple interace to allow timing function calls etc...
Definition: Stopwatch.hh:107
void send_json(const std::string &)
Definition: Server.cc:450
std::string socket_name
Definition: Server.hh:107
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:351
CatchOutput catchOut
Definition: Server.hh:62
std::string input
Definition: Server.hh:145
virtual uint64_t send(const std::string &output, const std::string &msg_type, uint64_t parent_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:417
std::condition_variable block_available
Definition: Server.hh:138
Definition: Server.hh:115
bool started
Definition: Server.hh:177
std::string collect
Definition: Server.hh:59
void wait_for_job()
Start a thread which waits for blocks to appear on the block queue, and executes them in turn...
Definition: Server.cc:243
uint64_t cell_id
Definition: Server.hh:148
Python output catching.
Definition: Server.hh:50
CatchOutput()
Definition: Server.cc:53
std::string authentication_token
Definition: Server.hh:128
std::queue< Block > block_queue
Definition: Server.hh:150
uint64_t return_cell_id
Definition: Server.hh:172
void on_close(websocketpp::connection_hdl hdl)
Definition: Server.cc:228
WebsocketServer wserver
Definition: Server.hh:106
void on_message(websocketpp::connection_hdl hdl, WebsocketServer::message_ptr msg)
Definition: Server.cc:334
void stop_block()
Halt the currently running block and prevent execution of any further blocks that may still be on the...
Definition: Server.cc:321
void clear()
Definition: Server.cc:67
uint64_t current_id
Definition: Server.hh:152
CatchOutput catchErr
Definition: Server.hh:62
websocketpp::connection_hdl current_hdl
Definition: Server.hh:151
std::string str() const
Definition: Server.cc:73
std::map< websocketpp::connection_hdl, Connection, std::owner_less< websocketpp::connection_hdl > > ConnectionMap
Definition: Server.hh:123
void run()
The only user-visible part: just instantiate a server object and start it with run().
Definition: Server.cc:509
std::mutex block_available_mutex
Definition: Server.hh:137
Server()
Definition: Server.cc:31
void init()
Definition: Server.cc:98
websocketpp::connection_hdl hdl
Definition: Server.hh:144
Stopwatch server_stopwatch
Definition: Server.hh:64
websocketpp::connection_hdl hdl
Definition: Server.hh:119
std::future< std::string > job
Definition: Server.hh:178
std::string architecture() const
Definition: Server.cc:78
Connection()
Definition: Server.cc:214
bool handles(const std::string &otype) const
Definition: Server.cc:411
pybind11::scoped_interpreter guard
Definition: Server.hh:187
std::string output
Definition: Server.hh:146
Stopwatch sympy_stopwatch
Definition: Server.hh:65
Block(websocketpp::connection_hdl, const std::string &, uint64_t id)
Definition: Server.cc:329
websocketpp::server< websocketpp::config::asio > WebsocketServer
Definition: Server.hh:101
boost::uuids::uuid uuid
Definition: Server.hh:120
ConnectionMap connections
Definition: Server.hh:124