mogilefs-client 3.9.0 → 3.10.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 +4 -4
- data/.gitattributes +4 -0
- data/.olddoc.yml +2 -0
- data/GIT-VERSION-GEN +1 -1
- data/README +1 -1
- data/lib/mogilefs.rb +2 -0
- data/lib/mogilefs/admin.rb +3 -2
- data/lib/mogilefs/backend.rb +14 -9
- data/lib/mogilefs/bigfile.rb +1 -1
- data/lib/mogilefs/bigfile/filter.rb +2 -2
- data/lib/mogilefs/chunker.rb +2 -3
- data/lib/mogilefs/client.rb +3 -1
- data/lib/mogilefs/mogilefs.rb +6 -2
- data/lib/mogilefs/new_file/stream.rb +1 -1
- data/lib/mogilefs/socket/pure_ruby.rb +76 -35
- data/pkg.mk +1 -1
- data/test/fresh.rb +1 -1
- data/test/test_backend.rb +16 -1
- data/test/test_fresh.rb +1 -1
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d02264aa8b34f8fab16add61f2e81ee0643127cf
|
4
|
+
data.tar.gz: 5b333aa4abe0f863d819a9a480fa11180b902f1b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c6d650e02544bf8b432c80d50c21b13fbdca9169cd69b5513b534e66b7dc279f25a81a7b8823233e7e2b844d4624dd7d8c06ed38f74212d79a386884b8621f30
|
7
|
+
data.tar.gz: bd840975cb4154cc4aa6a0370765a7ff48dbf5374daa8aef079a48a2de9b27c4c3a96a543c9c52c6a2de95324fe8271b3a98818d41cc9d55edf8dc03890c0b09
|
data/.gitattributes
ADDED
data/.olddoc.yml
CHANGED
@@ -5,3 +5,5 @@ rdoc_url: http://bogomips.org/mogilefs-client
|
|
5
5
|
changelog_start: v1.2.1
|
6
6
|
private_email: e@80x24.org
|
7
7
|
public_email: mogilefs-client-public@bogomips.org
|
8
|
+
nntp_url: nntp://news.public-inbox.org/inbox.comp.file-systems.mogilefs.ruby
|
9
|
+
ml_url: http://bogomips.org/mogilefs-client-public/
|
data/GIT-VERSION-GEN
CHANGED
data/README
CHANGED
@@ -14,7 +14,7 @@ list-cc :: mailto:mogile@googlegroups.com
|
|
14
14
|
list-archive :: http://bogomips.org/mogilefs-client-public
|
15
15
|
email :: mailto:e@80x24.org
|
16
16
|
repo :: git://bogomips.org/mogilefs-client.git
|
17
|
-
|
17
|
+
http://bogomips.org/mogilefs-client.git
|
18
18
|
gitweb :: http://repo.or.cz/w/ruby-mogilefs-client.git
|
19
19
|
download :: http://bogomips.org/mogilefs-client/files/
|
20
20
|
|
data/lib/mogilefs.rb
CHANGED
@@ -5,6 +5,7 @@
|
|
5
5
|
# Client usage information is available in MogileFS::MogileFS.
|
6
6
|
module MogileFS
|
7
7
|
|
8
|
+
# :stopdoc:
|
8
9
|
if defined?(Process::CLOCK_MONOTONIC)
|
9
10
|
def self.now
|
10
11
|
Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
@@ -14,6 +15,7 @@ def self.now
|
|
14
15
|
Time.now.to_f
|
15
16
|
end
|
16
17
|
end
|
18
|
+
# :startdoc:
|
17
19
|
|
18
20
|
# Standard error class for most MogileFS-specific errors
|
19
21
|
Error = Class.new(StandardError)
|
data/lib/mogilefs/admin.rb
CHANGED
@@ -69,8 +69,7 @@ def get_devices(devid = nil)
|
|
69
69
|
rv = clean('devices', 'dev', rv, true, to_i, want)
|
70
70
|
|
71
71
|
rv.each do |row|
|
72
|
-
u = row["utilization"] and
|
73
|
-
row["utilization"] = nil == u ? nil : u.to_f
|
72
|
+
u = row["utilization"] and row["utilization"] = u.to_f
|
74
73
|
|
75
74
|
case row["observed_state"]
|
76
75
|
when ""
|
@@ -83,6 +82,8 @@ def get_devices(devid = nil)
|
|
83
82
|
row["reject_bad_md5"] = true
|
84
83
|
when "0"
|
85
84
|
row["reject_bad_md5"] = false
|
85
|
+
when ""
|
86
|
+
row["reject_bad_md5"] = nil
|
86
87
|
end
|
87
88
|
end
|
88
89
|
end
|
data/lib/mogilefs/backend.rb
CHANGED
@@ -79,6 +79,7 @@ def initialize(args)
|
|
79
79
|
|
80
80
|
@mutex = Mutex.new
|
81
81
|
@timeout = args[:timeout] || 3
|
82
|
+
@connect_timeout = args[:connect_timeout] || @timeout
|
82
83
|
@socket = nil
|
83
84
|
@lasterr = nil
|
84
85
|
@lasterrstr = nil
|
@@ -242,7 +243,7 @@ def do_request(cmd, args, idempotent = false)
|
|
242
243
|
begin
|
243
244
|
io = dispatch_unlocked(request)
|
244
245
|
line = io.timed_gets(@timeout)
|
245
|
-
break if /\
|
246
|
+
break if /\n\z/ =~ line
|
246
247
|
|
247
248
|
line and raise MogileFS::InvalidResponseError,
|
248
249
|
"Invalid response from server: #{line.inspect}"
|
@@ -313,7 +314,7 @@ def clear_cache(types = %w(all))
|
|
313
314
|
types.each { |type| opts[type] = 1 }
|
314
315
|
|
315
316
|
sockets = @hosts.map do |host|
|
316
|
-
MogileFS::Socket.start(*(host.split(
|
317
|
+
MogileFS::Socket.start(*(host.split(':'.freeze))) rescue nil
|
317
318
|
end
|
318
319
|
sockets.compact!
|
319
320
|
|
@@ -346,8 +347,8 @@ def socket
|
|
346
347
|
next if dead = @dead[host] and dead[0] > (MogileFS.now - @fail_timeout)
|
347
348
|
|
348
349
|
begin
|
349
|
-
addr, port = host.split(
|
350
|
-
@socket = MogileFS::Socket.tcp(addr, port, @
|
350
|
+
addr, port = host.split(':'.freeze)
|
351
|
+
@socket = MogileFS::Socket.tcp(addr, port, @connect_timeout)
|
351
352
|
@active_host = host
|
352
353
|
rescue SystemCallError, MogileFS::Timeout => err
|
353
354
|
@dead[host] = [ MogileFS.now, err ]
|
@@ -365,8 +366,8 @@ def socket
|
|
365
366
|
# Turns a url params string into a Hash.
|
366
367
|
def url_decode(str) # :nodoc:
|
367
368
|
rv = {}
|
368
|
-
str.split(
|
369
|
-
k, v = pair.split(
|
369
|
+
str.split('&'.freeze).each do |pair|
|
370
|
+
k, v = pair.split('='.freeze, 2).map! { |x| url_unescape(x) }
|
370
371
|
rv[k.freeze] = v
|
371
372
|
end
|
372
373
|
rv
|
@@ -382,13 +383,15 @@ def url_decode(str) # :nodoc:
|
|
382
383
|
def url_encode(params) # :nodoc:
|
383
384
|
params.map do |k,v|
|
384
385
|
"#{url_escape k.to_s}=#{url_escape v.to_s}"
|
385
|
-
end.join(
|
386
|
+
end.join('&'.freeze)
|
386
387
|
end
|
387
388
|
|
388
389
|
# Escapes naughty URL characters.
|
389
390
|
if ''.respond_to?(:ord) # Ruby 1.9
|
390
391
|
def url_escape(str) # :nodoc:
|
391
|
-
str.gsub(/([^\w\,\-.\/\\\: ])/) { "%%%02x" % $1.ord }
|
392
|
+
str = str.gsub(/([^\w\,\-.\/\\\: ])/) { "%%%02x".freeze % $1.ord }
|
393
|
+
str.tr!(' '.freeze, '+'.freeze)
|
394
|
+
str
|
392
395
|
end
|
393
396
|
else # Ruby 1.8
|
394
397
|
def url_escape(str) # :nodoc:
|
@@ -398,6 +401,8 @@ def url_escape(str) # :nodoc:
|
|
398
401
|
|
399
402
|
# Unescapes naughty URL characters.
|
400
403
|
def url_unescape(str) # :nodoc:
|
401
|
-
str.tr('+', ' '
|
404
|
+
str = str.tr('+'.freeze, ' '.freeze)
|
405
|
+
str.gsub!(/%([a-f0-9][a-f0-9])/i) { [$1.to_i(16)].pack('C'.freeze) }
|
406
|
+
str
|
402
407
|
end
|
403
408
|
end
|
data/lib/mogilefs/bigfile.rb
CHANGED
@@ -26,6 +26,7 @@ def bigfile_write(key, wr_io, opts = { :verify => false })
|
|
26
26
|
# we only decode raw zlib deflated streams that mogtool (unfortunately)
|
27
27
|
# generates. tarballs and gzip(1) are up to to the application to decrypt.
|
28
28
|
if info[:compressed] || opts[:verify]
|
29
|
+
require 'mogilefs/bigfile/filter'
|
29
30
|
wr_io = MogileFS::Bigfile::Filter.new(wr_io, info, opts)
|
30
31
|
end
|
31
32
|
|
@@ -85,7 +86,6 @@ def bigfile_parse_info(info) # :nodoc:
|
|
85
86
|
rv
|
86
87
|
end
|
87
88
|
end
|
88
|
-
require "mogilefs/bigfile/filter"
|
89
89
|
|
90
90
|
__END__
|
91
91
|
# Copied from mogtool:
|
@@ -33,7 +33,7 @@ def flush
|
|
33
33
|
end
|
34
34
|
|
35
35
|
def write(buf)
|
36
|
-
|
36
|
+
unless @zi
|
37
37
|
if @info[:compressed] &&
|
38
38
|
INFLATABLE_TYPES.include?(@info[:type]) &&
|
39
39
|
buf.bytesize >= 2 &&
|
@@ -51,7 +51,7 @@ def write(buf)
|
|
51
51
|
if @zi
|
52
52
|
buf = @zi.inflate(buf)
|
53
53
|
else
|
54
|
-
@md5
|
54
|
+
@md5.update(buf) if @md5
|
55
55
|
end
|
56
56
|
@io.write(buf)
|
57
57
|
end
|
data/lib/mogilefs/chunker.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
# -*- encoding: binary -*-
|
2
2
|
class MogileFS::Chunker
|
3
|
-
CRLF = "\r\n"
|
4
3
|
attr_reader :io
|
5
4
|
|
6
5
|
def initialize(io, md5, expect_md5)
|
@@ -14,7 +13,7 @@ def write(buf)
|
|
14
13
|
@io.write("#{rv.to_s(16)}\r\n")
|
15
14
|
@io.write(buf)
|
16
15
|
@md5.update(buf) if @md5
|
17
|
-
@io.write(
|
16
|
+
@io.write("\r\n".freeze)
|
18
17
|
rv
|
19
18
|
end
|
20
19
|
|
@@ -30,7 +29,7 @@ def flush
|
|
30
29
|
end
|
31
30
|
@io.write("0\r\nContent-MD5: #{content_md5}\r\n\r\n")
|
32
31
|
else
|
33
|
-
@io.write("0\r\n\r\n")
|
32
|
+
@io.write("0\r\n\r\n".freeze)
|
34
33
|
end
|
35
34
|
end
|
36
35
|
end
|
data/lib/mogilefs/client.rb
CHANGED
@@ -27,6 +27,7 @@ def initialize(args)
|
|
27
27
|
@readonly = args[:readonly] ? true : false
|
28
28
|
@timeout = args[:timeout]
|
29
29
|
@fail_timeout = args[:fail_timeout]
|
30
|
+
@connect_timeout = args[:connect_timeout]
|
30
31
|
|
31
32
|
reload
|
32
33
|
end
|
@@ -37,7 +38,8 @@ def initialize(args)
|
|
37
38
|
def reload
|
38
39
|
@backend = MogileFS::Backend.new(:hosts => @hosts,
|
39
40
|
:timeout => @timeout,
|
40
|
-
:fail_timeout => @fail_timeout
|
41
|
+
:fail_timeout => @fail_timeout,
|
42
|
+
:connect_timeout => @connect_timeout)
|
41
43
|
end
|
42
44
|
|
43
45
|
##
|
data/lib/mogilefs/mogilefs.rb
CHANGED
@@ -64,6 +64,10 @@ class MogileFS::MogileFS < MogileFS::Client
|
|
64
64
|
# Timeout for tracker backend responses.
|
65
65
|
# Defaults to 3 seconds.
|
66
66
|
#
|
67
|
+
# [:connect_timeout => Integer]
|
68
|
+
#
|
69
|
+
# Timeout for connecting to a tracker
|
70
|
+
# Defaults to 3 seconds
|
67
71
|
def initialize(args = {})
|
68
72
|
@domain = args[:domain]
|
69
73
|
|
@@ -503,7 +507,7 @@ def file_info(key, args = nil)
|
|
503
507
|
def file_info_cleanup(rv) # :nodoc:
|
504
508
|
%w(fid length devcount).each { |f| rv[f] = rv[f].to_i }
|
505
509
|
devids = rv["devids"] and
|
506
|
-
rv["devids"] = devids.split(
|
510
|
+
rv["devids"] = devids.split(','.freeze).map! { |x| x.to_i }
|
507
511
|
rv
|
508
512
|
end
|
509
513
|
|
@@ -540,7 +544,7 @@ def file_debug(args)
|
|
540
544
|
nexttry|fromdevid|failcount|flags|devid|type)\z/x
|
541
545
|
rv[k] = v.to_i
|
542
546
|
when /devids\z/
|
543
|
-
rv[k] = v.split(
|
547
|
+
rv[k] = v.split(','.freeze).map! { |x| x.to_i }
|
544
548
|
end
|
545
549
|
end
|
546
550
|
end
|
@@ -5,13 +5,21 @@
|
|
5
5
|
class MogileFS::Socket < Socket
|
6
6
|
include MogileFS::SocketCommon
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
sock.connect_nonblock(sockaddr_in(port, host))
|
12
|
-
|
8
|
+
if RUBY_VERSION.to_f >= 2.3
|
9
|
+
def self.start(host, port)
|
10
|
+
sock = new(Socket::AF_INET, Socket::SOCK_STREAM, 0)
|
11
|
+
sock.connect_nonblock(sockaddr_in(port, host), :exception => false)
|
12
|
+
sock.post_init(host, port)
|
13
|
+
end
|
14
|
+
else
|
15
|
+
def self.start(host, port)
|
16
|
+
sock = new(Socket::AF_INET, Socket::SOCK_STREAM, 0)
|
17
|
+
begin
|
18
|
+
sock.connect_nonblock(sockaddr_in(port, host))
|
19
|
+
rescue Errno::EINPROGRESS
|
20
|
+
end
|
21
|
+
sock.post_init(host, port)
|
13
22
|
end
|
14
|
-
sock.post_init(host, port)
|
15
23
|
end
|
16
24
|
|
17
25
|
def self.tcp(host, port, timeout = 5)
|
@@ -23,50 +31,83 @@ def self.tcp(host, port, timeout = 5)
|
|
23
31
|
sock
|
24
32
|
end
|
25
33
|
|
26
|
-
def wait_writable(timeout)
|
34
|
+
def wait_writable(timeout = nil)
|
27
35
|
IO.select(nil, [ self ], nil, timeout)
|
28
36
|
end unless self.instance_methods.include?(:wait_writable) # Ruby <2.0.0
|
29
37
|
|
30
|
-
def timed_read(len, dst = "", timeout = 5)
|
31
|
-
begin
|
32
|
-
wait_readable(timeout) or unreadable_socket!(timeout)
|
33
|
-
return read_nonblock(len, dst)
|
34
|
-
rescue Errno::EAGAIN
|
35
|
-
rescue EOFError
|
36
|
-
return
|
37
|
-
end while true
|
38
|
-
end
|
39
|
-
|
40
38
|
def timed_peek(len, dst, timeout = 5)
|
41
39
|
begin
|
42
|
-
wait_readable(timeout) or unreadable_socket!(timeout)
|
43
40
|
rc = recv_nonblock(len, Socket::MSG_PEEK)
|
44
41
|
return rc.empty? ? nil : dst.replace(rc)
|
45
42
|
rescue Errno::EAGAIN
|
43
|
+
wait(timeout) or unreadable_socket!(timeout)
|
46
44
|
rescue EOFError
|
47
45
|
dst.replace("")
|
48
46
|
return
|
49
47
|
end while true
|
48
|
+
rescue EOFError
|
49
|
+
nil
|
50
50
|
end
|
51
51
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
52
|
+
# write_nonblock and read_nonblock support `exception: false`
|
53
|
+
if RUBY_VERSION.to_f >= 2.1
|
54
|
+
def timed_read(len, dst = "", timeout = 5)
|
55
|
+
case rc = read_nonblock(len, dst, :exception => false)
|
56
|
+
when String
|
57
|
+
return rc
|
58
|
+
when :wait_readable
|
59
|
+
wait(timeout) or unreadable_socket!(timeout)
|
60
|
+
when nil
|
61
|
+
return
|
62
|
+
end while true
|
63
|
+
rescue EOFError
|
64
|
+
nil
|
65
|
+
end
|
66
|
+
|
67
|
+
def timed_write(buf, timeout = 5)
|
68
|
+
written = 0
|
69
|
+
expect = buf.bytesize
|
70
|
+
case rc = write_nonblock(buf, :exception => false)
|
71
|
+
when Integer
|
72
|
+
return expect if rc == buf.bytesize
|
73
|
+
written += rc
|
74
|
+
buf = buf.byteslice(rc, buf.bytesize) # Ruby 1.9.3+
|
75
|
+
when :wait_writable
|
76
|
+
wait_writable(timeout) or request_truncated!(written, expect, timeout)
|
77
|
+
end while true
|
78
|
+
end
|
79
|
+
else # Ruby 1.8.7 - 2.0.0
|
80
|
+
def timed_read(len, dst = "", timeout = 5)
|
81
|
+
begin
|
82
|
+
return read_nonblock(len, dst)
|
83
|
+
rescue Errno::EAGAIN
|
84
|
+
wait(timeout) or unreadable_socket!(timeout)
|
85
|
+
rescue EOFError
|
86
|
+
return
|
87
|
+
end while true
|
88
|
+
rescue EOFError
|
89
|
+
nil
|
90
|
+
end
|
59
91
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
92
|
+
def timed_write(buf, timeout = 5)
|
93
|
+
written = 0
|
94
|
+
expect = buf.bytesize
|
95
|
+
begin
|
96
|
+
rc = write_nonblock(buf)
|
97
|
+
return expect if rc == buf.bytesize
|
98
|
+
written += rc
|
99
|
+
|
100
|
+
if buf.respond_to?(:byteslice) # Ruby 1.9.3+
|
101
|
+
buf = buf.byteslice(rc, buf.bytesize)
|
102
|
+
else
|
103
|
+
if buf.respond_to?(:encoding) && buf.encoding != Encoding::BINARY
|
104
|
+
buf = buf.dup.force_encoding(Encoding::BINARY)
|
105
|
+
end
|
106
|
+
buf = buf.slice(rc, buf.bytesize)
|
65
107
|
end
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
end while true
|
108
|
+
rescue Errno::EAGAIN
|
109
|
+
wait_writable(timeout) or request_truncated!(written, expect, timeout)
|
110
|
+
end while true
|
111
|
+
end
|
71
112
|
end
|
72
113
|
end
|
data/pkg.mk
CHANGED
data/test/fresh.rb
CHANGED
@@ -82,7 +82,7 @@ def add_host_device_domain
|
|
82
82
|
# MogileFS::Server 2.60+ shows reject_bad_md5 monitor status
|
83
83
|
dev = @admin.get_devices[0]
|
84
84
|
if dev.include?("reject_bad_md5")
|
85
|
-
assert [true, false].include?(dev["reject_bad_md5"])
|
85
|
+
assert [true, false, nil].include?(dev["reject_bad_md5"]), dev.inspect
|
86
86
|
end
|
87
87
|
|
88
88
|
out = err = nil
|
data/test/test_backend.rb
CHANGED
@@ -25,12 +25,14 @@ def test_initialize
|
|
25
25
|
|
26
26
|
assert_equal ['localhost:1'], @backend.hosts
|
27
27
|
assert_equal 3, @backend.timeout
|
28
|
+
assert_equal 3, @backend.instance_variable_get(:@connect_timeout)
|
28
29
|
assert_equal nil, @backend.lasterr
|
29
30
|
assert_equal nil, @backend.lasterrstr
|
30
31
|
assert_equal({}, @backend.dead)
|
31
32
|
|
32
33
|
@backend = MogileFS::Backend.new :hosts => ['localhost:6001'], :timeout => 1
|
33
34
|
assert_equal 1, @backend.timeout
|
35
|
+
assert_equal 1, @backend.instance_variable_get(:@connect_timeout)
|
34
36
|
end
|
35
37
|
|
36
38
|
def test_do_request
|
@@ -223,5 +225,18 @@ def test_fail_timeout
|
|
223
225
|
c = MogileFS::MogileFS.new(o)
|
224
226
|
assert_equal 0.666, c.backend.instance_variable_get(:@fail_timeout)
|
225
227
|
end
|
226
|
-
end
|
227
228
|
|
229
|
+
def test_connect_timeout
|
230
|
+
o = {
|
231
|
+
:domain => "none",
|
232
|
+
:hosts => %w(0:666 0:6 0:66),
|
233
|
+
:connect_timeout => 1
|
234
|
+
}
|
235
|
+
c = MogileFS::MogileFS.new(o)
|
236
|
+
assert_equal 1, c.backend.instance_variable_get(:@connect_timeout)
|
237
|
+
o[:timeout] = 5
|
238
|
+
c = MogileFS::MogileFS.new(o)
|
239
|
+
assert_equal 1, c.backend.instance_variable_get(:@connect_timeout)
|
240
|
+
assert_equal 5, c.backend.instance_variable_get(:@timeout)
|
241
|
+
end
|
242
|
+
end
|
data/test/test_fresh.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mogilefs-client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.
|
4
|
+
version: 3.10.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- mogilefs-client hackers
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-08-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: olddoc
|
@@ -36,6 +36,7 @@ extensions: []
|
|
36
36
|
extra_rdoc_files: []
|
37
37
|
files:
|
38
38
|
- ".document"
|
39
|
+
- ".gitattributes"
|
39
40
|
- ".gitignore"
|
40
41
|
- ".manifest"
|
41
42
|
- ".olddoc.yml"
|
@@ -126,7 +127,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
126
127
|
version: '0'
|
127
128
|
requirements: []
|
128
129
|
rubyforge_project:
|
129
|
-
rubygems_version: 2.
|
130
|
+
rubygems_version: 2.6.6
|
130
131
|
signing_key:
|
131
132
|
specification_version: 4
|
132
133
|
summary: client - MogileFS client library for Ruby
|