droonga-client 0.2.1 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile +9 -1
- data/bin/droonga-add +7 -4
- data/bin/droonga-groonga +35 -36
- data/bin/droonga-request +27 -38
- data/bin/droonga-send +22 -18
- data/bin/droonga-system-status +13 -9
- data/doc/text/news.md +10 -1
- data/droonga-client.gemspec +1 -0
- data/lib/droonga/client.rb +27 -2
- data/lib/droonga/client/connection/droonga-protocol/coolio.rb +1 -1
- data/lib/droonga/client/connection/http.rb +22 -7
- data/lib/droonga/client/message_completer.rb +5 -1
- data/lib/droonga/client/version.rb +2 -2
- data/lib/droonga/command/base.rb +18 -5
- metadata +38 -24
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0bddfcb4cdb8dd14e9290a5e63ef0bbbff7a2302
|
4
|
+
data.tar.gz: 973fd9fcc5799bada35619aca7551a1c668f33b4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3998d23334009b7c7b6e35bc67d271493edbc691cf3467f714c8e139b78827b592456eb574c4e16286d3c2d7c1b910eac78b42d7c9f8989b1abf4b341f1e2f45
|
7
|
+
data.tar.gz: 5bc8cf2f9df903588bf3816036e2f200a38e02c102ce26abd894b1408976639bfa2c99fc0e5e6c7fd02a8363ab612c15e0f2d8297f8b81a463a732e31aefc12f
|
data/Gemfile
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# -*- mode: ruby; coding: utf-8 -*-
|
2
2
|
#
|
3
|
-
# Copyright (C) 2013 Droonga Project
|
3
|
+
# Copyright (C) 2013-2015 Droonga Project
|
4
4
|
#
|
5
5
|
# This library is free software; you can redistribute it and/or
|
6
6
|
# modify it under the terms of the GNU Lesser General Public
|
@@ -19,3 +19,11 @@ source 'https://rubygems.org'
|
|
19
19
|
|
20
20
|
# Specify your gem's dependencies in droonga-client.gemspec
|
21
21
|
gemspec
|
22
|
+
|
23
|
+
parent_dir = File.join(File.dirname(__FILE__), "..")
|
24
|
+
grn2drn_dir = File.join(parent_dir, "grn2drn")
|
25
|
+
if File.exist?(grn2drn_dir)
|
26
|
+
gem "grn2drn", :path => grn2drn_dir
|
27
|
+
else
|
28
|
+
gem "grn2drn", :github => "droonga/grn2drn"
|
29
|
+
end
|
data/bin/droonga-add
CHANGED
@@ -27,7 +27,8 @@ module Droonga
|
|
27
27
|
option.banner("Usage: droonga-add [options]\n" +
|
28
28
|
" ex: droonga-add --table User --name Adam --age 10\n" +
|
29
29
|
" droonga-add --table Server --value:host example.com\n" +
|
30
|
-
" (You can specify column value expressly with the prefix \"value:\".)"
|
30
|
+
" (You can specify column value expressly with the prefix \"value:\".)\n" +
|
31
|
+
"")
|
31
32
|
|
32
33
|
option.on("table=",
|
33
34
|
"Name of the target table.",
|
@@ -51,10 +52,12 @@ module Droonga
|
|
51
52
|
puts "Adding new record..."
|
52
53
|
puts(JSON.pretty_generate(add_params))
|
53
54
|
|
54
|
-
|
55
|
-
|
55
|
+
result = request(add_message) do |response|
|
56
|
+
raise NoResponse.new unless response
|
57
|
+
response["body"]
|
58
|
+
end
|
56
59
|
|
57
|
-
if
|
60
|
+
if result
|
58
61
|
puts "Done."
|
59
62
|
true
|
60
63
|
else
|
data/bin/droonga-groonga
CHANGED
@@ -18,6 +18,7 @@
|
|
18
18
|
require "json"
|
19
19
|
|
20
20
|
require "droonga/command/base"
|
21
|
+
require "grn2drn/command-converter"
|
21
22
|
|
22
23
|
module Droonga
|
23
24
|
module Command
|
@@ -32,34 +33,31 @@ module Droonga
|
|
32
33
|
parse_options do |option|
|
33
34
|
option.banner("Usage: droonga-groonga [groonga-command-name] [options]\n" +
|
34
35
|
" ex: droonga-groonga select --table=Users")
|
35
|
-
|
36
36
|
option.separator("Formatting:")
|
37
37
|
option.on(:pretty,
|
38
38
|
"Output result as a pretty print JSON.",
|
39
39
|
:default => false)
|
40
40
|
end
|
41
41
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
body = response["body"]
|
54
|
-
|
55
|
-
if @options[:pretty]
|
56
|
-
puts(JSON.pretty_generate(body))
|
42
|
+
unless ARGV.empty?
|
43
|
+
groonga_command_args = ARGV.collect do |arg|
|
44
|
+
if /\s/ =~ arg
|
45
|
+
JSON.generate(arg)
|
46
|
+
else
|
47
|
+
arg
|
48
|
+
end
|
49
|
+
end
|
50
|
+
command_converter.convert(groonga_command_args.join(" ")) do |command|
|
51
|
+
process_groonga_message(command)
|
52
|
+
end
|
57
53
|
else
|
58
|
-
|
54
|
+
command_converter.convert(ARGF) do |command|
|
55
|
+
process_groonga_message(command)
|
56
|
+
end
|
59
57
|
end
|
60
58
|
|
61
59
|
true
|
62
|
-
rescue MissingRequiredParameter
|
60
|
+
rescue MissingRequiredParameter
|
63
61
|
puts(@options)
|
64
62
|
false
|
65
63
|
rescue NoResponse
|
@@ -68,28 +66,29 @@ module Droonga
|
|
68
66
|
end
|
69
67
|
|
70
68
|
private
|
71
|
-
def
|
72
|
-
|
73
|
-
|
74
|
-
|
69
|
+
def process_groonga_message(groonga_message)
|
70
|
+
request(groonga_message) do |response|
|
71
|
+
raise NoResponse.new unless response
|
72
|
+
body = response["body"]
|
75
73
|
|
76
|
-
|
77
|
-
|
78
|
-
option_name = nil
|
79
|
-
argv.each do |arg|
|
80
|
-
case arg
|
81
|
-
when /\A--([^\s=]+)=(.+)\z/
|
82
|
-
params[$1] = $2
|
83
|
-
when /\A--([^\s=]+)\z/
|
84
|
-
option_name = $1
|
74
|
+
if @options[:pretty]
|
75
|
+
puts(JSON.pretty_generate(body))
|
85
76
|
else
|
86
|
-
|
87
|
-
params[option_name] = arg
|
88
|
-
option_name = nil
|
89
|
-
end
|
77
|
+
puts(JSON.generate(body))
|
90
78
|
end
|
91
79
|
end
|
92
|
-
|
80
|
+
end
|
81
|
+
|
82
|
+
def command_converter
|
83
|
+
@command_converter ||= create_command_converter
|
84
|
+
end
|
85
|
+
|
86
|
+
def create_command_converter
|
87
|
+
convert_options = {
|
88
|
+
:id_prefix => "droonga-groonga:#{Time.now.to_i.to_s}",
|
89
|
+
:dataset => @options[:dataset],
|
90
|
+
}
|
91
|
+
::Grn2Drn::CommandConverter.new(convert_options)
|
93
92
|
end
|
94
93
|
end
|
95
94
|
end
|
data/bin/droonga-request
CHANGED
@@ -26,10 +26,9 @@ options = {
|
|
26
26
|
:port => Droonga::Client::DEFAULT_PORT,
|
27
27
|
:tag => Droonga::Client::DEFAULT_TAG,
|
28
28
|
:default_dataset => Droonga::Client::DEFAULT_DATASET,
|
29
|
-
:protocol =>
|
29
|
+
:protocol => Droonga::Client::DEFAULT_PROTOCOL,
|
30
30
|
:default_target_role => Droonga::Client::DEFAULT_TARGET_ROLE,
|
31
31
|
:timeout => 1,
|
32
|
-
:exit_on_response => true,
|
33
32
|
:receiver_host => Droonga::Client::DEFAULT_HOST,
|
34
33
|
:receiver_port => 0,
|
35
34
|
:report_request => false,
|
@@ -44,60 +43,50 @@ parser.banner += " REQUEST_JSON_FILE"
|
|
44
43
|
parser.separator("")
|
45
44
|
parser.separator("Connect:")
|
46
45
|
parser.on("--host=HOST",
|
47
|
-
"Host name to
|
46
|
+
"Host name of the endpoint to communicate with the Droonga cluster.",
|
48
47
|
"(#{options[:host]})") do |host|
|
49
48
|
options[:host] = host
|
50
49
|
end
|
51
50
|
parser.on("--port=PORT", Integer,
|
52
|
-
"Port number to
|
51
|
+
"Port number to communicate with the endpoint of the Droonga cluster.",
|
53
52
|
"(#{options[:port]})") do |port|
|
54
53
|
options[:port] = port
|
55
54
|
end
|
56
55
|
parser.on("--tag=TAG",
|
57
|
-
"Tag name to
|
56
|
+
"Tag name to communicate with the endpoint of the Droonga cluster.",
|
58
57
|
"(#{options[:tag]})") do |tag|
|
59
58
|
options[:tag] = tag
|
60
59
|
end
|
61
60
|
available_protocols = [:droonga, :http]
|
62
61
|
parser.on("--protocol=PROTOCOL", available_protocols,
|
63
|
-
"Protocol to
|
62
|
+
"Protocol to communicate with the endpoint of the Droonga cluster.",
|
64
63
|
"[#{available_protocols.join('|')}]",
|
65
64
|
"(#{options[:protocol]})") do |protocol|
|
66
|
-
options[:protocol] = protocol
|
65
|
+
options[:protocol] = protocol.downcase.to_sym
|
67
66
|
end
|
68
67
|
parser.separator("")
|
69
68
|
parser.separator("Timeout:")
|
70
69
|
parser.on("--timeout=TIMEOUT", Integer,
|
71
|
-
"
|
70
|
+
"Time to terminate unresponsive connections, in seconds.",
|
72
71
|
"(#{options[:timeout]})") do |timeout|
|
73
72
|
options[:timeout] = timeout
|
74
73
|
end
|
75
|
-
parser.on("--[no-]exit-on-response",
|
76
|
-
"Exit when a response is received.",
|
77
|
-
"(#{options[:exit_on_response]})") do |exit_on_response|
|
78
|
-
options[:exit_on_response] = exit_on_response
|
79
|
-
end
|
80
74
|
parser.separator("")
|
81
75
|
parser.separator("Droonga protocol:")
|
82
76
|
parser.on("--receiver-host=HOST",
|
83
|
-
"Host name
|
77
|
+
"Host name of the computer you are running this command.",
|
84
78
|
"(#{options[:receiver_host]})") do |host|
|
85
79
|
options[:receiver_host] = host
|
86
80
|
end
|
87
|
-
parser.on("--receiver-port=PORT", Integer,
|
88
|
-
"Port number to be received a response from Droonga engine.",
|
89
|
-
"(#{options[:receiver_port]})") do |port|
|
90
|
-
options[:receiver_port] = port
|
91
|
-
end
|
92
81
|
parser.separator("")
|
93
82
|
parser.separator("Report:")
|
94
83
|
parser.on("--[no-]report-request",
|
95
|
-
"Reports request
|
84
|
+
"Reports request messages actually sent.",
|
96
85
|
"(#{options[:report_request]})") do |report_request|
|
97
86
|
options[:report_request] = report_request
|
98
87
|
end
|
99
88
|
parser.on("--[no-]report-elapsed-time",
|
100
|
-
"Reports elapsed time.",
|
89
|
+
"Reports elapsed time between a request and a response.",
|
101
90
|
"(#{options[:report_elapsed_time]})") do |report_elapsed_time|
|
102
91
|
options[:report_elapsed_time] = report_elapsed_time
|
103
92
|
end
|
@@ -109,17 +98,17 @@ parser.on("--detault-dataset=NAME",
|
|
109
98
|
options[:default_dataset] = name
|
110
99
|
end
|
111
100
|
parser.on("--detault-target-role=ROLE",
|
112
|
-
"Default
|
101
|
+
"Default role of engine nodes which should process messages.",
|
113
102
|
"(#{options[:default_target_role]})") do |role|
|
114
103
|
options[:default_target_role] = role
|
115
104
|
end
|
116
105
|
parser.on("--[no-]completion",
|
117
|
-
"Do completion of required fields for input
|
106
|
+
"Do completion of required fields for input messages or not.",
|
118
107
|
"(#{options[:completion]})") do |completion|
|
119
108
|
options[:completion] = completion
|
120
109
|
end
|
121
110
|
parser.on("--[no-]validation",
|
122
|
-
"Do validation for input
|
111
|
+
"Do validation for input messages or not.",
|
123
112
|
"(#{options[:validation]})") do |validation|
|
124
113
|
options[:validation] = validation
|
125
114
|
end
|
@@ -128,9 +117,9 @@ request_json_files = parser.parse!(ARGV)
|
|
128
117
|
client = Droonga::Client.new(options)
|
129
118
|
json_parser = Yajl::Parser.new
|
130
119
|
json_parser.on_parse_complete = lambda do |request_message|
|
131
|
-
request_message["dataset"] ||= options[:default_dataset]
|
132
120
|
if options[:report_request]
|
133
121
|
message = "Request: "
|
122
|
+
request_message = client.complete(request_message)
|
134
123
|
begin
|
135
124
|
message << JSON.pretty_generate(request_message)
|
136
125
|
rescue
|
@@ -140,21 +129,21 @@ json_parser.on_parse_complete = lambda do |request_message|
|
|
140
129
|
print(message)
|
141
130
|
end
|
142
131
|
start = Time.now
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
message << response.inspect
|
132
|
+
response = client.request(request_message)
|
133
|
+
message = ""
|
134
|
+
if options[:report_elapsed_time]
|
135
|
+
message << "Elapsed time: #{Time.now - start}\n"
|
136
|
+
end
|
137
|
+
begin
|
138
|
+
if options[:protocol] == :http
|
139
|
+
response = JSON.parse(response)
|
152
140
|
end
|
153
|
-
message <<
|
154
|
-
|
155
|
-
|
141
|
+
message << JSON.pretty_generate(response)
|
142
|
+
rescue
|
143
|
+
message << response.inspect
|
156
144
|
end
|
157
|
-
|
145
|
+
message << "\n"
|
146
|
+
print(message)
|
158
147
|
end
|
159
148
|
|
160
149
|
if request_json_files.empty?
|
data/bin/droonga-send
CHANGED
@@ -25,7 +25,7 @@ require "droonga/client"
|
|
25
25
|
options = OpenStruct.new
|
26
26
|
options.report_request = false
|
27
27
|
options.report_throughput = false
|
28
|
-
options.default_protocol =
|
28
|
+
options.default_protocol = Droonga::Client::DEFAULT_PROTOCOL
|
29
29
|
options.default_host = Droonga::Client::DEFAULT_HOST
|
30
30
|
options.default_port = Droonga::Client::DEFAULT_PORT
|
31
31
|
options.default_tag = Droonga::Client::DEFAULT_TAG
|
@@ -53,15 +53,16 @@ def parse_server(server, options)
|
|
53
53
|
protocol = nil
|
54
54
|
end
|
55
55
|
|
56
|
-
protocol ||= options.default_protocol
|
56
|
+
protocol ||= options.default_protocol.to_s
|
57
57
|
port ||= options.default_port
|
58
58
|
tag ||= options.default_tag
|
59
59
|
|
60
60
|
{
|
61
61
|
:host => host,
|
62
62
|
:port => Integer(port),
|
63
|
-
:protocol => protocol.to_sym,
|
63
|
+
:protocol => protocol.downcase.to_sym,
|
64
64
|
:tag => tag,
|
65
|
+
:default_dataset => options.default_dataset,
|
65
66
|
:default_target_role => options.default_target_role,
|
66
67
|
:completion => options.completion,
|
67
68
|
:validation => options.validation,
|
@@ -114,36 +115,36 @@ parser.on("--server=PROTOCOL:HOST:PORT/TAG",
|
|
114
115
|
servers << server
|
115
116
|
end
|
116
117
|
parser.on("--messages-per-second=N", Integer,
|
117
|
-
"
|
118
|
-
"'#{Droonga::Client::RateLimiter::NO_LIMIT}' means no limit.",
|
118
|
+
"Maximum number of messages to be sent in a second.",
|
119
|
+
"'#{Droonga::Client::RateLimiter::NO_LIMIT}' means \"no limit\".",
|
119
120
|
"(#{messages_per_second})") do |n|
|
120
121
|
messages_per_second = n
|
121
122
|
end
|
122
123
|
parser.on("--default-protocol=PROTOCOL",
|
123
|
-
"Default protocol
|
124
|
+
"Default protocol to communicate with endpoints of the Droonga cluster.",
|
124
125
|
"(#{options.default_protocol})") do |protocol|
|
125
|
-
options.default_protocol = protocol
|
126
|
+
options.default_protocol = protocol.downcase.to_sym
|
126
127
|
end
|
127
128
|
parser.on("--default-port=PORT", Integer,
|
128
|
-
"Default port
|
129
|
+
"Default port number to communicate with endpoints of the Droonga cluster.",
|
129
130
|
"(#{options.default_port})") do |port|
|
130
131
|
options.default_port = port
|
131
132
|
end
|
132
133
|
parser.on("--default-tag=TAG",
|
133
|
-
"Default tag
|
134
|
+
"Default tag name to communicate with the endpoints of the Droonga cluster.",
|
134
135
|
"(#{options.default_tag})") do |tag|
|
135
136
|
options.default_tag = tag
|
136
137
|
end
|
137
138
|
parser.separator("")
|
138
139
|
parser.separator("Report:")
|
139
140
|
parser.on("--[no-]report-request",
|
140
|
-
"Reports request
|
141
|
+
"Reports request messages.",
|
141
142
|
"(#{options.report_request})") do |report_request|
|
142
143
|
options.report_request = report_request
|
143
144
|
end
|
144
|
-
parser.on("--report-throughput",
|
145
|
+
parser.on("--[no-]report-throughput",
|
145
146
|
"Reports throughput by messages per second.",
|
146
|
-
"(
|
147
|
+
"(#{options.report_throughput})") do
|
147
148
|
options.report_throughput = true
|
148
149
|
end
|
149
150
|
parser.separator("")
|
@@ -154,23 +155,26 @@ parser.on("--default-dataset=NAME",
|
|
154
155
|
options.default_dataset = name
|
155
156
|
end
|
156
157
|
parser.on("--default-target-role=ROLE",
|
157
|
-
"Default
|
158
|
+
"Default role of engine nodes which should process messages.",
|
158
159
|
"(#{options.default_target_role})") do |role|
|
159
160
|
options.default_target_role = role
|
160
161
|
end
|
161
162
|
parser.on("--[no-]completion",
|
162
|
-
"Do completion of required fields for input
|
163
|
+
"Do completion of required fields for input messages or not.",
|
163
164
|
"(#{options.completion})") do |completion|
|
164
165
|
options.completion = completion
|
165
166
|
end
|
166
167
|
parser.on("--[no-]validation",
|
167
|
-
"Do validation for input
|
168
|
+
"Do validation for input messages or not.",
|
168
169
|
"(#{options.validation})") do |validation|
|
169
170
|
options.validation = validation
|
170
171
|
end
|
171
172
|
request_json_files = parser.parse!(ARGV)
|
172
173
|
|
173
|
-
|
174
|
+
if servers.empty?
|
175
|
+
default_server = "#{options.default_protocol}:#{options.default_host}:#{options.default_port}/#{options.default_tag}"
|
176
|
+
servers << default_server
|
177
|
+
end
|
174
178
|
if messages_per_second > 0 and servers.size > 1
|
175
179
|
messages_per_second = messages_per_second / servers.size
|
176
180
|
end
|
@@ -187,9 +191,10 @@ end
|
|
187
191
|
client_index = 0
|
188
192
|
json_parser = Yajl::Parser.new
|
189
193
|
json_parser.on_parse_complete = lambda do |request_message|
|
190
|
-
|
194
|
+
client = clients[client_index]
|
191
195
|
if options.report_request
|
192
196
|
message = "Request: "
|
197
|
+
request_message = client.complete(request_message)
|
193
198
|
begin
|
194
199
|
message << JSON.pretty_generate(request_message)
|
195
200
|
rescue
|
@@ -198,7 +203,6 @@ json_parser.on_parse_complete = lambda do |request_message|
|
|
198
203
|
message << "\n"
|
199
204
|
print(message)
|
200
205
|
end
|
201
|
-
client = clients[client_index]
|
202
206
|
client.send(request_message)
|
203
207
|
client_index = (client_index + 1) % clients.size
|
204
208
|
throughput_reporter.on_message_sent if throughput_reporter
|
data/bin/droonga-system-status
CHANGED
@@ -25,19 +25,23 @@ module Droonga
|
|
25
25
|
def run
|
26
26
|
parse_options do |option|
|
27
27
|
option.on(:pretty,
|
28
|
-
"Output result as a pretty
|
28
|
+
"Output result as a pretty printed JSON.",
|
29
29
|
:default => false)
|
30
30
|
end
|
31
31
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
32
|
+
system_status_message = {
|
33
|
+
"dataset" => @options[:dataset],
|
34
|
+
"type" => "system.status",
|
35
|
+
}
|
36
|
+
request(system_status_message) do |response|
|
37
|
+
raise NoResponse.new unless response
|
38
|
+
body = response["body"]
|
36
39
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
40
|
+
if @options[:pretty]
|
41
|
+
puts(JSON.pretty_generate(body))
|
42
|
+
else
|
43
|
+
puts(JSON.generate(body))
|
44
|
+
end
|
41
45
|
end
|
42
46
|
|
43
47
|
true
|
data/doc/text/news.md
CHANGED
@@ -1,6 +1,15 @@
|
|
1
1
|
# News
|
2
2
|
|
3
|
-
## 0.2.
|
3
|
+
## 0.2.2: 2015-05-29
|
4
|
+
|
5
|
+
* `droonga-request`
|
6
|
+
* Works correctly with HTTP protocol. (regression)
|
7
|
+
* The `--[no-]exit-on-response` option is removed because it is nonsense.
|
8
|
+
* Add `--dry-run` option for `droonga-add`, `droonga-system-status` and `droonga-groonga` commands.
|
9
|
+
You can try them without sending messages.
|
10
|
+
* `droonga-groonga` now supports conversion of multiple Groonga commands given via the standard input.
|
11
|
+
|
12
|
+
## 0.2.1: 2015-04-29
|
4
13
|
|
5
14
|
* Required fields of input messages are automatically completed by default.
|
6
15
|
* Input messages are automatically validated by default.
|
data/droonga-client.gemspec
CHANGED
@@ -37,6 +37,7 @@ Gem::Specification.new do |spec|
|
|
37
37
|
|
38
38
|
spec.add_runtime_dependency "droonga-message-pack-packer"
|
39
39
|
spec.add_runtime_dependency "fluent-logger"
|
40
|
+
spec.add_runtime_dependency "grn2drn", ">= 1.0.5"
|
40
41
|
spec.add_runtime_dependency "msgpack"
|
41
42
|
spec.add_runtime_dependency "rack"
|
42
43
|
spec.add_runtime_dependency "slop", "<= 3.6.0"
|
data/lib/droonga/client.rb
CHANGED
@@ -25,6 +25,7 @@ require "droonga/client/message_validator"
|
|
25
25
|
|
26
26
|
module Droonga
|
27
27
|
class Client
|
28
|
+
DEFAULT_PROTOCOL = :droonga
|
28
29
|
DEFAULT_HOST = Socket.gethostname
|
29
30
|
DEFAULT_HOST.force_encoding("US-ASCII") if DEFAULT_HOST.ascii_only?
|
30
31
|
DEFAULT_PORT = 10031
|
@@ -34,6 +35,7 @@ module Droonga
|
|
34
35
|
DEFAULT_TIMEOUT_SECONDS = 3
|
35
36
|
|
36
37
|
attr_writer :on_error
|
38
|
+
attr_reader :protocol
|
37
39
|
|
38
40
|
class ConnectionError < StandardError
|
39
41
|
def initialize(error)
|
@@ -83,6 +85,7 @@ module Droonga
|
|
83
85
|
# @option options [Boolean] :validation (true)
|
84
86
|
# Do or do not validate input messages.
|
85
87
|
def initialize(options={})
|
88
|
+
@protocol = options[:protocol] || DEFAULT_PROTOCOL
|
86
89
|
@connection = create_connection(options)
|
87
90
|
@connection.on_error = lambda do |error|
|
88
91
|
on_error(ConnectionError.new(error))
|
@@ -91,7 +94,8 @@ module Droonga
|
|
91
94
|
@completion = options[:completion] != false
|
92
95
|
@validation = options[:validation] != false
|
93
96
|
|
94
|
-
@completer = MessageCompleter.new(:
|
97
|
+
@completer = MessageCompleter.new(:default_dataset => options[:default_dataset],
|
98
|
+
:default_timeout => options[:default_timeout],
|
95
99
|
:default_target_role => options[:default_target_role])
|
96
100
|
@validator = MessageValidator.new
|
97
101
|
end
|
@@ -122,9 +126,30 @@ module Droonga
|
|
122
126
|
@connection.close
|
123
127
|
end
|
124
128
|
|
129
|
+
def complete(message)
|
130
|
+
case @protocol
|
131
|
+
when :http
|
132
|
+
http_request = @connection.build_request(message)
|
133
|
+
http_headers = {}
|
134
|
+
http_request.canonical_each do |name, value|
|
135
|
+
http_headers[name] = value
|
136
|
+
end
|
137
|
+
{
|
138
|
+
"method" => http_request.method,
|
139
|
+
"path" => http_request.path,
|
140
|
+
"headers" => http_headers,
|
141
|
+
"body" => http_request.body,
|
142
|
+
}
|
143
|
+
when :droonga
|
144
|
+
do_completion(message, :completion => true)
|
145
|
+
else
|
146
|
+
nil
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
125
150
|
private
|
126
151
|
def create_connection(options)
|
127
|
-
case
|
152
|
+
case @protocol
|
128
153
|
when :http
|
129
154
|
Connection::HTTP.new(options)
|
130
155
|
when :droonga
|
@@ -87,8 +87,14 @@ module Droonga
|
|
87
87
|
end
|
88
88
|
else
|
89
89
|
thread = Thread.new do
|
90
|
-
|
91
|
-
|
90
|
+
catch do |tag|
|
91
|
+
send(message, options) do |response|
|
92
|
+
begin
|
93
|
+
yield(response.body)
|
94
|
+
rescue LocalJumpError
|
95
|
+
throw(tag)
|
96
|
+
end
|
97
|
+
end
|
92
98
|
end
|
93
99
|
end
|
94
100
|
Request.new(thread)
|
@@ -142,7 +148,7 @@ module Droonga
|
|
142
148
|
request = build_request(message)
|
143
149
|
http.start do
|
144
150
|
http.request(request) do |response|
|
145
|
-
yield(response)
|
151
|
+
yield(response) if block_given?
|
146
152
|
end
|
147
153
|
end
|
148
154
|
end
|
@@ -153,15 +159,18 @@ module Droonga
|
|
153
159
|
def close
|
154
160
|
end
|
155
161
|
|
156
|
-
private
|
157
162
|
def build_request(message)
|
158
163
|
http_method = message["method"] || "GET"
|
159
164
|
http_headers = message["headers"] || {}
|
160
|
-
case http_method
|
165
|
+
case http_method.to_s.upcase
|
161
166
|
when "POST"
|
162
167
|
request = Net::HTTP::Post.new(build_path(message, {}),
|
163
168
|
http_headers)
|
164
|
-
|
169
|
+
body = message["body"]
|
170
|
+
if body.is_a?(Hash) or body.is_a?(Array)
|
171
|
+
body = JSON.generate(body)
|
172
|
+
end
|
173
|
+
request.body = body
|
165
174
|
request
|
166
175
|
when "GET"
|
167
176
|
parameters = message["body"] || {}
|
@@ -172,9 +181,10 @@ module Droonga
|
|
172
181
|
end
|
173
182
|
end
|
174
183
|
|
184
|
+
private
|
175
185
|
def build_path(message, parameters)
|
176
186
|
type = message["type"]
|
177
|
-
base_path = message["path"] ||
|
187
|
+
base_path = message["path"] || build_droonga_path(type)
|
178
188
|
if parameters.empty?
|
179
189
|
base_path
|
180
190
|
else
|
@@ -182,6 +192,11 @@ module Droonga
|
|
182
192
|
end
|
183
193
|
end
|
184
194
|
|
195
|
+
def build_droonga_path(type)
|
196
|
+
type = type.gsub(".", "/")
|
197
|
+
"/droonga/#{type}"
|
198
|
+
end
|
199
|
+
|
185
200
|
def on_error(error)
|
186
201
|
@on_error.call(error) if @on_error
|
187
202
|
end
|
@@ -23,6 +23,7 @@ module Droonga
|
|
23
23
|
def initialize(options={})
|
24
24
|
@options = options
|
25
25
|
@fixed_date = @options[:fixed_date]
|
26
|
+
@default_dataset = @options[:default_dataset]
|
26
27
|
@default_timeout = @options[:default_timeout]
|
27
28
|
@default_target_role = @options[:default_target_role]
|
28
29
|
end
|
@@ -30,13 +31,16 @@ module Droonga
|
|
30
31
|
def complete(message)
|
31
32
|
id = message["id"] || generate_id
|
32
33
|
date = message["date"] || @fixed_date || new_date
|
34
|
+
dataset = message["dataset"] || @default_dataset
|
33
35
|
if not have_timeout?(message) and @default_timeout
|
34
36
|
message["timeout"] = @default_timeout
|
35
37
|
end
|
36
38
|
if not message["targetRole"].nil? and @default_target_role
|
37
39
|
message["targetRole"] = @default_target_role
|
38
40
|
end
|
39
|
-
message.merge("id"
|
41
|
+
message.merge("id" => id,
|
42
|
+
"date" => date,
|
43
|
+
"dataset" => dataset)
|
40
44
|
end
|
41
45
|
|
42
46
|
private
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
2
|
#
|
3
|
-
# Copyright (C) 2013-
|
3
|
+
# Copyright (C) 2013-2015 Droonga Project
|
4
4
|
#
|
5
5
|
# This library is free software; you can redistribute it and/or
|
6
6
|
# modify it under the terms of the GNU Lesser General Public
|
@@ -17,6 +17,6 @@
|
|
17
17
|
|
18
18
|
module Droonga
|
19
19
|
class Client
|
20
|
-
VERSION = "0.2.
|
20
|
+
VERSION = "0.2.2"
|
21
21
|
end
|
22
22
|
end
|
data/lib/droonga/command/base.rb
CHANGED
@@ -33,6 +33,10 @@ module Droonga
|
|
33
33
|
options = Slop.parse(:help => true) do |option|
|
34
34
|
yield(option) if block_given?
|
35
35
|
|
36
|
+
option.on(:"dry-run",
|
37
|
+
"Only reports messages to be sent to the engine.",
|
38
|
+
:default => false)
|
39
|
+
|
36
40
|
option.separator("Connections:")
|
37
41
|
option.on(:host=,
|
38
42
|
"Host name of the engine node.",
|
@@ -48,13 +52,13 @@ module Droonga
|
|
48
52
|
"Dataset name for the sending message.",
|
49
53
|
:default => Client::DEFAULT_DATASET)
|
50
54
|
option.on("receiver-host=",
|
51
|
-
"Host name of this
|
55
|
+
"Host name of the computer you are running this command.",
|
52
56
|
:default => Client::DEFAULT_HOST)
|
53
57
|
option.on("target-role=",
|
54
|
-
"Role of engine nodes which should
|
58
|
+
"Role of engine nodes which should process the message.",
|
55
59
|
:default => Client::DEFAULT_TARGET_ROLE)
|
56
60
|
option.on("timeout=",
|
57
|
-
"Time to terminate unresponsive connections
|
61
|
+
"Time to terminate unresponsive connections, in seconds.",
|
58
62
|
:default => Client::DEFAULT_TIMEOUT_SECONDS)
|
59
63
|
end
|
60
64
|
@options = options
|
@@ -63,12 +67,21 @@ module Droonga
|
|
63
67
|
raise MissingRequiredParameter.new
|
64
68
|
end
|
65
69
|
|
66
|
-
def request(message)
|
70
|
+
def request(message, &block)
|
71
|
+
if @options[:"dry-run"]
|
72
|
+
if @options[:pretty]
|
73
|
+
puts(JSON.pretty_generate(message))
|
74
|
+
else
|
75
|
+
puts(JSON.generate(message))
|
76
|
+
end
|
77
|
+
return nil
|
78
|
+
end
|
79
|
+
|
67
80
|
response = nil
|
68
81
|
open do |client|
|
69
82
|
response = client.request(message)
|
70
83
|
end
|
71
|
-
response
|
84
|
+
yield response
|
72
85
|
end
|
73
86
|
|
74
87
|
def send(message)
|
metadata
CHANGED
@@ -1,139 +1,153 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: droonga-client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Droonga Project
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-05-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: droonga-message-pack-packer
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- -
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '0'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- -
|
24
|
+
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: fluent-logger
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- -
|
31
|
+
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '0'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- -
|
38
|
+
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: grn2drn
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 1.0.5
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 1.0.5
|
41
55
|
- !ruby/object:Gem::Dependency
|
42
56
|
name: msgpack
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
44
58
|
requirements:
|
45
|
-
- -
|
59
|
+
- - ">="
|
46
60
|
- !ruby/object:Gem::Version
|
47
61
|
version: '0'
|
48
62
|
type: :runtime
|
49
63
|
prerelease: false
|
50
64
|
version_requirements: !ruby/object:Gem::Requirement
|
51
65
|
requirements:
|
52
|
-
- -
|
66
|
+
- - ">="
|
53
67
|
- !ruby/object:Gem::Version
|
54
68
|
version: '0'
|
55
69
|
- !ruby/object:Gem::Dependency
|
56
70
|
name: rack
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|
58
72
|
requirements:
|
59
|
-
- -
|
73
|
+
- - ">="
|
60
74
|
- !ruby/object:Gem::Version
|
61
75
|
version: '0'
|
62
76
|
type: :runtime
|
63
77
|
prerelease: false
|
64
78
|
version_requirements: !ruby/object:Gem::Requirement
|
65
79
|
requirements:
|
66
|
-
- -
|
80
|
+
- - ">="
|
67
81
|
- !ruby/object:Gem::Version
|
68
82
|
version: '0'
|
69
83
|
- !ruby/object:Gem::Dependency
|
70
84
|
name: slop
|
71
85
|
requirement: !ruby/object:Gem::Requirement
|
72
86
|
requirements:
|
73
|
-
- - <=
|
87
|
+
- - "<="
|
74
88
|
- !ruby/object:Gem::Version
|
75
89
|
version: 3.6.0
|
76
90
|
type: :runtime
|
77
91
|
prerelease: false
|
78
92
|
version_requirements: !ruby/object:Gem::Requirement
|
79
93
|
requirements:
|
80
|
-
- - <=
|
94
|
+
- - "<="
|
81
95
|
- !ruby/object:Gem::Version
|
82
96
|
version: 3.6.0
|
83
97
|
- !ruby/object:Gem::Dependency
|
84
98
|
name: yajl-ruby
|
85
99
|
requirement: !ruby/object:Gem::Requirement
|
86
100
|
requirements:
|
87
|
-
- -
|
101
|
+
- - ">="
|
88
102
|
- !ruby/object:Gem::Version
|
89
103
|
version: '0'
|
90
104
|
type: :runtime
|
91
105
|
prerelease: false
|
92
106
|
version_requirements: !ruby/object:Gem::Requirement
|
93
107
|
requirements:
|
94
|
-
- -
|
108
|
+
- - ">="
|
95
109
|
- !ruby/object:Gem::Version
|
96
110
|
version: '0'
|
97
111
|
- !ruby/object:Gem::Dependency
|
98
112
|
name: bundler
|
99
113
|
requirement: !ruby/object:Gem::Requirement
|
100
114
|
requirements:
|
101
|
-
- - ~>
|
115
|
+
- - "~>"
|
102
116
|
- !ruby/object:Gem::Version
|
103
117
|
version: '1.3'
|
104
118
|
type: :development
|
105
119
|
prerelease: false
|
106
120
|
version_requirements: !ruby/object:Gem::Requirement
|
107
121
|
requirements:
|
108
|
-
- - ~>
|
122
|
+
- - "~>"
|
109
123
|
- !ruby/object:Gem::Version
|
110
124
|
version: '1.3'
|
111
125
|
- !ruby/object:Gem::Dependency
|
112
126
|
name: packnga
|
113
127
|
requirement: !ruby/object:Gem::Requirement
|
114
128
|
requirements:
|
115
|
-
- -
|
129
|
+
- - ">="
|
116
130
|
- !ruby/object:Gem::Version
|
117
131
|
version: '0'
|
118
132
|
type: :development
|
119
133
|
prerelease: false
|
120
134
|
version_requirements: !ruby/object:Gem::Requirement
|
121
135
|
requirements:
|
122
|
-
- -
|
136
|
+
- - ">="
|
123
137
|
- !ruby/object:Gem::Version
|
124
138
|
version: '0'
|
125
139
|
- !ruby/object:Gem::Dependency
|
126
140
|
name: rake
|
127
141
|
requirement: !ruby/object:Gem::Requirement
|
128
142
|
requirements:
|
129
|
-
- -
|
143
|
+
- - ">="
|
130
144
|
- !ruby/object:Gem::Version
|
131
145
|
version: '0'
|
132
146
|
type: :development
|
133
147
|
prerelease: false
|
134
148
|
version_requirements: !ruby/object:Gem::Requirement
|
135
149
|
requirements:
|
136
|
-
- -
|
150
|
+
- - ">="
|
137
151
|
- !ruby/object:Gem::Version
|
138
152
|
version: '0'
|
139
153
|
description: Droonga client for Ruby
|
@@ -148,8 +162,8 @@ executables:
|
|
148
162
|
extensions: []
|
149
163
|
extra_rdoc_files: []
|
150
164
|
files:
|
151
|
-
- .gitignore
|
152
|
-
- .yardopts
|
165
|
+
- ".gitignore"
|
166
|
+
- ".yardopts"
|
153
167
|
- Gemfile
|
154
168
|
- LICENSE.txt
|
155
169
|
- README.md
|
@@ -184,12 +198,12 @@ require_paths:
|
|
184
198
|
- lib
|
185
199
|
required_ruby_version: !ruby/object:Gem::Requirement
|
186
200
|
requirements:
|
187
|
-
- -
|
201
|
+
- - ">="
|
188
202
|
- !ruby/object:Gem::Version
|
189
203
|
version: 1.9.3
|
190
204
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
191
205
|
requirements:
|
192
|
-
- -
|
206
|
+
- - ">="
|
193
207
|
- !ruby/object:Gem::Version
|
194
208
|
version: '0'
|
195
209
|
requirements: []
|