droonga-client 0.0.1 → 0.1.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8451550565af3065d58578612f6a93f66346a5d2
4
- data.tar.gz: 24a9b4f1bd9d8a055ac12d100a324590fb527ca9
3
+ metadata.gz: 8624d5def9e15c15e068add4c8f60f007fcb6d21
4
+ data.tar.gz: 5ae5c17b038077337bf1653de18243c39afe7250
5
5
  SHA512:
6
- metadata.gz: 5b5ec6bfd26accbe56311256ef64fe349cbcad404fdf659da43c5d19558277abe21c342e621e95d81e94560abd56d6e0c49b1c8ce402bbd6e0509401da7d823f
7
- data.tar.gz: a83b71c182458ae873ad27913defd1f67172a04a302f7ec67d977ccd6acd48f3f8307bab72b2054e7c330a65ba705c6d65ad2bf15c0045975d57111df8398803
6
+ metadata.gz: 3cf44081bdd4f97c0cab49adbd8d64be5270465608f291dcc492441eae82d6eb522aa694e790dfedad7d6db46b77a04ed1c75e5df75771e7ab918a47b9b482c4
7
+ data.tar.gz: a7e2fd87920b468f14beb8169fef80490351d0cbf8e151cedce15f74fdb50dddff724739215a56027afc035d028175c2b5f639a9d778a4be748369b659c33c31
data/doc/text/news.md CHANGED
@@ -1,5 +1,14 @@
1
1
  # News
2
2
 
