jio 0.1

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.
@@ -0,0 +1,26 @@
1
+ #ifndef JIO_TRANSACTION_H
2
+ #define JIO_TRANSACTION_H
3
+
4
+ #define JIO_TRANSACTION_RELEASED 0x01
5
+
6
+ typedef struct {
7
+ jtrans_t *trans;
8
+ VALUE views;
9
+ int flags;
10
+ } jio_jtrans_wrapper;
11
+
12
+ #define JioAssertTransaction(obj) JioAssertType(obj, rb_cJioTransaction, "JIO::Transaction")
13
+ #define JioGetTransaction(obj) \
14
+ jio_jtrans_wrapper *trans = NULL; \
15
+ JioAssertTransaction(obj); \
16
+ Data_Get_Struct(obj, jio_jtrans_wrapper, trans); \
17
+ if (!trans) rb_raise(rb_eTypeError, "uninitialized JIO transaction handle!");
18
+
19
+ void rb_jio_mark_transaction(void *ptr);
20
+ void rb_jio_free_transaction(void *ptr);
21
+
22
+ VALUE rb_jio_file_new_transaction(VALUE obj, VALUE flags);
23
+
24
+ void _init_rb_jio_transaction();
25
+
26
+ #endif
Binary file
@@ -0,0 +1,22 @@
1
+ # encoding: utf-8
2
+
3
+ require File.expand_path('../lib/jio/version', __FILE__)
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "jio"
7
+ s.version = JIO::VERSION
8
+ s.summary = "jio - transactional, journaled file I/O for Ruby"
9
+ s.description = "jio - transactional, journaled file I/O for Ruby"
10
+ s.authors = ["Lourens Naudé"]
11
+ s.email = ["lourens@methodmissing.com"]
12
+ s.homepage = "http://github.com/methodmissing/jio"
13
+ s.date = Time.now.utc.strftime('%Y-%m-%d')
14
+ s.platform = Gem::Platform::RUBY
15
+ s.extensions = Dir["ext/jio/extconf.rb"]
16
+ s.has_rdoc = true
17
+ s.files = `git ls-files`.split
18
+ s.test_files = `git ls-files test`.split("\n")
19
+ s.rdoc_options = ["--charset=UTF-8"]
20
+ s.require_paths = ["lib"]
21
+ s.add_development_dependency('rake-compiler', '~> 0.8.1')
22
+ end
@@ -0,0 +1,12 @@
1
+ # encoding: utf-8
2
+
3
+ begin
4
+ require "jio/jio_ext"
5
+ rescue LoadError
6
+ require "jio_ext"
7
+ end
8
+
9
+ module JIO
10
+ end
11
+
12
+ require 'jio/file'
@@ -0,0 +1,24 @@
1
+ # encoding: utf-8
2
+
3
+ module JIO
4
+ class File
5
+ alias orig_transaction transaction
6
+ def transaction(flags)
7
+ if block_given?
8
+ begin
9
+ trans = orig_transaction(flags)
10
+ yield trans
11
+ rescue
12
+ trans.rollback
13
+ error = true
14
+ raise
15
+ ensure
16
+ trans.commit if !error && !trans.committed?
17
+ trans.release
18
+ end
19
+ else
20
+ orig_transaction(flags)
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,5 @@
1
+ # encoding: utf-8
2
+
3
+ module JIO
4
+ VERSION = '0.1'
5
+ end
@@ -0,0 +1,32 @@
1
+ # encoding: utf-8
2
+
3
+ require 'test/unit'
4
+ require 'jio'
5
+ require 'fileutils' #19
6
+ require 'timeout'
7
+
8
+ TMP = File.expand_path(File.join(File.dirname(__FILE__), '..', 'tmp'))
9
+ SANDBOX = File.join(TMP, 'sandbox')
10
+ FileUtils.rm_rf SANDBOX
11
+ FileUtils.mkdir_p SANDBOX
12
+
13
+ class JioTestCase < Test::Unit::TestCase
14
+ FILE = File.join(SANDBOX, 'file.jio')
15
+ OPEN_ARGS = [FILE, JIO::RDWR | JIO::CREAT | JIO::TRUNC, 0644, JIO::J_LINGER]
16
+
17
+ undef_method :default_test if method_defined? :default_test
18
+
19
+ def setup
20
+ File.unlink(FILE) if File.exists?(FILE)
21
+ end
22
+
23
+ if ENV['STRESS_GC']
24
+ def setup
25
+ GC.stress = true
26
+ end
27
+
28
+ def teardown
29
+ GC.stress = false
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,116 @@
1
+ # encoding: utf-8
2
+
3
+ require File.join(File.dirname(__FILE__), 'helper')
4
+
5
+ class TestFile < JioTestCase
6
+ def test_open_close
7
+ file = JIO.open(*OPEN_ARGS)
8
+ assert_instance_of JIO::File, file
9
+ ensure
10
+ assert file.close
11
+ end
12
+
13
+ def test_sync
14
+ file = JIO.open(*OPEN_ARGS)
15
+ assert file.sync
16
+ ensure
17
+ assert file.close
18
+ end
19
+
20
+ def test_move_journal
21
+ file = JIO.open(*OPEN_ARGS)
22
+ assert file.move_journal(SANDBOX)
23
+ ensure
24
+ assert file.close
25
+ end
26
+
27
+ def test_autosync
28
+ file = JIO.open(*OPEN_ARGS)
29
+ assert file.autosync(1, 1024)
30
+ file.write("CO")
31
+ file.write("MM")
32
+ file.write("IT")
33
+ sleep 1.1
34
+ file.rewind
35
+ assert_equal "COMMIT", file.read(6)
36
+ assert file.stop_autosync
37
+ ensure
38
+ assert file.close
39
+ end
40
+
41
+ def test_read_write
42
+ file = JIO.open(*OPEN_ARGS)
43
+ assert_equal "", file.read(0)
44
+ assert_equal 4, file.write('ABCD')
45
+ assert_equal 'ABCD', file.pread(4, 0)
46
+ file.pwrite('EFGH', 4)
47
+ assert_equal 'EFGH', file.pread(4, 4)
48
+ file.pwrite('LMNOPQRS', 0)
49
+ assert_equal 'LMNOPQRS', file.pread(8, 0)
50
+ ensure
51
+ assert file.close
52
+ end
53
+
54
+ def test_lseek
55
+ file = JIO.open(*OPEN_ARGS)
56
+ assert_equal 4, file.write('ABCD')
57
+ file.lseek(2, IO::SEEK_SET)
58
+ assert_equal 'CD', file.read(2)
59
+ ensure
60
+ assert file.close
61
+ end
62
+
63
+ def test_truncate
64
+ file = JIO.open(*OPEN_ARGS)
65
+ assert_equal 4, file.write('ABCD')
66
+ assert_equal 4, File.size(FILE)
67
+ file.truncate(2)
68
+ assert_equal 2, File.size(FILE)
69
+ file.truncate(0)
70
+ assert_equal 0, File.size(FILE)
71
+ ensure
72
+ assert file.close
73
+ end
74
+
75
+ def test_fileno
76
+ file = JIO.open(*OPEN_ARGS)
77
+ assert_instance_of Fixnum, file.fileno
78
+ ensure
79
+ assert file.close
80
+ end
81
+
82
+ def test_rewind
83
+ file = JIO.open(*OPEN_ARGS)
84
+ file.write('ABCD')
85
+ file.rewind
86
+ assert_equal 'ABCD', file.read(4)
87
+ ensure
88
+ assert file.close
89
+ end
90
+
91
+ def test_tell
92
+ file = JIO.open(*OPEN_ARGS)
93
+ file.write('ABCD')
94
+ assert_equal 4, file.tell
95
+ ensure
96
+ assert file.close
97
+ end
98
+
99
+ def test_eof_p
100
+ file = JIO.open(*OPEN_ARGS)
101
+ file.write('ABCD')
102
+ assert file.eof?
103
+ file.rewind
104
+ assert !file.eof?
105
+ ensure
106
+ assert file.close
107
+ end
108
+
109
+ def test_error
110
+ file = JIO.open(*OPEN_ARGS)
111
+ file.write('ABCD')
112
+ assert !file.error?
113
+ ensure
114
+ assert file.close
115
+ end
116
+ end
@@ -0,0 +1,23 @@
1
+ # encoding: utf-8
2
+
3
+ require File.join(File.dirname(__FILE__), 'helper')
4
+
5
+ class TestJio < JioTestCase
6
+ def test_check
7
+ file = JIO.open(*OPEN_ARGS)
8
+ trans = file.transaction(JIO::J_LINGER)
9
+ trans.write('COMMIT', 0)
10
+ assert trans.commit
11
+ assert trans.committed?
12
+ expected = {:reapplied=>1,
13
+ :invalid=>2,
14
+ :corrupt=>0,
15
+ :total=>3,
16
+ :in_progress=>0,
17
+ :broken=>0}
18
+ assert_equal expected, JIO.check(FILE, 0)
19
+ ensure
20
+ trans.release
21
+ assert file.close
22
+ end
23
+ end
@@ -0,0 +1,111 @@
1
+ # encoding: utf-8
2
+
3
+ require File.join(File.dirname(__FILE__), 'helper')
4
+
5
+ class TestTransaction < JioTestCase
6
+ def test_spawn_transaction
7
+ file = JIO.open(*OPEN_ARGS)
8
+ trans = file.transaction(JIO::J_LINGER)
9
+ assert_instance_of JIO::Transaction, trans
10
+ ensure
11
+ trans.release
12
+ assert file.close
13
+ end
14
+
15
+ def test_spawn_transaction_with_block
16
+ file = JIO.open(*OPEN_ARGS)
17
+ file.transaction(JIO::J_LINGER) do |trans|
18
+ assert_instance_of JIO::Transaction, trans
19
+ trans.write("COMMIT", 0)
20
+ end
21
+ assert_equal "COMMIT", file.read(6)
22
+ ensure
23
+ assert file.close
24
+ end
25
+
26
+ def test_spawn_transaction_with_block_error
27
+ file = JIO.open(*OPEN_ARGS)
28
+ file.transaction(JIO::J_LINGER) do |trans|
29
+ assert_instance_of JIO::Transaction, trans
30
+ trans.write("COMMIT", 0)
31
+ raise "rollback"
32
+ end rescue nil
33
+ assert_not_equal "COMMIT", file.read(6)
34
+ ensure
35
+ assert file.close
36
+ end
37
+
38
+ def test_transaction_views
39
+ file = JIO.open(*OPEN_ARGS)
40
+ trans = file.transaction(JIO::J_LINGER)
41
+ trans.write('COMMIT', 0)
42
+ trans.read(2, 2)
43
+ assert_equal [], trans.views
44
+ assert_equal nil, trans.release
45
+ ensure
46
+ assert file.close
47
+ end
48
+
49
+ def test_commit_transaction
50
+ file = JIO.open(*OPEN_ARGS)
51
+ trans = file.transaction(JIO::J_LINGER)
52
+ trans.write('COMMIT', 0)
53
+ trans.read(2, 2)
54
+ trans.read(2, 4)
55
+ assert_equal [], trans.views
56
+ assert trans.commit
57
+ assert_equal %w(MM IT), trans.views
58
+ ensure
59
+ trans.release
60
+ file.close
61
+ end
62
+
63
+ def test_rollback_transaction
64
+ file = JIO.open(*OPEN_ARGS)
65
+ trans = file.transaction(JIO::J_LINGER)
66
+ trans.write('COMMIT', 0)
67
+ assert trans.commit
68
+ assert trans.rollback
69
+ ensure
70
+ trans.release
71
+ assert file.close
72
+ end
73
+
74
+ def test_transaction_committed_p
75
+ file = JIO.open(*OPEN_ARGS)
76
+ trans = file.transaction(JIO::J_LINGER)
77
+ trans.write('COMMIT', 0)
78
+ assert trans.commit
79
+ assert trans.committed?
80
+ ensure
81
+ trans.release
82
+ assert file.close
83
+ end
84
+
85
+
86
+ def test_transaction_rollbacked_p
87
+ file = JIO.open(*OPEN_ARGS)
88
+ trans = file.transaction(JIO::J_LINGER)
89
+ trans.write('COMMIT', 0)
90
+ assert trans.commit
91
+ assert_equal 'COMMIT', file.read(6)
92
+ assert trans.rollback
93
+ # XXX: try to reproduce a rollbacked state
94
+ assert !trans.rollbacked?
95
+ ensure
96
+ trans.release
97
+ assert file.close
98
+ end
99
+
100
+ def test_transaction_rollbacking_p
101
+ file = JIO.open(*OPEN_ARGS)
102
+ trans = file.transaction(JIO::J_LINGER)
103
+ trans.write('COMMIT', 0)
104
+ assert trans.commit
105
+ assert trans.rollback
106
+ assert !trans.rollbacking?
107
+ ensure
108
+ trans.release
109
+ assert file.close
110
+ end
111
+ end
metadata ADDED
@@ -0,0 +1,90 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: jio
3
+ version: !ruby/object:Gem::Version
4
+ version: '0.1'
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Lourens Naudé
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-08-02 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rake-compiler
16
+ requirement: &70330249254420 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 0.8.1
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: *70330249254420
25
+ description: jio - transactional, journaled file I/O for Ruby
26
+ email:
27
+ - lourens@methodmissing.com
28
+ executables: []
29
+ extensions:
30
+ - ext/jio/extconf.rb
31
+ extra_rdoc_files: []
32
+ files:
33
+ - .gitignore
34
+ - .travis.yml
35
+ - Gemfile
36
+ - Gemfile.lock
37
+ - LICENSE
38
+ - README.rdoc
39
+ - Rakefile
40
+ - ext/jio/extconf.rb
41
+ - ext/jio/file.c
42
+ - ext/jio/file.h
43
+ - ext/jio/jio_ext.c
44
+ - ext/jio/jio_ext.h
45
+ - ext/jio/jio_prelude.h
46
+ - ext/jio/jruby.h
47
+ - ext/jio/rubinius.h
48
+ - ext/jio/ruby18.h
49
+ - ext/jio/ruby19.h
50
+ - ext/jio/transaction.c
51
+ - ext/jio/transaction.h
52
+ - ext/libjio.tar.gz
53
+ - jio.gemspec
54
+ - lib/jio.rb
55
+ - lib/jio/file.rb
56
+ - lib/jio/version.rb
57
+ - test/helper.rb
58
+ - test/test_file.rb
59
+ - test/test_jio.rb
60
+ - test/test_transaction.rb
61
+ homepage: http://github.com/methodmissing/jio
62
+ licenses: []
63
+ post_install_message:
64
+ rdoc_options:
65
+ - --charset=UTF-8
66
+ require_paths:
67
+ - lib
68
+ required_ruby_version: !ruby/object:Gem::Requirement
69
+ none: false
70
+ requirements:
71
+ - - ! '>='
72
+ - !ruby/object:Gem::Version
73
+ version: '0'
74
+ required_rubygems_version: !ruby/object:Gem::Requirement
75
+ none: false
76
+ requirements:
77
+ - - ! '>='
78
+ - !ruby/object:Gem::Version
79
+ version: '0'
80
+ requirements: []
81
+ rubyforge_project:
82
+ rubygems_version: 1.8.10
83
+ signing_key:
84
+ specification_version: 3
85
+ summary: jio - transactional, journaled file I/O for Ruby
86
+ test_files:
87
+ - test/helper.rb
88
+ - test/test_file.rb
89
+ - test/test_jio.rb
90
+ - test/test_transaction.rb