Cadabra
Computer algebra system for field theory problems
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
Server.hh
Go to the documentation of this file.
1 
2 #pragma once
3 
4 #include <string>
5 #include <boost/uuid/uuid.hpp>
6 #include <websocketpp/server.hpp>
7 #include <websocketpp/config/asio_no_tls.hpp>
8 #include <websocketpp/common/functional.hpp>
9 #include <future>
10 #include <boost/python.hpp>
11 
12 #include "Stopwatch.hh"
13 #include "ProgressMonitor.hh"
14 
30 
31 class Server : public ProgressMonitor {
32  public:
33  Server();
34  Server(const Server&)=delete;
35  Server(const std::string& socket);
36  ~Server();
37 
41  void run();
42 
43 
48 
49  class CatchOutput {
50  public:
51  CatchOutput();
52  CatchOutput(const CatchOutput&);
53 
54  void write(const std::string& txt);
55  void clear();
56  std::string str() const;
57  private:
58  std::string collect;
59  };
60 
62 
65 
66  private:
67  void init();
68 
69  // WebSocket++ dependent parts below.
70  typedef websocketpp::server<websocketpp::config::asio> WebsocketServer;
71  void on_socket_init(websocketpp::connection_hdl hdl, boost::asio::ip::tcp::socket & s);
72  void on_message(websocketpp::connection_hdl hdl, WebsocketServer::message_ptr msg);
73  void on_open(websocketpp::connection_hdl hdl);
74  void on_close(websocketpp::connection_hdl hdl);
76  std::string socket_name;
77 
78  // Connection tracking. There can be multiple connections to
79  // the server, but they all have access to the same Python
80  // scope. With multiple connections, one can inspect the Python
81  // stack from a different client (e.g. for debugging purposes).
82 
83  class Connection {
84  public:
85  Connection();
86 
87  websocketpp::connection_hdl hdl;
88  boost::uuids::uuid uuid;
89  };
90  typedef std::map<websocketpp::connection_hdl, Connection,
91  std::owner_less<websocketpp::connection_hdl>> ConnectionMap;
93 
94  // Mutex to be able to use the websocket layer from both the
95  // main loop and the python-running thread.
96  std::mutex ws_mutex;
97 
98 
99  // Basics for the working thread that processes blocks.
100  std::thread runner;
102  std::condition_variable block_available;
103  void wait_for_job();
104 
105  // Data and connection info for a single block of code.
106  class Block {
107  public:
108  Block(websocketpp::connection_hdl, const std::string&, uint64_t id);
109  websocketpp::connection_hdl hdl; // FIXME: decouple from websocket?
110  std::string input;
111  std::string output;
112  std::string error;
113  uint64_t cell_id;
114  };
115  std::queue<Block> block_queue;
116  websocketpp::connection_hdl current_hdl;
117  uint64_t current_id; // id of the block given to us by the client.
118 
119  // Run a piece of Python code. This is called from a separate
120  // thread constructed by on_message().
121  std::string run_string(const std::string&, bool handle_output=true);
122 
129 
130  void on_block_finished(Block);
131  void on_block_error(Block);
132  void on_kernel_fault(Block);
133 
134  std::string architecture() const;
135 
136  bool handles(const std::string& otype) const;
137 
155 
156  uint64_t send(const std::string& output, const std::string& msg_type, uint64_t parent_id=0, bool last_in_sequence=false);
157  void send_json(const std::string&);
158 
159  uint64_t return_cell_id; // serial number of cells generated by us.
160 
163  void stop_block();
164  bool started;
165  std::future<std::string> job;
166 
170 
171  void dispatch_message(websocketpp::connection_hdl, const std::string& json_string);
172 
173  // Python global info.
174  boost::python::object main_module;
175  boost::python::object main_namespace;
176 
178 };
179 
void on_socket_init(websocketpp::connection_hdl hdl, boost::asio::ip::tcp::socket &s)
Definition: Server.cc:217
void on_kernel_fault(Block)
Definition: Server.cc:458
Definition: Server.hh:106
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:31
std::string error
Definition: Server.hh:112
int cells_ran
Definition: Server.hh:177
std::string run_string(const std::string &, bool handle_output=true)
Definition: Server.cc:163
boost::python::object main_module
Definition: Server.hh:174
std::mutex ws_mutex
Definition: Server.hh:96
~Server()
Definition: Server.cc:52
void write(const std::string &txt)
Definition: Server.cc:65
websocketpp::config::asio_client::message_type::ptr message_ptr
Definition: ComputeThread.hh:12
Definition: ProgressMonitor.hh:10
void on_block_error(Block)
Definition: Server.cc:432
void on_open(websocketpp::connection_hdl hdl)
Definition: Server.cc:228
void on_block_finished(Block)
Called by the run_block() thread upon completion of the task.
Definition: Server.cc:381
std::thread runner
Definition: Server.hh:100
Definition: Stopwatch.hh:32
void send_json(const std::string &)
Definition: Server.cc:425
std::string socket_name
Definition: Server.hh:76
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:335
CatchOutput catchOut
Definition: Server.hh:61
std::string input
Definition: Server.hh:110
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:392
boost::python::object main_namespace
Definition: Server.hh:175
std::condition_variable block_available
Definition: Server.hh:102
Definition: Server.hh:83
bool started
Definition: Server.hh:164
std::string collect
Definition: Server.hh:58
void wait_for_job()
Definition: Server.cc:252
uint64_t cell_id
Definition: Server.hh:113
Python output catching.
Definition: Server.hh:49
CatchOutput()
Definition: Server.cc:57
std::string str() const
Definition: Server.cc:77
std::queue< Block > block_queue
Definition: Server.hh:115
uint64_t return_cell_id
Definition: Server.hh:159
void on_close(websocketpp::connection_hdl hdl)
Definition: Server.cc:237
WebsocketServer wserver
Definition: Server.hh:75
void on_message(websocketpp::connection_hdl hdl, WebsocketServer::message_ptr msg)
Definition: Server.cc:320
bool handles(const std::string &otype) const
Definition: Server.cc:386
void stop_block()
Halt the currently running block and prevent execution of any further blocks that may still be on the...
Definition: Server.cc:307
void clear()
Definition: Server.cc:71
uint64_t current_id
Definition: Server.hh:117
CatchOutput catchErr
Definition: Server.hh:61
websocketpp::connection_hdl current_hdl
Definition: Server.hh:116
std::map< websocketpp::connection_hdl, Connection, std::owner_less< websocketpp::connection_hdl > > ConnectionMap
Definition: Server.hh:91
void run()
The only user-visible part: just instantiate a server object and start it with run().
Definition: Server.cc:484
std::mutex block_available_mutex
Definition: Server.hh:101
Server()
Definition: Server.cc:37
void init()
Definition: Server.cc:87
websocketpp::connection_hdl hdl
Definition: Server.hh:109
Stopwatch server_stopwatch
Definition: Server.hh:63
websocketpp::connection_hdl hdl
Definition: Server.hh:87
std::future< std::string > job
Definition: Server.hh:165
std::string architecture() const
Definition: Server.cc:82
Connection()
Definition: Server.cc:223
std::string output
Definition: Server.hh:111
Stopwatch sympy_stopwatch
Definition: Server.hh:64
Block(websocketpp::connection_hdl, const std::string &, uint64_t id)
Definition: Server.cc:315
websocketpp::server< websocketpp::config::asio > WebsocketServer
Definition: Server.hh:70
boost::uuids::uuid uuid
Definition: Server.hh:88
ConnectionMap connections
Definition: Server.hh:92