Merge lp:~mohyt/drizzle/drizzle-json_server-multithreading into lp:drizzle
- drizzle-json_server-multithreading
- Merge into 7.2
Proposed by
Mohit Srivastava
Status: | Merged |
---|---|
Approved by: | Henrik Ingo |
Approved revision: | 2572 |
Merged at revision: | 2573 |
Proposed branch: | lp:~mohyt/drizzle/drizzle-json_server-multithreading |
Merge into: | lp:drizzle |
Diff against target: |
694 lines (+330/-79) 7 files modified
plugin/json_server/docs/index.rst (+62/-10) plugin/json_server/http_server.cc (+60/-0) plugin/json_server/http_server.h (+67/-0) plugin/json_server/json_server.cc (+130/-60) plugin/json_server/plugin.ini (+2/-0) plugin/json_server/tests/r/basic.result (+6/-6) plugin/json_server/tests/t/basic.test (+3/-3) |
To merge this branch: | bzr merge lp:~mohyt/drizzle/drizzle-json_server-multithreading |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Drizzle Trunk | Pending | ||
Review via email: mp+115325@code.launchpad.net |
Commit message
Description of the change
To post a comment you must log in.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'plugin/json_server/docs/index.rst' |
2 | --- plugin/json_server/docs/index.rst 2012-06-25 09:31:28 +0000 |
3 | +++ plugin/json_server/docs/index.rst 2012-07-17 12:13:20 +0000 |
4 | @@ -39,6 +39,7 @@ |
5 | |
6 | :Default: 8086 |
7 | :Variable: :ref:`json_server_port <json_server_port>` |
8 | + :Since: 0.1 |
9 | |
10 | Port number to use for connection or 0 for default (port 8086) |
11 | |
12 | @@ -46,6 +47,7 @@ |
13 | |
14 | :Default: test |
15 | :Variable: :ref:`json_server_schema <json_server_schema>` |
16 | + :Since: 0.3 |
17 | |
18 | Schema which is used when not explicitly specified in request URI. |
19 | Note: Currently this is in the /json API only. |
20 | @@ -54,6 +56,7 @@ |
21 | |
22 | :Default: |
23 | :Variable: :ref:`json_server_table <json_server_table>` |
24 | + :Since: 0.3 |
25 | |
26 | Table which is used when not explicitly specified in request URI. |
27 | Note: Currently this is in the /json API only. |
28 | @@ -62,11 +65,22 @@ |
29 | |
30 | :Default: OFF |
31 | :Variable: :ref:`json_server_allow_drop_table <json_server_allow_drop_table>` |
32 | + :Since: 0.3 |
33 | |
34 | When json-server.allow_drop_table is set to ON, it is possible to drop |
35 | a table with a HTTP DELETE request with no _id specified. When set to OFF |
36 | (the default), omitting _id will result in an error. |
37 | |
38 | +.. option:: --json-server.max_threads ARG |
39 | + |
40 | + :Default: 32 |
41 | + :Variable: :ref:`json_server_max_threads <json_server_max_threads>` |
42 | + :Since: 0.3 |
43 | + |
44 | + Number of worker threads used by json server to handle http requests. Note |
45 | + that despite the name, current implementation is to immediately spawn as many |
46 | + threads as defined here. |
47 | + |
48 | .. _json_server_variables: |
49 | |
50 | Variables |
51 | @@ -81,6 +95,7 @@ |
52 | |
53 | :Scope: Global |
54 | :Dynamic: No |
55 | + :Since: 0.1 |
56 | |
57 | Port number to use for connection or 0 for default (port 8086) |
58 | |
59 | @@ -90,6 +105,7 @@ |
60 | |
61 | :Scope: Global |
62 | :Dynamic: yes |
63 | + :Since: 0.3 |
64 | |
65 | Schema which is used when not explicitly specified in request URI. |
66 | Note: Currently this is in the /json API only. |
67 | @@ -100,6 +116,7 @@ |
68 | |
69 | :Scope: Global |
70 | :Dynamic: yes |
71 | + :Since: 0.3 |
72 | |
73 | Table which is used when not explicitly specified in request URI. |
74 | Note: Currently this is in the /json API only. |
75 | @@ -110,11 +127,28 @@ |
76 | |
77 | :Scope: Global |
78 | :Dynamic: yes |
79 | + :Since: 0.3 |
80 | |
81 | When json-server.allow_drop_table is set to ON, it is possible to drop |
82 | a table with a HTTP DELETE request with no _id specified. When set to OFF |
83 | (the default), omitting _id will result in an error. |
84 | |
85 | +.. _json_server_max_threads: |
86 | + |
87 | +* ``json_server_max_threads`` |
88 | + |
89 | + :Scope: Global |
90 | + :Dynamic: yes |
91 | + :Since: 0.3 |
92 | + |
93 | + Number of threads used by json server to handle request. Note that despite |
94 | + the name, current implementation is to immediately spawn as many threads as |
95 | + defined here. Currently this variable can be increased dynamically, but an |
96 | + attempt to set a value that is lower than the current value will be silently |
97 | + ignored. (You have to restart drizzled to set a lower value as a startup |
98 | + option.) |
99 | + |
100 | + |
101 | .. _json_server_apis: |
102 | |
103 | APIs |
104 | @@ -133,24 +167,36 @@ |
105 | |
106 | .. code-block:: none |
107 | |
108 | - /0.1/sql |
109 | - /0.2/sql |
110 | + /0.3/sql |
111 | + /latest/sql |
112 | /sql |
113 | |
114 | -Because the SQL API did not change between 0.1 and 0.2, all of the above URIs |
115 | -are exactly the same. |
116 | +The ``/sql`` URI used to handle SQL-over-HTTP requests (examples below). |
117 | + |
118 | +Note that /0.1/sql and /0.2/sql have been removed since crashing bugs were |
119 | +found in them. Therefore, only the latest versions of this functionality |
120 | +are available. |
121 | |
122 | .. code-block:: none |
123 | |
124 | - /0.2/json |
125 | + /0.3/json |
126 | + /latest/json |
127 | /json |
128 | |
129 | -The pure JSON API did not exist in the 0.1 release, as you can see from above. |
130 | +The ``/json`` URI used to handle pure json requests (examples below). |
131 | + |
132 | +Note that /0.2/json has been removed since crashing bugs was |
133 | +found in the first version. Therefore, only the latest versions of this |
134 | +functionality are available. |
135 | |
136 | .. code-block:: none |
137 | |
138 | + /0.1/version |
139 | + /0.2/version |
140 | + /0.3/version |
141 | + /lastest/version |
142 | /version |
143 | - / |
144 | + |
145 | |
146 | The ``/version`` URI will return the version of Drizzle (in a JSON document, of |
147 | course): |
148 | @@ -163,6 +209,12 @@ |
149 | "version" : "7.1.31.2451-snapshot" |
150 | } |
151 | |
152 | +The key ``json_server_version`` was introduced in plugin version 0.3. |
153 | + |
154 | +.. code-block:: none |
155 | + |
156 | + / |
157 | + |
158 | The root URI / returns a simple HTML GUI that can be used to test both the SQL |
159 | and pure JSON APIs. Just point your browser to http://localhost:8086/ and try |
160 | it! |
161 | @@ -307,7 +359,7 @@ |
162 | POST /json?schema=test&table=people HTTP/1.1 |
163 | |
164 | { |
165 | - query: |
166 | + "query": |
167 | { |
168 | "_id" : 2, |
169 | "document" : { "firstname" : "Henrik", "lastname" : "Ingo", "age" : 35} |
170 | @@ -519,5 +571,5 @@ |
171 | * Changed structure of the query document to be |
172 | ``{ "query" : <old query document> }`` This is to allow for future |
173 | extensibility. |
174 | -* New options json_server.schema, json_server.table and |
175 | - json_server.allow_drop_table |
176 | \ No newline at end of file |
177 | +* Support for multi-threading. |
178 | +* New options json_server.schema, json_server.table ,json_server.allow_drop_table and json_server.max_threads . |
179 | |
180 | === added file 'plugin/json_server/http_server.cc' |
181 | --- plugin/json_server/http_server.cc 1970-01-01 00:00:00 +0000 |
182 | +++ plugin/json_server/http_server.cc 2012-07-17 12:13:20 +0000 |
183 | @@ -0,0 +1,60 @@ |
184 | +/* - mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*- |
185 | + * vim:expandtab:shiftwidth=2:tabstop=2:smarttab: |
186 | + * |
187 | + * Copyright (C) 2012 Mohit Srivastava |
188 | + * |
189 | + * This program is free software; you can redistribute it and/or modify |
190 | + * it under the terms of the GNU General Public License as published by |
191 | + * the Free Software Foundation; either version 2 of the License, or |
192 | + * (at your option) any later version. |
193 | + * |
194 | + * This program is distributed in the hope that it will be useful, |
195 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
196 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
197 | + * GNU General Public License for more details. |
198 | + * |
199 | + * You should have received a copy of the GNU General Public License |
200 | + * along with this program; if not, write to the Free Software |
201 | + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
202 | + */ |
203 | +/** |
204 | + * @file Implements a class HTTPServer handles socket related functions. Based on example code https://gist.github.com/665437 . |
205 | + */ |
206 | + |
207 | +#include <plugin/json_server/http_server.h> |
208 | + |
209 | +namespace drizzle_plugin{ |
210 | + namespace json_server{ |
211 | + |
212 | +int HTTPServer::BindSocket(const char* address,int port) |
213 | +{ |
214 | + int r; |
215 | + int nfd; |
216 | + nfd = socket(AF_INET, SOCK_STREAM, 0); |
217 | + if (nfd < 0) return -1; |
218 | + |
219 | + int one = 1; |
220 | + r = setsockopt(nfd, SOL_SOCKET, SO_REUSEADDR, (char *)&one, sizeof(int)); |
221 | + |
222 | + struct sockaddr_in addr; |
223 | + memset(&addr, 0, sizeof(addr)); |
224 | + addr.sin_family = AF_INET; |
225 | + addr.sin_addr.s_addr = inet_addr(address); |
226 | + addr.sin_port = htons(port); |
227 | + |
228 | + r = bind(nfd, (struct sockaddr*)&addr, sizeof(addr)); |
229 | + if (r < 0) return -1; |
230 | + r = listen(nfd, 10240); |
231 | + if (r < 0) return -1; |
232 | + |
233 | + int flags; |
234 | + if ((flags = fcntl(nfd, F_GETFL, 0)) < 0 |
235 | + || fcntl(nfd, F_SETFL, flags | O_NONBLOCK) < 0) |
236 | + return -1; |
237 | + |
238 | + return nfd; |
239 | + |
240 | +} |
241 | +} |
242 | +} |
243 | + |
244 | |
245 | === added file 'plugin/json_server/http_server.h' |
246 | --- plugin/json_server/http_server.h 1970-01-01 00:00:00 +0000 |
247 | +++ plugin/json_server/http_server.h 2012-07-17 12:13:20 +0000 |
248 | @@ -0,0 +1,67 @@ |
249 | +/* - mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*- |
250 | + * vim:expandtab:shiftwidth=2:tabstop=2:smarttab: |
251 | + * |
252 | + * Copyright (C) 2012 Mohit Srivastava |
253 | + * |
254 | + * This program is free software; you can redistribute it and/or modify |
255 | + * it under the terms of the GNU General Public License as published by |
256 | + * the Free Software Foundation; either version 2 of the License, or |
257 | + * (at your option) any later version. |
258 | + * |
259 | + * This program is distributed in the hope that it will be useful, |
260 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
261 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
262 | + * GNU General Public License for more details. |
263 | + * |
264 | + * You should have received a copy of the GNU General Public License |
265 | + * along with this program; if not, write to the Free Software |
266 | + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
267 | + */ |
268 | +/** |
269 | + * @file Implements a class HTTPServer handles socket related functions. Based on example code https://gist.github.com/665437 . |
270 | + */ |
271 | +#include <event.h> |
272 | +#include <evhttp.h> |
273 | +#include <errno.h> |
274 | +#include <string.h> |
275 | +#include <fcntl.h> |
276 | +#include <sys/socket.h> |
277 | +#include <sys/types.h> |
278 | +#include <netinet/in.h> |
279 | +#include <arpa/inet.h> |
280 | +#include <iostream> |
281 | +using namespace std; |
282 | +/** |
283 | + * Drizzle Plugin Namespace |
284 | + */ |
285 | +namespace drizzle_plugin { |
286 | +/** |
287 | + * Json Server Plugin Namespace |
288 | + */ |
289 | +namespace json_server{ |
290 | + |
291 | +class HTTPServer |
292 | +{ |
293 | + public: |
294 | + /** |
295 | + * Constructor |
296 | + */ |
297 | + HTTPServer() {} |
298 | + /** |
299 | + * Destructor |
300 | + */ |
301 | + ~HTTPServer() {} |
302 | + protected: |
303 | + /** |
304 | + * Bind socket to a address and port. |
305 | + * |
306 | + * @param address a constant character pointer. |
307 | + * @param port a integer. |
308 | + * |
309 | + * @return a non-negative file descriptor on success or -1 on failure. |
310 | + */ |
311 | + int BindSocket(const char *address, int port); |
312 | +}; |
313 | + |
314 | +} |
315 | +} |
316 | |
317 | === modified file 'plugin/json_server/json_server.cc' |
318 | --- plugin/json_server/json_server.cc 2012-06-28 06:46:59 +0000 |
319 | +++ plugin/json_server/json_server.cc 2012-07-17 12:13:20 +0000 |
320 | @@ -59,6 +59,7 @@ |
321 | #include <plugin/json_server/json/json.h> |
322 | #include <plugin/json_server/db_access.h> |
323 | #include <plugin/json_server/http_handler.h> |
324 | +#include <plugin/json_server/http_server.h> |
325 | |
326 | namespace po= boost::program_options; |
327 | using namespace drizzled; |
328 | @@ -71,12 +72,16 @@ |
329 | static const string DEFAULT_SCHEMA = "test"; |
330 | static const string DEFAULT_TABLE = ""; |
331 | static const string JSON_SERVER_VERSION = "0.3"; |
332 | -static const bool ALLOW_DROP_TABLE=false; |
333 | +static const uint32_t DEFAULT_MAX_THREADS= 32; |
334 | +static const bool DEFAULT_ALLOW_DROP_TABLE=false; |
335 | bool allow_drop_table; |
336 | string default_schema; |
337 | string default_table; |
338 | +uint32_t max_threads; |
339 | +uint32_t clone_max_threads=0; |
340 | bool updateSchema(Session *, set_var* var); |
341 | bool updateTable(Session *, set_var* var); |
342 | +void updateMaxThreads(Session *, sql_var_t); |
343 | static port_constraint port; |
344 | |
345 | static in_port_t getPort(void) |
346 | @@ -87,8 +92,9 @@ |
347 | extern "C" void process_request(struct evhttp_request *req, void* ); |
348 | extern "C" void process_root_request(struct evhttp_request *req, void* ); |
349 | extern "C" void process_api01_version_req(struct evhttp_request *req, void* ); |
350 | -extern "C" void process_api01_sql_req(struct evhttp_request *req, void* ); |
351 | -extern "C" void process_api02_json_req(struct evhttp_request *req, void* ); |
352 | +extern "C" void process_version_req(struct evhttp_request *req, void* ); |
353 | +extern "C" void process_sql_req(struct evhttp_request *req, void* ); |
354 | +extern "C" void process_json_req(struct evhttp_request *req, void* ); |
355 | extern "C" void process_request(struct evhttp_request *req, void* ) |
356 | { |
357 | struct evbuffer *buf = evbuffer_new(); |
358 | @@ -221,6 +227,21 @@ |
359 | |
360 | Json::Value root; |
361 | root["version"]= ::drizzled::version(); |
362 | + |
363 | + Json::StyledWriter writer; |
364 | + std::string output= writer.write(root); |
365 | + |
366 | + evbuffer_add(buf, output.c_str(), output.length()); |
367 | + evhttp_send_reply(req, HTTP_OK, "OK", buf); |
368 | +} |
369 | + |
370 | +extern "C" void process_version_req(struct evhttp_request *req, void* ) |
371 | +{ |
372 | + struct evbuffer *buf = evbuffer_new(); |
373 | + if (buf == NULL) return; |
374 | + |
375 | + Json::Value root; |
376 | + root["version"]= ::drizzled::version(); |
377 | root["json_server_version"]=JSON_SERVER_VERSION; |
378 | |
379 | Json::StyledWriter writer; |
380 | @@ -230,7 +251,7 @@ |
381 | evhttp_send_reply(req, HTTP_OK, "OK", buf); |
382 | } |
383 | |
384 | -extern "C" void process_api01_sql_req(struct evhttp_request *req, void* ) |
385 | +extern "C" void process_sql_req(struct evhttp_request *req, void* ) |
386 | { |
387 | struct evbuffer *buf = evbuffer_new(); |
388 | if (buf == NULL) return; |
389 | @@ -296,12 +317,11 @@ |
390 | /** |
391 | * Transform a HTTP request for sql transaction and return results based on input json document. |
392 | * |
393 | - * @todo allow DBA to set default schema (also in post,del methods) |
394 | * @todo allow DBA to set whether to use strict mode for parsing json (should get rid of white space), especially for POST of course. |
395 | * |
396 | * @param req should contain a "table" parameter in request uri. "query", "_id" and "schema" are optional. |
397 | */ |
398 | -extern "C" void process_api02_json_req(struct evhttp_request *req, void* ) |
399 | +extern "C" void process_json_req(struct evhttp_request *req, void* ) |
400 | { |
401 | Json::Value json_out; |
402 | Json::Value json_in; |
403 | @@ -344,7 +364,6 @@ |
404 | close(fd); |
405 | } |
406 | |
407 | - |
408 | static void run(struct event_base *base) |
409 | { |
410 | internal::my_thread_init(); |
411 | @@ -353,15 +372,16 @@ |
412 | } |
413 | |
414 | |
415 | -class JsonServer : public drizzled::plugin::Daemon |
416 | +class JsonServer : public drizzled::plugin::Daemon , public HTTPServer |
417 | { |
418 | private: |
419 | - drizzled::thread_ptr json_thread; |
420 | + std::vector<drizzled::thread_ptr> json_threads; |
421 | in_port_t _port; |
422 | struct evhttp *httpd; |
423 | struct event_base *base; |
424 | int wakeup_fd[2]; |
425 | struct event wakeup_event; |
426 | + int nfd; |
427 | |
428 | public: |
429 | JsonServer(in_port_t port_arg) : |
430 | @@ -392,59 +412,76 @@ |
431 | sql_perror("F_SETFL"); |
432 | return false; |
433 | } |
434 | - |
435 | - if ((base= event_init()) == NULL) |
436 | - { |
437 | - sql_perror("event_init()"); |
438 | - return false; |
439 | - } |
440 | - |
441 | - if ((httpd= evhttp_new(base)) == NULL) |
442 | - { |
443 | - sql_perror("evhttp_new()"); |
444 | - return false; |
445 | - } |
446 | - |
447 | - |
448 | - if ((evhttp_bind_socket(httpd, "0.0.0.0", getPort())) == -1) |
449 | + if ((nfd=BindSocket("0.0.0.0", getPort())) == -1) |
450 | { |
451 | sql_perror("evhttp_bind_socket()"); |
452 | return false; |
453 | } |
454 | - |
455 | - // These URLs are available. Bind worker method to each of them. |
456 | - // Please group by api version. Also unchanged functions must be copied to next version! |
457 | - evhttp_set_cb(httpd, "/", process_root_request, NULL); |
458 | - // API 0.1 |
459 | - evhttp_set_cb(httpd, "/0.1/version", process_api01_version_req, NULL); |
460 | - evhttp_set_cb(httpd, "/0.1/sql", process_api01_sql_req, NULL); |
461 | - // API 0.2 |
462 | - evhttp_set_cb(httpd, "/0.2/version", process_api01_version_req, NULL); |
463 | - evhttp_set_cb(httpd, "/0.2/sql", process_api01_sql_req, NULL); |
464 | - evhttp_set_cb(httpd, "/0.2/json", process_api02_json_req, NULL); |
465 | - // API "latest" and also available in top level |
466 | - evhttp_set_cb(httpd, "/latest/version", process_api01_version_req, NULL); |
467 | - evhttp_set_cb(httpd, "/latest/sql", process_api01_sql_req, NULL); |
468 | - evhttp_set_cb(httpd, "/latest/json", process_api02_json_req, NULL); |
469 | - evhttp_set_cb(httpd, "/version", process_api01_version_req, NULL); |
470 | - evhttp_set_cb(httpd, "/sql", process_api01_sql_req, NULL); |
471 | - evhttp_set_cb(httpd, "/json", process_api02_json_req, NULL); |
472 | - // Catch all does nothing and returns generic message. |
473 | - //evhttp_set_gencb(httpd, process_request, NULL); |
474 | - |
475 | - event_set(&wakeup_event, wakeup_fd[0], EV_READ | EV_PERSIST, shutdown_event, base); |
476 | - event_base_set(base, &wakeup_event); |
477 | - if (event_add(&wakeup_event, NULL) < 0) |
478 | - { |
479 | - sql_perror("event_add"); |
480 | - return false; |
481 | - } |
482 | - |
483 | - json_thread.reset(new boost::thread((boost::bind(&run, base)))); |
484 | - |
485 | - if (not json_thread) |
486 | - return false; |
487 | - |
488 | + |
489 | + // Create Max_thread number of threads. |
490 | + if(not createThreads(max_threads)) |
491 | + { |
492 | + return false; |
493 | + } |
494 | + |
495 | + return true; |
496 | + } |
497 | + |
498 | + bool createThreads(uint32_t num_threads) |
499 | + { |
500 | + for(uint32_t i =0;i<num_threads;i++) |
501 | + { |
502 | + if ((base= event_init()) == NULL) |
503 | + { |
504 | + sql_perror("event_init()"); |
505 | + return false; |
506 | + } |
507 | + |
508 | + if ((httpd= evhttp_new(base)) == NULL) |
509 | + { |
510 | + sql_perror("evhttp_new()"); |
511 | + return false; |
512 | + } |
513 | + |
514 | + if(evhttp_accept_socket(httpd,nfd)) |
515 | + { |
516 | + sql_perror("evhttp_accept_socket()"); |
517 | + return false; |
518 | + } |
519 | + |
520 | + // These URLs are available. Bind worker method to each of them. |
521 | + evhttp_set_cb(httpd, "/", process_root_request, NULL); |
522 | + // API 0.1 |
523 | + evhttp_set_cb(httpd, "/0.1/version", process_api01_version_req, NULL); |
524 | + // API 0.2 |
525 | + evhttp_set_cb(httpd, "/0.2/version", process_api01_version_req, NULL); |
526 | + // API 0.3 |
527 | + evhttp_set_cb(httpd, "/0.3/version", process_version_req, NULL); |
528 | + evhttp_set_cb(httpd, "/0.3/sql", process_sql_req, NULL); |
529 | + evhttp_set_cb(httpd, "/0.3/json", process_json_req, NULL); |
530 | + // API "latest" and also available in top level |
531 | + evhttp_set_cb(httpd, "/latest/version", process_version_req, NULL); |
532 | + evhttp_set_cb(httpd, "/latest/sql", process_sql_req, NULL); |
533 | + evhttp_set_cb(httpd, "/latest/json", process_json_req, NULL); |
534 | + evhttp_set_cb(httpd, "/version", process_version_req, NULL); |
535 | + evhttp_set_cb(httpd, "/sql", process_sql_req, NULL); |
536 | + evhttp_set_cb(httpd, "/json", process_json_req, NULL); |
537 | + |
538 | + |
539 | + event_set(&wakeup_event, wakeup_fd[0], EV_READ | EV_PERSIST, shutdown_event, base); |
540 | + event_base_set(base, &wakeup_event); |
541 | + if (event_add(&wakeup_event, NULL) < 0) |
542 | + { |
543 | + sql_perror("event_add"); |
544 | + return false; |
545 | + } |
546 | + drizzled::thread_ptr local_thread; |
547 | + local_thread.reset(new boost::thread((boost::bind(&run, base)))); |
548 | + json_threads.push_back(local_thread); |
549 | + |
550 | + if (not json_threads[i]) |
551 | + return false; |
552 | + } |
553 | return true; |
554 | } |
555 | |
556 | @@ -455,7 +492,10 @@ |
557 | buffer[0]= 4; |
558 | if ((write(wakeup_fd[1], &buffer, 1)) == 1) |
559 | { |
560 | - json_thread->join(); |
561 | + for(uint32_t i=0;i<max_threads;i++) |
562 | + { |
563 | + json_threads[i]->join(); |
564 | + } |
565 | evhttp_free(httpd); |
566 | event_base_free(base); |
567 | } |
568 | @@ -463,6 +503,31 @@ |
569 | }; |
570 | JsonServer *server=NULL; |
571 | |
572 | +void updateMaxThreads(Session *, sql_var_t) |
573 | +{ |
574 | + if (clone_max_threads < max_threads) |
575 | + { |
576 | + if(server->createThreads(max_threads - clone_max_threads)) |
577 | + { |
578 | + clone_max_threads=max_threads;//success |
579 | + } |
580 | + else |
581 | + { |
582 | + //char buf[100]; |
583 | + //sprintf(buf,"json_server unable to create more threads"); |
584 | + //my_error(ER_SCRIPT,MYF(0),buf); |
585 | + errmsg_printf(error::ERROR,_("json_server unable to create more threads")); |
586 | + } |
587 | + } |
588 | + else |
589 | + { |
590 | + max_threads = clone_max_threads; |
591 | + //my_error(ER_SCRIPT,MYF(0),"json_server_max_threads cannot be smaller than previous configured value"); |
592 | + errmsg_printf(error::ERROR, _("json_server_max_threadscannot be smaller than previous configured value"));//error |
593 | + } |
594 | +} |
595 | + |
596 | + |
597 | bool updateSchema(Session *, set_var* var) |
598 | { |
599 | if (not var->value->str_value.empty()) |
600 | @@ -491,7 +556,9 @@ |
601 | context.registerVariable(new sys_var_std_string("schema", default_schema, NULL, &updateSchema)); |
602 | context.registerVariable(new sys_var_std_string("table", default_table, NULL, &updateTable)); |
603 | context.registerVariable(new sys_var_bool_ptr("allow_drop_table", &allow_drop_table)); |
604 | + context.registerVariable(new sys_var_uint32_t_ptr("max_threads",&max_threads,&updateMaxThreads)); |
605 | |
606 | + clone_max_threads=max_threads; |
607 | |
608 | |
609 | if (server and not server->init()) |
610 | @@ -514,8 +581,11 @@ |
611 | po::value<string>(&default_table)->default_value(DEFAULT_TABLE), |
612 | _("table in use by json server")); |
613 | context("allow_drop_table", |
614 | - po::value<bool>(&allow_drop_table)->default_value(ALLOW_DROP_TABLE), |
615 | + po::value<bool>(&allow_drop_table)->default_value(DEFAULT_ALLOW_DROP_TABLE), |
616 | _("allow to drop table")); |
617 | + context("max_threads", |
618 | + po::value<uint32_t>(&max_threads)->default_value(DEFAULT_MAX_THREADS), |
619 | + _("Maximum threads in use by json server")); |
620 | |
621 | } |
622 | |
623 | |
624 | === modified file 'plugin/json_server/plugin.ini' |
625 | --- plugin/json_server/plugin.ini 2012-06-15 11:31:23 +0000 |
626 | +++ plugin/json_server/plugin.ini 2012-07-17 12:13:20 +0000 |
627 | @@ -4,6 +4,7 @@ |
628 | sql_executor.h |
629 | sql_to_json_generator.h |
630 | http_handler.h |
631 | + http_server.h |
632 | db_access.h |
633 | json/autolink.h |
634 | json/config.h |
635 | @@ -23,6 +24,7 @@ |
636 | sql_generator.cc |
637 | sql_to_json_generator.cc |
638 | http_handler.cc |
639 | + http_server.cc |
640 | db_access.cc |
641 | json/json_reader.cpp |
642 | json/json_value.cpp |
643 | |
644 | === modified file 'plugin/json_server/tests/r/basic.result' |
645 | --- plugin/json_server/tests/r/basic.result 2012-06-28 06:46:59 +0000 |
646 | +++ plugin/json_server/tests/r/basic.result 2012-07-17 12:13:20 +0000 |
647 | @@ -1,14 +1,14 @@ |
648 | create table t1 (a int primary key auto_increment, b varchar(100)); |
649 | -select http_post("http://localhost:PORT/0.1/sql", 'select * from t1;');; |
650 | -http_post("http://localhost:PORT/0.1/sql", 'select * from t1;') |
651 | +select http_post("http://localhost:PORT/sql", 'select * from t1;');; |
652 | +http_post("http://localhost:PORT/sql", 'select * from t1;') |
653 | { |
654 | "query" : "select * from t1;", |
655 | "sqlstate" : "00000" |
656 | } |
657 | |
658 | insert into t1 (b) values ("from MySQL protocol"); |
659 | -select http_post('http://localhost:PORT/0.1/sql', 'select * from t1;');; |
660 | -http_post('http://localhost:PORT/0.1/sql', 'select * from t1;') |
661 | +select http_post('http://localhost:PORT/sql', 'select * from t1;');; |
662 | +http_post('http://localhost:PORT/sql', 'select * from t1;') |
663 | { |
664 | "query" : "select * from t1;", |
665 | "result_set" : [ |
666 | @@ -17,8 +17,8 @@ |
667 | "sqlstate" : "00000" |
668 | } |
669 | |
670 | -select http_post('http://localhost:PORT/0.1/sql', 'insert into t1 (b) values (\'from http\');');; |
671 | -http_post('http://localhost:PORT/0.1/sql', 'insert into t1 (b) values (\'from http\');') |
672 | +select http_post('http://localhost:PORT/sql', 'insert into t1 (b) values (\'from http\');');; |
673 | +http_post('http://localhost:PORT/sql', 'insert into t1 (b) values (\'from http\');') |
674 | { |
675 | "query" : "insert into t1 (b) values ('from http');", |
676 | "sqlstate" : "00000" |
677 | |
678 | === modified file 'plugin/json_server/tests/t/basic.test' |
679 | --- plugin/json_server/tests/t/basic.test 2012-06-28 06:46:59 +0000 |
680 | +++ plugin/json_server/tests/t/basic.test 2012-07-17 12:13:20 +0000 |
681 | @@ -1,11 +1,11 @@ |
682 | create table t1 (a int primary key auto_increment, b varchar(100)); |
683 | --replace_result $JSON_SERVER_PORT PORT |
684 | ---eval select http_post("http://localhost:$JSON_SERVER_PORT/0.1/sql", 'select * from t1;'); |
685 | +--eval select http_post("http://localhost:$JSON_SERVER_PORT/sql", 'select * from t1;'); |
686 | insert into t1 (b) values ("from MySQL protocol"); |
687 | --replace_result $JSON_SERVER_PORT PORT |
688 | ---eval select http_post('http://localhost:$JSON_SERVER_PORT/0.1/sql', 'select * from t1;'); |
689 | +--eval select http_post('http://localhost:$JSON_SERVER_PORT/sql', 'select * from t1;'); |
690 | --replace_result $JSON_SERVER_PORT PORT |
691 | ---eval select http_post('http://localhost:$JSON_SERVER_PORT/0.1/sql', 'insert into t1 (b) values (\'from http\');'); |
692 | +--eval select http_post('http://localhost:$JSON_SERVER_PORT/sql', 'insert into t1 (b) values (\'from http\');'); |
693 | SELECT * from t1; |
694 | drop table t1; |
695 |