3
+ ## 0.1.0: 2013-12-29
4
+
5
+ ### Improvements
6
+
7
+ * Added {Droonga::Client.open}.
8
+ * Added {Droonga::Client#close}.
9
+ * Supported multiple responses.
10
+ * Supported asynchronous request.
11
+
3
12
  ## 0.0.1: 2013-11-29
4
13
 
5
14
  The first release!!!
@@ -16,6 +16,7 @@
16
16
  # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
17
 
18
18
  require "socket"
19
+ require "thread"
19
20
  require "msgpack"
20
21
  require "fluent-logger"
21
22
 
@@ -23,20 +24,32 @@ module Droonga
23
24
  class Client
24
25
  module Connection
25
26
  class DroongaProtocol
27
+ class Request
28
+ def initialize(thread)
29
+ @thread = thread
30
+ end
31
+
32
+ def wait
33
+ @thread.join
34
+ end
35
+ end
36
+
26
37
  def initialize(options={})
27
38
  default_options = {
28
- :tag => "droonga",
29
- :host => "127.0.0.1",
30
- :port => 24224,
31
- :timeout => 5
39
+ :tag => "droonga",
40
+ :host => "127.0.0.1",
41
+ :port => 24224,
42
+ :connect_timeout => 1,
43
+ :read_timeout => 0.1,
32
44
  }
33
45
  options = default_options.merge(options)
34
46
  @logger = Fluent::Logger::FluentLogger.new(options.delete(:tag),
35
47
  options)
36
- @timeout = options[:timeout]
48
+ @connect_timeout = options[:connect_timeout]
49
+ @read_timeout = options[:read_timeout]
37
50
  end
38
51
 
39
- def search(body)
52
+ def search(body, &block)
40
53
  envelope = {
41
54
  "id" => Time.now.to_f.to_s,
42
55
  "date" => Time.now,
@@ -44,42 +57,88 @@ module Droonga
44
57
  "type" => "search",
45
58
  "body" => body,
46
59
  }
47
- send(envelope, :response => :one)
60
+ execute(envelope, &block)
48
61
  end
49
62
 
50
- # Sends low level request. Normally, you should use other
51
- # convenience methods.
63
+ # Sends a request message and receives one ore more response
64
+ # messages.
52
65
  #
53
- # @param envelope [Hash] Request envelope.
54
- # @param options [Hash] The options to send request.
55
- # @option options :response [nil, :none, :one] (nil) The response type.
56
- # If you specify `nil`, it is treated as `:one`.
57
- # @return The response. TODO: WRITE ME
58
- def send(envelope, options={})
59
- response_type = options[:response] || :one
60
- case response_type
61
- when :none
62
- @logger.post("message", envelope)
63
- when :one
64
- receiver = Receiver.new
66
+ # @overload execute(message, options={})
67
+ # Executes the request message synchronously.
68
+ #
69
+ # @param message [Hash] Request message.
70
+ # @param options [Hash] The options to executes a request.
71
+ # TODO: WRITE ME
72
+ #
73
+ # @return [Object] The response. TODO: WRITE ME
74
+ #
75
+ # @overload execute(message, options={}, &block)
76
+ # Executes the passed request message asynchronously.
77
+ #
78
+ # @param message [Hash] Request message.
79
+ # @param options [Hash] The options to executes a request.
80
+ # TODO: WRITE ME
81
+ # @yield [response]
82
+ # The block is called when response is received.
83
+ # @yieldparam [Object] response
84
+ # The response.
85
+ #
86
+ # @return [Request] The request object.
87
+ def execute(message, options={}, &block)
88
+ receiver = Receiver.new
89
+ message = message.dup
90
+ message["replyTo"] = "#{receiver.host}:#{receiver.port}/droonga"
91
+ send(message, options)
92
+
93
+ connect_timeout = options[:connect_timeout] || @connect_timeout
94
+ read_timeout = options[:read_timeout] || @read_timeout
95
+ receive_options = {
96
+ :connect_timeout => connect_timeout,
97
+ :read_timeout => read_timeout
98
+ }
99
+ sync = block.nil?
100
+ if sync
65
101
  begin
66
- envelope = envelope.dup
67
- envelope["replyTo"] = "#{receiver.host}:#{receiver.port}/droonga"
68
- @logger.post("message", envelope)
69
- receiver.receive(:timeout => @timeout)
102
+ receiver.receive(receive_options)
70
103
  ensure
71
104
  receiver.close
72
105
  end
73
106
  else
74
- raise InvalidResponseType.new(response_type)
107
+ thread = Thread.new do
108
+ begin
109
+ response = receiver.receive(receive_options)
110
+ yield(response) if response
111
+ ensure
112
+ receiver.close
113
+ end
114
+ end
115
+ Request.new(thread)
75
116
  end
76
117
  end
77
118
 
119
+ # Sends low level request. Normally, you should use other
120
+ # convenience methods.
121
+ #
122
+ # @param envelope [Hash] Request envelope.
123
+ # @param options [Hash] The options to send request.
124
+ # TODO: WRITE ME
125
+ # @return [void]
126
+ def send(envelope, options={}, &block)
127
+ @logger.post("message", envelope)
128
+ end
129
+
130
+ # Close the connection. This connection can't be used anymore.
131
+ #
132
+ # @return [void]
133
+ def close
134
+ @logger.close
135
+ end
136
+
78
137
  class Receiver
79
138
  def initialize(options={})
80
139
  default_options = {
81
- :host => "0.0.0.0",
82
- :port => 0,
140
+ :host => "0.0.0.0",
141
+ :port => 0,
83
142
  }
84
143
  options = default_options.merge(options)
85
144
  @socket = TCPServer.new(options[:host], options[:port])
@@ -97,19 +156,38 @@ module Droonga
97
156
  @socket.addr[1]
98
157
  end
99
158
 
159
+ BUFFER_SIZE = 8192
100
160
  def receive(options={})
101
- if IO.select([@socket], nil, nil, options[:timeout])
161
+ responses = []
162
+ select(@socket, options[:connect_timeout]) do
102
163
  client = @socket.accept
103
- response = nil
104
- unpacker = MessagePack::Unpacker.new(client)
105
- unpacker.each do |object|
106
- response = object
107
- break
164
+ unpacker = MessagePack::Unpacker.new
165
+ select(client, options[:read_timeout]) do
166
+ data = client.read_nonblock(BUFFER_SIZE)
167
+ unpacker.feed_each(data) do |object|
168
+ responses << object
169
+ end
108
170
  end
109
171
  client.close
110
- response
111
- else
112
- nil
172
+ end
173
+ # TODO: ENABLE ME
174
+ # if responses.size >= 2
175
+ # responses
176
+ # else
177
+ responses.first
178
+ # end
179
+ end
180
+
181
+ private
182
+ def select(input, timeout)
183
+ loop do
184
+ start = Time.now
185
+ readables, = IO.select([input], nil, nil, timeout)
186
+ timeout -= (Time.now - start)
187
+ timeout /= 2.0
188
+ timeout = 0 if timeout < 0
189
+ break if readables.nil?
190
+ yield(timeout)
113
191
  end
114
192
  end
115
193
  end
@@ -17,6 +17,6 @@
17
17
 
18
18
  module Droonga
19
19
  class Client
20
- VERSION = "0.0.1"
20
+ VERSION = "0.1.0"
21
21
  end
22
22
  end
@@ -21,8 +21,40 @@ require "droonga/client/connection/droonga_protocol"
21
21
 
22
22
  module Droonga
23
23
  class Client
24
+ class << self
25
+ # Opens a new connection and yields a {Client} object to use the
26
+ # connection. The client is closed after the given block is
27
+ # finished.
28
+ #
29
+ # @param (see #initialize)
30
+ #
31
+ # @yield [client] Gives the opened client. It is alive while yielding.
32
+ # @yieldparam client [Client] The opened client.
33
+ #
34
+ # @return The return value from the given block.
35
+ def open(options={})
36
+ client = new(options)
37
+ begin
38
+ yield(client)
39
+ ensure
40
+ client.close
41
+ end
42
+ end
43
+ end
44
+
24
45
  attr_reader :connection
25
46
 
47
+ # Creates a new Droonga Engine client.
48
+ #
49
+ # @param options [Hash] Options to connect Droonga Engine.
50
+ # @option options [String] :tag ("droonga") The tag of the request message.
51
+ # @option options [String] :host ("127.0.0.1")
52
+ # The host name or IP address of the Droonga Engine to be connected.
53
+ # @option options [Integer] :port (24224)
54
+ # The port number of the Droonga Engine to be connected.
55
+ # @option options [Integer] :timeout (5)
56
+ # The timeout value for connecting to, writing to and reading
57
+ # from Droonga Engine.
26
58
  def initialize(options={})
27
59
  @connection = Connection::DroongaProtocol.new(options)
28
60
  end
@@ -30,5 +62,13 @@ module Droonga
30
62
  def search(body)
31
63
  @connection.search(body)
32
64
  end
65
+
66
+ # Close the connection used by the client. You can't send any
67
+ # request anymore.
68
+ #
69
+ # @return [void]
70
+ def close
71
+ @connection.close
72
+ end
33
73
  end
34
74
  end
metadata CHANGED
@@ -1,83 +1,83 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: droonga-client
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Droonga Project
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-11-29 00:00:00.000000000 Z
11
+ date: 2013-12-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: msgpack
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
41
  - !ruby/object:Gem::Dependency
42
42
  name: bundler
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - "~>"
45
+ - - ~>
46
46
  - !ruby/object:Gem::Version
47
47
  version: '1.3'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - "~>"
52
+ - - ~>
53
53
  - !ruby/object:Gem::Version
54
54
  version: '1.3'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: rake
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - ">="
59
+ - - '>='
60
60
  - !ruby/object:Gem::Version
61
61
  version: '0'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - ">="
66
+ - - '>='
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: packnga
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - ">="
73
+ - - '>='
74
74
  - !ruby/object:Gem::Version
75
75
  version: '0'
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - ">="
80
+ - - '>='
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
83
  description: Droonga client for Ruby
@@ -87,8 +87,8 @@ executables: []
87
87
  extensions: []
88
88
  extra_rdoc_files: []
89
89
  files:
90
- - ".gitignore"
91
- - ".yardopts"
90
+ - .gitignore
91
+ - .yardopts
92
92
  - Gemfile
93
93
  - LICENSE.txt
94
94
  - README.md
@@ -110,17 +110,17 @@ require_paths:
110
110
  - lib
111
111
  required_ruby_version: !ruby/object:Gem::Requirement
112
112
  requirements:
113
- - - ">="
113
+ - - '>='
114
114
  - !ruby/object:Gem::Version
115
115
  version: '0'
116
116
  required_rubygems_version: !ruby/object:Gem::Requirement
117
117
  requirements:
118
- - - ">="
118
+ - - '>='
119
119
  - !ruby/object:Gem::Version
120
120
  version: '0'
121
121
  requirements: []
122
122
  rubyforge_project:
123
- rubygems_version: 2.2.0
123
+ rubygems_version: 2.0.14
124
124
  signing_key:
125
125
  specification_version: 4
126
126
  summary: Droonga client for Ruby