riak-client 1.0.0.beta → 1.0.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.
Files changed (69) hide show
  1. data/.gitignore +7 -4
  2. data/Gemfile +12 -17
  3. data/Guardfile +1 -1
  4. data/LICENSE +16 -0
  5. data/README.markdown +178 -0
  6. data/RELEASE_NOTES.md +99 -0
  7. data/Rakefile +25 -1
  8. data/erl_src/riak_kv_test014_backend.beam +0 -0
  9. data/erl_src/riak_kv_test014_backend.erl +189 -0
  10. data/erl_src/riak_kv_test_backend.beam +0 -0
  11. data/erl_src/riak_kv_test_backend.erl +37 -19
  12. data/lib/riak/client.rb +322 -272
  13. data/lib/riak/client/beefcake_protobuffs_backend.rb +6 -10
  14. data/lib/riak/client/decaying.rb +28 -0
  15. data/lib/riak/client/excon_backend.rb +27 -11
  16. data/lib/riak/client/http_backend.rb +71 -2
  17. data/lib/riak/client/http_backend/configuration.rb +17 -3
  18. data/lib/riak/client/http_backend/transport_methods.rb +3 -3
  19. data/lib/riak/client/net_http_backend.rb +18 -14
  20. data/lib/riak/client/node.rb +111 -0
  21. data/lib/riak/client/pool.rb +180 -0
  22. data/lib/riak/client/protobuffs_backend.rb +15 -5
  23. data/lib/riak/client/search.rb +9 -3
  24. data/lib/riak/link.rb +5 -7
  25. data/lib/riak/locale/en.yml +1 -0
  26. data/lib/riak/node/configuration.rb +1 -0
  27. data/lib/riak/node/defaults.rb +19 -6
  28. data/lib/riak/node/generation.rb +9 -2
  29. data/lib/riak/node/log.rb +2 -2
  30. data/lib/riak/node/version.rb +22 -16
  31. data/lib/riak/robject.rb +19 -3
  32. data/lib/riak/serializers.rb +1 -1
  33. data/lib/riak/test_server.rb +10 -2
  34. data/lib/riak/version.rb +1 -1
  35. data/riak-client.gemspec +3 -3
  36. data/spec/failover/failover.rb +59 -0
  37. data/spec/integration/riak/http_backends_spec.rb +2 -2
  38. data/spec/integration/riak/node_spec.rb +16 -24
  39. data/spec/integration/riak/protobuffs_backends_spec.rb +1 -1
  40. data/spec/integration/riak/test_server_spec.rb +4 -3
  41. data/spec/integration/riak/threading_spec.rb +193 -0
  42. data/spec/riak/beefcake_protobuffs_backend/object_methods_spec.rb +23 -0
  43. data/spec/riak/beefcake_protobuffs_backend_spec.rb +4 -2
  44. data/spec/riak/bucket_spec.rb +2 -1
  45. data/spec/riak/client_spec.rb +80 -181
  46. data/spec/riak/excon_backend_spec.rb +3 -2
  47. data/spec/riak/http_backend/configuration_spec.rb +37 -5
  48. data/spec/riak/http_backend/object_methods_spec.rb +1 -1
  49. data/spec/riak/http_backend/transport_methods_spec.rb +2 -2
  50. data/spec/riak/http_backend_spec.rb +53 -3
  51. data/spec/riak/map_reduce_spec.rb +1 -1
  52. data/spec/riak/net_http_backend_spec.rb +1 -2
  53. data/spec/riak/node_spec.rb +173 -0
  54. data/spec/riak/pool_spec.rb +306 -0
  55. data/spec/riak/robject_spec.rb +8 -4
  56. data/spec/riak/search_spec.rb +66 -15
  57. data/spec/riak/serializers_spec.rb +12 -1
  58. data/spec/spec_helper.rb +9 -1
  59. data/spec/support/http_backend_implementation_examples.rb +6 -2
  60. data/spec/support/sometimes.rb +46 -0
  61. data/spec/support/test_server.rb +50 -19
  62. data/spec/support/unified_backend_examples.rb +11 -10
  63. data/spec/support/version_filter.rb +14 -0
  64. metadata +40 -29
  65. data/lib/active_support/cache/riak_store.rb +0 -2
  66. data/lib/riak/cache_store.rb +0 -84
  67. data/lib/riak/client/pump.rb +0 -30
  68. data/lib/riak/util/fiber1.8.rb +0 -48
  69. data/spec/integration/riak/cache_store_spec.rb +0 -129
