libgfapi-ruby 0.0.8 → 0.0.9

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f2cf4e28e5936b345b94a5b64495a3aee76b48e6
4
- data.tar.gz: 52d88565ff4b52182ec47e0d7495b4eca46df4ca
3
+ metadata.gz: 4e77e350dc931b821a46330717902e9dcc53b145
4
+ data.tar.gz: 2edc86242e04fbc8c33e7b5182f35400f9b27cf0
5
5
  SHA512:
6
- metadata.gz: 64da0439a3d8bedf46943b3a98dba14ad1b1938a53871f6489f47df036cb711b165a318513689b030ce15bf5eea59aa0e9569c2d9307e1cd3abbca4ce8c432b8
7
- data.tar.gz: d85a6a1eea2c1fc5609a17c8217a0f41cb52598284bbde20db89aabbc21d6c49e67be55b96574b20f4a066bd1fff2d12d53df67abccb810d9bbda049dbb2f636
6
+ metadata.gz: db150aa3a1b1b3019aeba9ec219f74b94015d877ec47e024ff3306045a323050a19f523a24591600f0ef00edec53f842a2672da6f0d7e444ff2d96dfe04e19b0
7
+ data.tar.gz: dcb362fa8d89b90100015cbd45fdbbc4068b07eb19a0347980a43a6b62deb443d7296304997a69c64fece012a68cd43fd9cd11d67e3c4ca93f937c7f295bf742
@@ -338,6 +338,11 @@ module GlusterFS
338
338
  =end
339
339
  attach_function :lstat, :glfs_lstat, [:pointer, :string, :pointer], :int
340
340
 
341
+ =begin
342
+ int glfs_fsync (glfs_fd_t *fd) __THROW;
343
+ =end
344
+ attach_function :fsync, :glfs_fsync, [:pointer], :int
345
+
341
346
  =begin
342
347
  glfs_fd_t *glfs_opendir (glfs_t *fs, const char *path) __THROW;
343
348
  =end
@@ -7,7 +7,7 @@ class GlusterFS::File
7
7
  end
8
8
 
9
9
  def read_file(buf_size = 4092)
10
- raise GlusterFS::Error, "File is empty or does not exist: #{@path}" if lstat[:st_size] < 1
10
+ check_exists
11
11
  fd = GlusterFS.open(@volume.fs, @path, 0)
12
12
  temp = Tempfile.new(path.gsub('/', '-'))
13
13
  buff = FFI::MemoryPointer.new(:char, buf_size)
@@ -22,6 +22,7 @@ class GlusterFS::File
22
22
  end
23
23
 
24
24
  def read(buf_size = 4092)
25
+ check_exists
25
26
  fd = GlusterFS.open(@volume.fs, @path, 0)
26
27
  temp = ''
27
28
  buff = FFI::MemoryPointer.new(:char, buf_size)
@@ -35,9 +36,13 @@ class GlusterFS::File
35
36
  temp
36
37
  end
37
38
 
38
- def write_file(file, perms = 0644)
39
+ def write_file(file, perms = 0644, buffer_size = 4092)
39
40
  fd = GlusterFS.creat(@volume.fs, path, 2, perms)
40
- res = GlusterFS.write(fd, file.read, file.size, 0)
41
+ res = 0
42
+ until file.eof?
43
+ chunk = file.read(buffer_size)
44
+ res += GlusterFS.write(fd, chunk, chunk.size , 0)
45
+ end
41
46
  GlusterFS.close(fd)
42
47
  res
43
48
  end
@@ -67,4 +72,11 @@ class GlusterFS::File
67
72
  lstat[:st_size]
68
73
  end
69
74
 
75
+ private
76
+
77
+ # Reading non-existing file causes segfault on file.read
78
+ def check_exists
79
+ raise GlusterFS::Error, "File does not exist: #{@path}" unless exists?
80
+ end
81
+
70
82
  end
@@ -1,3 +1,3 @@
1
1
  module GlusterFS
2
- VERSION = "0.0.8"
2
+ VERSION = "0.0.9"
3
3
  end
@@ -22,5 +22,6 @@ Gem::Specification.new do |spec|
22
22
  spec.add_development_dependency "bundler", "~> 1.5"
23
23
  spec.add_development_dependency "rake"
24
24
  spec.add_development_dependency "rspec"