@@ -0,0 +1,14 @@
1
+ RSpec.configure do |config|
2
+ config.before(:each, :integration => true,
3
+ :version => lambda {|v| !!v },
4
+ :test_server => lambda {|ts| ts != false }) do
5
+ required = example.metadata[:version]
6
+ actual = test_server.version
7
+ case required
8
+ when String
9
+ pending("SKIP: Tests feature for Riak #{required}, but testing against #{actual}") if actual < required
10
+ when Range
11
+ pending("SKIP: Tests feature for Riak versions #{required.begin} through #{required.end}, but testing against #{actual}") unless required.include?(actual)
12
+ end
13
+ end
14
+ end
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: riak-client
3
3
  version: !ruby/object:Gem::Version
4
- hash: 31098193
5
- prerelease: 6
4
+ hash: 23
5
+ prerelease:
6
6
  segments:
7
7
  - 1
8
8
  - 0
9
9
  - 0
10
- - beta
11
- version: 1.0.0.beta
10
+ version: 1.0.0
12
11
  platform: ruby
13
12
  authors:
14
13
  - Sean Cribbs
@@ -16,8 +15,7 @@ autorequire:
16
15
  bindir: bin
17
16
  cert_chain: []
18
17
 
19
- date: 2011-11-08 00:00:00 -03:00
20
- default_executable:
18
+ date: 2012-02-03 00:00:00 Z
21
19
  dependencies:
22
20
  - !ruby/object:Gem::Dependency
23
21
  name: rspec
@@ -27,12 +25,12 @@ dependencies:
27
25
  requirements:
28
26
  - - ~>
29
27
  - !ruby/object:Gem::Version
30
- hash: 23
28
+ hash: 47
31
29
  segments:
32
30
  - 2
33
- - 6
31
+ - 8
34
32
  - 0
35
- version: 2.6.0
33
+ version: 2.8.0
36
34
  type: :development
37
35
  version_requirements: *id001
38
36
  - !ruby/object:Gem::Dependency
@@ -87,14 +85,12 @@ dependencies:
87
85
  requirement: &id005 !ruby/object:Gem::Requirement
88
86
  none: false
89
87
  requirements:
90
- - - ~>
88
+ - - ">="
91
89
  - !ruby/object:Gem::Version
92
- hash: 49
90
+ hash: 3
93
91
  segments:
94
92
  - 0
95
- - 8
96
- - 7
97
- version: 0.8.7
93
+ version: "0"
98
94
  type: :development
99
95
  version_requirements: *id005
100
96
  - !ruby/object:Gem::Dependency
@@ -171,18 +167,20 @@ extensions: []
171
167
  extra_rdoc_files: []
172
168
 
173
169
  files:
170
+ - erl_src/riak_kv_test014_backend.beam
171
+ - erl_src/riak_kv_test014_backend.erl
174
172
  - erl_src/riak_kv_test_backend.beam
175
173
  - erl_src/riak_kv_test_backend.erl
176
174
  - erl_src/riak_search_test_backend.beam
177
175
  - erl_src/riak_search_test_backend.erl
178
176
  - Gemfile
179
177
  - Guardfile
180
- - lib/active_support/cache/riak_store.rb
181
178
  - lib/riak/bucket.rb
182
- - lib/riak/cache_store.rb
179
+ - lib/riak/client/#http_backend.rb#
183
180
  - lib/riak/client/beefcake/messages.rb
184
181
  - lib/riak/client/beefcake/object_methods.rb
185
182
  - lib/riak/client/beefcake_protobuffs_backend.rb
183
+ - lib/riak/client/decaying.rb
186
184
  - lib/riak/client/excon_backend.rb
187
185
  - lib/riak/client/http_backend/configuration.rb
188
186
  - lib/riak/client/http_backend/key_streamer.rb
@@ -191,8 +189,9 @@ files:
191
189
  - lib/riak/client/http_backend/transport_methods.rb
192
190
  - lib/riak/client/http_backend.rb
193
191
  - lib/riak/client/net_http_backend.rb
192
+ - lib/riak/client/node.rb
193
+ - lib/riak/client/pool.rb
194
194
  - lib/riak/client/protobuffs_backend.rb
195
- - lib/riak/client/pump.rb
196
195
  - lib/riak/client/search.rb
197
196
  - lib/riak/client.rb
198
197
  - lib/riak/cluster.rb
@@ -215,6 +214,7 @@ files:
215
214
  - lib/riak/map_reduce/phase.rb
216
215
  - lib/riak/map_reduce.rb
217
216
  - lib/riak/map_reduce_error.rb
217
+ - lib/riak/node/#console.rb#
218
218
  - lib/riak/node/configuration.rb
219
219
  - lib/riak/node/console.rb
220
220
  - lib/riak/node/control.rb
@@ -229,7 +229,6 @@ files:
229
229
  - lib/riak/stamp.rb
230
230
  - lib/riak/test_server.rb
231
231
  - lib/riak/util/escape.rb
232
- - lib/riak/util/fiber1.8.rb
233
232
  - lib/riak/util/headers.rb
234
233
  - lib/riak/util/multipart/stream_parser.rb
235
234
  - lib/riak/util/multipart.rb
@@ -238,8 +237,12 @@ files:
238
237
  - lib/riak/version.rb
239
238
  - lib/riak/walk_spec.rb
240
239
  - lib/riak.rb
240
+ - LICENSE
241
241
  - Rakefile
242
+ - README.markdown
243
+ - RELEASE_NOTES.md
242
244
  - riak-client.gemspec
245
+ - spec/failover/failover.rb
243
246
  - spec/fixtures/cat.jpg
244
247
  - spec/fixtures/multipart-blank.txt
245
248
  - spec/fixtures/multipart-mapreduce.txt
@@ -249,12 +252,13 @@ files:
249
252
  - spec/fixtures/server.cert.crt
250
253
  - spec/fixtures/server.cert.key
251
254
  - spec/fixtures/test.pem
252
- - spec/integration/riak/cache_store_spec.rb
253
255
  - spec/integration/riak/cluster_spec.rb
254
256
  - spec/integration/riak/http_backends_spec.rb
255
257
  - spec/integration/riak/node_spec.rb
256
258
  - spec/integration/riak/protobuffs_backends_spec.rb
257
259
  - spec/integration/riak/test_server_spec.rb
260
+ - spec/integration/riak/threading_spec.rb
261
+ - spec/riak/beefcake_protobuffs_backend/object_methods_spec.rb
258
262
  - spec/riak/beefcake_protobuffs_backend_spec.rb
259
263
  - spec/riak/bucket_spec.rb
260
264
  - spec/riak/client_spec.rb
@@ -272,6 +276,8 @@ files:
272
276
  - spec/riak/map_reduce_spec.rb
273
277
  - spec/riak/multipart_spec.rb
274
278
  - spec/riak/net_http_backend_spec.rb
279
+ - spec/riak/node_spec.rb
280
+ - spec/riak/pool_spec.rb
275
281
  - spec/riak/robject_spec.rb
276
282
  - spec/riak/search_spec.rb
277
283
  - spec/riak/serializers_spec.rb
@@ -284,12 +290,13 @@ files:
284
290
  - spec/support/integration_setup.rb
285
291
  - spec/support/mock_server.rb
286
292
  - spec/support/mocks.rb
293
+ - spec/support/sometimes.rb
287
294
  - spec/support/test_server.rb
288
295
  - spec/support/test_server.yml.example
289
296
  - spec/support/unified_backend_examples.rb
297
+ - spec/support/version_filter.rb
290
298
  - .gitignore
291
- has_rdoc: true
292
- homepage: http://seancribbs.github.com/ripple
299
+ homepage: http://github.com/basho/riak-ruby-client
293
300
  licenses: []
294
301
 
295
302
  post_install_message:
@@ -309,22 +316,21 @@ required_ruby_version: !ruby/object:Gem::Requirement
309
316
  required_rubygems_version: !ruby/object:Gem::Requirement
310
317
  none: false
311
318
  requirements:
312
- - - ">"
319
+ - - ">="
313
320
  - !ruby/object:Gem::Version
314
- hash: 25
321
+ hash: 3
315
322
  segments:
316
- - 1
317
- - 3
318
- - 1
319
- version: 1.3.1
323
+ - 0
324
+ version: "0"
320
325
  requirements: []
321
326
 
322
327
  rubyforge_project:
323
- rubygems_version: 1.6.2
328
+ rubygems_version: 1.8.10
324
329
  signing_key:
325
330
  specification_version: 3
326
331
  summary: riak-client is a rich client for Riak, the distributed database by Basho.
327
332
  test_files:
333
+ - spec/failover/failover.rb
328
334
  - spec/fixtures/cat.jpg
329
335
  - spec/fixtures/multipart-blank.txt
330
336
  - spec/fixtures/multipart-mapreduce.txt
@@ -334,12 +340,13 @@ test_files:
334
340
  - spec/fixtures/server.cert.crt
335
341
  - spec/fixtures/server.cert.key
336
342
  - spec/fixtures/test.pem
337
- - spec/integration/riak/cache_store_spec.rb
338
343
  - spec/integration/riak/cluster_spec.rb
339
344
  - spec/integration/riak/http_backends_spec.rb
340
345
  - spec/integration/riak/node_spec.rb
341
346
  - spec/integration/riak/protobuffs_backends_spec.rb
342
347
  - spec/integration/riak/test_server_spec.rb
348
+ - spec/integration/riak/threading_spec.rb
349
+ - spec/riak/beefcake_protobuffs_backend/object_methods_spec.rb
343
350
  - spec/riak/beefcake_protobuffs_backend_spec.rb
344
351
  - spec/riak/bucket_spec.rb
345
352
  - spec/riak/client_spec.rb
@@ -357,6 +364,8 @@ test_files:
357
364
  - spec/riak/map_reduce_spec.rb
358
365
  - spec/riak/multipart_spec.rb
359
366
  - spec/riak/net_http_backend_spec.rb
367
+ - spec/riak/node_spec.rb
368
+ - spec/riak/pool_spec.rb
360
369
  - spec/riak/robject_spec.rb
361
370
  - spec/riak/search_spec.rb
362
371
  - spec/riak/serializers_spec.rb
@@ -369,7 +378,9 @@ test_files:
369
378
  - spec/support/integration_setup.rb
370
379
  - spec/support/mock_server.rb
371
380
  - spec/support/mocks.rb
381
+ - spec/support/sometimes.rb
372
382
  - spec/support/test_server.rb
373
383
  - spec/support/test_server.yml.example
374
384
  - spec/support/unified_backend_examples.rb
385
+ - spec/support/version_filter.rb
375
386
  - .gitignore