25
+ spec.add_development_dependency "pry-nav"
25
26
  spec.add_development_dependency "ruby-mass"
26
27
  end
@@ -48,9 +48,10 @@ module GlusterFS
48
48
  end
49
49
 
50
50
  context '#write_file' do
51
+ let(:contents) { '12345' * 1024 }
51
52
  let(:data) do
52
53
  d = Tempfile.new('test')
53
- d.write '12345'
54
+ d.write contents
54
55
  d.rewind
55
56
  d
56
57
  end
@@ -58,7 +59,26 @@ module GlusterFS
58
59
 
59
60
  context 'writes file' do
60
61
  subject { file.write_file(data) }
61
- it('returns bytes written') { should == data.length }
62
+ specify 'consistently' do
63
+ subject.should == data.length
64
+ file.read.should == contents
65
+ end
66
+ end
67
+
68
+ context 'with small buffer' do
69
+ subject { file.write_file(data, 0644, 16) }
70
+ specify 'consistently' do
71
+ subject.should == data.length
72
+ file.read.should == contents
73
+ end
74
+ end
75
+
76
+ context 'with huge buffer' do
77
+ subject { file.write_file(data, 0644, 102400) }
78
+ specify 'consistently' do
79
+ subject.should == data.length
80
+ file.read.should == contents
81
+ end
62
82
  end
63
83
 
64
84
  context 'overwrites file' do
@@ -1,9 +1,8 @@
1
1
  require 'ruby-mass'
2
2
  module GlusterFS
3
3
 
4
- # Set MEM_PRINT=1 MEM_ITERATIONS=10000 to get a stress test
5
-
6
4
  def self.mem_size
5
+ ObjectSpace.garbage_collect
7
6
  _, size = `ps ax -o pid,rss | grep -E "^[[:space:]]*#{$$}"`.strip.split.map(&:to_i)
8
7
  size.to_i
9
8
  end
@@ -22,17 +21,38 @@ module GlusterFS
22
21
  puts "RUBY_FREE_MIN=#{ENV['RUBY_FREE_MIN']}"
23
22
  puts "Initial memory use: #{GlusterFS.mem_size}"
24
23
  Mass.print
24
+ else
25
+ puts "Set MEM_PRINT=1 MEM_ITERATIONS=10000 to get a better memory stress test"
25
26
  end
26
27
  end
27
28
 
28
- let(:random_blob) do
29
- o = [('a'..'z'), ('A'..'Z')].map { |i| i.to_a }.flatten
30
- (0...15000).map { o[rand(o.length)] }.join
29
+ let!(:random_blob) do
30
+ '0' * 1048576 * 5 # 5MB
31
31
  end
32
32
  let(:volume) { Volume.new(GFS_VOLUME)
33
33
  .mount(GFS_SERVER_HOST, GFS_SERVER_PORT) }
34
34
  let(:root_dir) { Directory.new(volume, '/memtest-root') }
35
35
 
36
+ # Mem leak here! Only run when MEM_ITERATIONS is provided.
37
+ if ENV['MEM_ITERATIONS']
38
+ context 'mount / unmount volume' do
39
+ specify do
40
+ puts "Volume Iterations: #{iterations}"
41
+ mem_size_before = GlusterFS.mem_size
42
+ iterations.times do |i|
43
+ vol = Volume.new(GFS_VOLUME)
44
+ vol.mount(GFS_SERVER_HOST, GFS_SERVER_PORT)
45
+ vol.unmount
46
+ puts i
47
+ end
48
+ mem_size = GlusterFS.mem_size
49
+ puts "Mem growth: #{mem_size - mem_size_before}"
50
+ Mass.print if ENV['MEM_PRINT']
51
+ (mem_size - mem_size_before).should be < 10240
52
+ end
53
+ end
54
+ end
55
+
36
56
  context 'create many directories' do
37
57
  before { root_dir.create }
38
58
  after { root_dir.delete }