@@ -1,2 +0,0 @@
1
- require 'riak'
2
- require 'riak/cache_store'
@@ -1,84 +0,0 @@
1
-
2
- require 'yaml'
3
- require 'riak/client'
4
- require 'riak/bucket'
5
- require 'riak/robject'
6
- require 'riak/failed_request'
7
- require 'active_support/version'
8
-
9
- if ActiveSupport::VERSION::STRING < "3.0.0"
10
- raise LoadError, "ActiveSupport 3.0.0 or greater is required to use Riak::CacheStore."
11
- else
12
- require 'active_support/cache'
13
- end
14
-
15
- module Riak
16
- # An ActiveSupport::Cache::Store implementation that uses Riak.
17
- # Compatible only with ActiveSupport version 3 or greater.
18
- class CacheStore < ActiveSupport::Cache::Store
19
- attr_accessor :client
20
-
21
- # Creates a Riak-backed cache store.
22
- def initialize(options = {})
23
- super
24
- @bucket_name = options.delete(:bucket) || '_cache'
25
- @n_value = options.delete(:n_value) || 2
26
- @r = options.delete(:r) || 1
27
- @w = options.delete(:w) || 1
28
- @dw = options.delete(:dw) || 0
29
- @rw = options.delete(:rw) || "quorum"
30
- @client = Riak::Client.new(options)
31
- set_bucket_defaults
32
- end
33
-
34
- def bucket
35
- @bucket ||= @client.bucket(@bucket_name)
36
- end
37
-
38
- def delete_matched(matcher, options={})
39
- instrument(:delete_matched, matcher) do
40
- bucket.keys do |keys|
41
- keys.grep(matcher).each do |k|
42
- bucket.delete(k)
43
- end
44
- end
45
- end
46
- end
47
-
48
- protected
49
- def set_bucket_defaults
50
- begin
51
- new_values = {}
52
- new_values['n_val'] = @n_value unless bucket.n_value == @n_value
53
- new_values['r'] = @r unless bucket.r == @r
54
- new_values['w'] = @w unless bucket.w == @w
55
- new_values['dw'] = @dw unless bucket.dw == @dw
56
- new_values['rw'] = @rw unless bucket.rw == @rw
57
- bucket.props = new_values unless new_values.empty?
58
- rescue
59
- end
60
- end
61
-
62
- def write_entry(key, value, options={})
63
- object = bucket.get_or_new(key)
64
- object.content_type = 'application/yaml'
65
- object.data = value
66
- object.store
67
- end
68
-
69
- def read_entry(key, options={})
70
- begin
71
- bucket.get(key).data
72
- rescue Riak::FailedRequest => fr
73
- raise fr unless fr.not_found?
74
- nil
75
- end
76
- end
77
-
78
- def delete_entry(key, options={})
79
- bucket.delete(key)
80
- end
81
- end
82
- end
83
-
84
- ActiveSupport::Cache::RiakStore = Riak::CacheStore unless defined?(ActiveSupport::Cache::RiakStore)
@@ -1,30 +0,0 @@
1
-
2
- begin
3
- require 'fiber'
4
- rescue LoadError
5
- require 'riak/util/fiber1.8'
6
- end
7
-
8
- module Riak
9
- class Client
10
- # @private
11
- class Pump
12
- def initialize(block)
13
- @fiber = Fiber.new do
14
- loop do
15
- block.call Fiber.yield
16
- end
17
- end
18
- @fiber.resume
19
- end
20
-
21
- def pump(input)
22
- @fiber.resume input
23
- end
24
-
25
- def to_proc
26
- method(:pump).to_proc
27
- end
28
- end
29
- end
30
- end
@@ -1,48 +0,0 @@
1
- # Poor Man's Fiber (API compatible Thread based Fiber implementation for Ruby 1.8)
2
- # (c) 2008 Aman Gupta (tmm1)
3
-
4
- unless defined? Fiber
5
- require 'thread'
6
-
7
- class FiberError < StandardError; end
8
-
9
- class Fiber
10
- def initialize
11
- raise ArgumentError, 'new Fiber requires a block' unless block_given?
12
-
13
- @yield = Queue.new
14
- @resume = Queue.new
15
-
16
- @thread = Thread.new{ @yield.push [ *yield(*@resume.pop) ] }
17
- @thread.abort_on_exception = true
18
- @thread[:fiber] = self
19
- end
20
- attr_reader :thread
21
-
22
- def resume *args
23
- raise FiberError, 'dead fiber called' unless @thread.alive?
24
- @resume.push(args)
25
- result = @yield.pop
26
- result.size > 1 ? result : result.first
27
- end
28
-
29
- def yield *args
30
- @yield.push(args)
31
- result = @resume.pop
32
- result.size > 1 ? result : result.first
33
- end
34
-
35
- def self.yield *args
36
- raise FiberError, "can't yield from root fiber" unless fiber = Thread.current[:fiber]
37
- fiber.yield(*args)
38
- end
39
-
40
- def self.current
41
- Thread.current[:fiber] or raise FiberError, 'not inside a fiber'
42
- end
43
-
44
- def inspect
45
- "#<#{self.class}:0x#{self.object_id.to_s(16)}>"
46
- end
47
- end
48
- end
@@ -1,129 +0,0 @@
1
- require 'spec_helper'
2
- require 'riak/cache_store'
3
-
4
- describe Riak::CacheStore do
5
- before do
6
- @web_port = $test_server.http_port
7
- @cache = ActiveSupport::Cache.lookup_store(:riak_store, :http_port => @web_port)
8
- end
9
-
10
- describe "Riak integration" do
11
- it "should have a client" do
12
- @cache.should respond_to(:client)
13
- @cache.client.should be_kind_of(Riak::Client)
14
- end
15
-
16
- it "should have a bucket to store entries in" do
17
- @cache.bucket.should be_kind_of(Riak::Bucket)
18
- end
19
-
20
- it "should configure the client according to the initialized options" do
21
- @cache = ActiveSupport::Cache.lookup_store(:riak_store, :http_port => 10000)
22
- @cache.client.http_port.should == 10000
23
- end
24
-
25
- it "should choose the bucket according to the initializer option" do
26
- @cache = ActiveSupport::Cache.lookup_store(:riak_store, :bucket => "foobar", :http_port => @web_port)
27
- @cache.bucket.name.should == "foobar"
28
- end
29
-
30
- it "should set the N value to 2 by default" do
31
- @cache.bucket.n_value.should == 2
32
- end
33
-
34
- it "should set the N value to the specified value" do
35
- @cache = ActiveSupport::Cache.lookup_store(:riak_store, :n_value => 1, :http_port => @web_port)
36
- @cache.bucket.n_value.should == 1
37
- end
38
-
39
- it "should set the bucket R value to 1 by default" do
40
- @cache.bucket.r.should == 1
41
- end
42
-
43
- it "should set the bucket R default to the specified value" do
44
- @cache = ActiveSupport::Cache.lookup_store(:riak_store, :r => "quorum", :http_port => @web_port)
45
- @cache.bucket.r.should == "quorum"
46
- end
47
-
48
- it "should set the bucket W value to 1 by default" do
49
- @cache.bucket.w.should == 1
50
- end
51
-
52
- it "should set the bucket W default to the specified value" do
53
- @cache = ActiveSupport::Cache.lookup_store(:riak_store, :w => "all", :http_port => @web_port)
54
- @cache.bucket.w.should == "all"
55
- end
56
-
57
- it "should set the bucket DW value to 0 by default" do
58
- @cache.bucket.dw.should == 0
59
- end
60
-
61
- it "should set the bucket DW default to the specified value" do
62
- @cache = ActiveSupport::Cache.lookup_store(:riak_store, :dw => "quorum", :http_port => @web_port)
63
- @cache.bucket.dw.should == "quorum"
64
- end
65
-
66
- it "should set the bucket RW value to quorum by default" do
67
- @cache.bucket.rw.should == "quorum"
68
- end
69
-
70
- it "should set the bucket RW default to the specified value" do
71
- @cache = ActiveSupport::Cache.lookup_store(:riak_store, :rw => "all", :http_port => @web_port)
72
- @cache.bucket.rw.should == "all"
73
- end
74
- end
75
-
76
-
77
- it "should read and write strings" do
78
- @cache.write('foo', 'bar')
79
- @cache.read('foo').should == 'bar'
80
- end
81
-
82
- it "should read and write hashes" do
83
- @cache.write('foo', {:a => "b"})
84
- @cache.read('foo').should == {:a => "b"}
85
- end
86
-
87
- it "should read and write integers" do
88
- @cache.write('foo', 1)
89
- @cache.read('foo').should == 1
90
- end
91
-
92
- it "should read and write nil" do
93
- @cache.write('foo', nil)
94
- @cache.read('foo').should be_nil
95
- end
96
-
97
- it "should return the stored value when fetching on hit" do
98
- @cache.write('foo', 'bar')
99
- @cache.fetch('foo'){'baz'}.should == 'bar'
100
- end
101
-
102
- it "should return the default value when fetching on miss" do
103
- @cache.fetch('foo'){ 'baz' }.should == 'baz'
104
- end
105
-
106
- it "should return the default value when forcing a miss" do
107
- @cache.fetch('foo', :force => true){'bar'}.should == 'bar'
108
- end
109
-
110
- it "should detect if a value exists in the cache" do
111
- @cache.write('foo', 'bar')
112
- @cache.exist?('foo').should be_true
113
- end
114
-
115
- it "should delete matching keys from the cache" do
116
- @cache.write('foo', 'bar')
117
- @cache.write('green', 'thumb')
118
- @cache.delete_matched(/foo/)
119
- @cache.read('foo').should be_nil
120
- @cache.read('green').should == 'thumb'
121
- end
122
-
123
- it "should delete a single key from the cache" do
124
- @cache.write('foo', 'bar')
125
- @cache.read('foo').should == 'bar'
126
- @cache.delete('foo')
127
- @cache.read('foo').should be_nil
128
- end
129
- end