@@ -0,0 +1,77 @@
1
+ require 'ruby-mass'
2
+ require 'fileutils'
3
+ require 'benchmark'
4
+ module GlusterFS
5
+
6
+ describe 'performance' do
7
+ let(:file_mount_point) { ENV['GFS_MOUNT_DIR'] || '/mnt/dist-volume' }
8
+ let(:iterations) { (ENV['PERF_ITERATIONS'] || 100).to_i }
9
+ let!(:random_blob) do
10
+ '0' * 1048576 * 5 # 5MB
11
+ end
12
+
13
+ specify 'native file system operations' do
14
+ test_dir ="/tmp/fs-perftest-root"
15
+ FileUtils.rm_rf test_dir
16
+ time = Benchmark.realtime do
17
+ FileUtils.mkdir_p test_dir
18
+ iterations.times do |i|
19
+ dir = "#{test_dir}/perf-test-#{i}"
20
+ FileUtils.mkdir dir
21
+ file = "#{dir}/file-#{i}"
22
+ ::File.open(file, 'w+') do |f|
23
+ f.write(random_blob)
24
+ end
25
+ FileUtils.rm(file)
26
+ FileUtils.rmdir(dir)
27
+ end
28
+ FileUtils.rmdir(test_dir)
29
+ end
30
+ puts "Native FS Time: #{iterations} iterations: #{'%.4f' % time} sec"
31
+ end
32
+
33
+ specify 'mounted file system operations' do
34
+ test_dir ="#{file_mount_point}/mnt-perftest-root"
35
+ FileUtils.rm_rf test_dir
36
+ time = Benchmark.realtime do
37
+ FileUtils.mkdir_p test_dir
38
+ iterations.times do |i|
39
+ dir = "#{test_dir}/perf-test-#{i}"
40
+ FileUtils.mkdir dir
41
+ file = "#{dir}/file-#{i}"
42
+ ::File.open(file, 'w+') do |f|
43
+ f.write(random_blob)
44
+ end
45
+ FileUtils.rm(file)
46
+ FileUtils.rmdir(dir)
47
+ end
48
+ FileUtils.rmdir(test_dir)
49
+ end
50
+ puts "Mounted FS Time: #{iterations} iterations: #{'%.4f' % time} sec"
51
+ end
52
+
53
+ let(:volume) { Volume.new(GFS_VOLUME)
54
+ .mount(GFS_SERVER_HOST, GFS_SERVER_PORT) }
55
+ specify 'api operations' do
56
+ test_dir ="/gfs-perftest-root"
57
+ FileUtils.rm_rf "#{file_mount_point}/test_dir"
58
+ time = Benchmark.realtime do
59
+ gfs_test_dir = Directory.new(volume, test_dir)
60
+ gfs_test_dir.create
61
+ iterations.times do |i|
62
+ dir = "#{test_dir}/perf-test-#{i}"
63
+ gfs_dir = Directory.new(volume, dir)
64
+ gfs_dir.create
65
+ file = "#{dir}/file-#{i}"
66
+ gfs_file = File.new(volume, file)
67
+ gfs_file.write(random_blob)
68
+ gfs_file.delete
69
+ gfs_dir.delete
70
+ end
71
+ gfs_test_dir.delete
72
+ end
73
+ puts "GFS API Time: #{iterations} iterations: #{'%.4f' % time} sec"
74
+ end
75
+
76
+ end
77
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: libgfapi-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.8
4
+ version: 0.0.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tomas Varaneckas
@@ -66,6 +66,20 @@ dependencies:
66
66
  - - '>='
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: pry-nav
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
69
83
  - !ruby/object:Gem::Dependency
70
84
  name: ruby-mass
71
85
  requirement: !ruby/object:Gem::Requirement
@@ -105,6 +119,7 @@ files:
105
119
  - spec/glusterfs/directory_spec.rb
106
120
  - spec/glusterfs/file_spec.rb
107
121
  - spec/glusterfs/stress/memleak_spec.rb
122
+ - spec/glusterfs/stress/performance_spec.rb
108
123
  - spec/glusterfs/volume_spec.rb
109
124
  - spec/spec_helper.rb
110
125
  homepage: https://github.com/spajus/libgfapi-ruby
@@ -135,6 +150,7 @@ test_files:
135
150
  - spec/glusterfs/directory_spec.rb
136
151
  - spec/glusterfs/file_spec.rb
137
152
  - spec/glusterfs/stress/memleak_spec.rb
153
+ - spec/glusterfs/stress/performance_spec.rb
138
154
  - spec/glusterfs/volume_spec.rb
139
155
  - spec/spec_helper.rb
140
156
  has_rdoc: