manana 0.1.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 4260f96ef0f5a33bc8a66db747e1759388927bc1
4
+ data.tar.gz: 9cb8a090b23e690c940fdefbbd1ababa97c41fd7
5
+ SHA512:
6
+ metadata.gz: bd56b8099f8cfad6e654fb4c2093d95e583c96dd433d3a690661e63d98c0228337e6c48739feda76a5757a8232ffb90d4bd63785cff5179d90d1181b17ee91a3
7
+ data.tar.gz: 46bcc0990610755a158174ce7715c41c2d70bbd55d7858e289714a013bee6cb4e460bc910f178dab0ec6ef7541089795ab4063401d40d2fd96fdd3b90c9372d7
data/.travis.yml CHANGED
@@ -2,6 +2,7 @@ language: ruby
2
2
  rvm:
3
3
  - 1.9.2
4
4
  - 1.9.3
5
+ - 2.1.5
5
6
  env:
6
7
  global:
7
8
  - "TRAVIS=1"
data/Gemfile CHANGED
@@ -10,10 +10,12 @@ unless ENV["TRAVIS"] == "1"
10
10
  gem 'yard'
11
11
  gem 'redcarpet'
12
12
 
13
- gem 'pry'
14
- gem 'pry-debugger'
15
- gem 'pry-rescue'
16
- gem 'pry-stack_explorer'
13
+ if RUBY_VERSION =~ /^2\./
14
+ gem 'pry-byebug'
15
+ else
16
+ gem 'pry'
17
+ end
18
+
17
19
  end
18
20
 
19
21
  group :samples do
@@ -29,6 +31,5 @@ end
29
31
 
30
32
  # for travis.cl
31
33
  group :test do
32
- gem 'rake'
33
34
  gem 'mocha'
34
35
  end
data/README.md CHANGED
@@ -58,7 +58,7 @@ Or install it yourself as:
58
58
  require 'manana'
59
59
 
60
60
  # initialization...
61
- client = Manana.deferred_init {
61
+ client = Manana.wrap {
62
62
  Weather.setup # web service adapter setup
63
63
  Weather # return the class instance
64
64
  }
@@ -1,3 +1,3 @@
1
1
  class Manana
2
- VERSION = "0.1.0"
2
+ VERSION = "0.5.0"
3
3
  end
data/lib/manana.rb CHANGED
@@ -4,7 +4,7 @@ require "manana/version"
4
4
  # *Manana* lets you defer the initialization of an object until its methods are called.
5
5
  # @example basic usage - see {https://github.com/coldnebo/manana/blob/master/samples/self_healing.rb samples/self_healing.rb}
6
6
  # # initialization...
7
- # client = Manana.deferred_init {
7
+ # client = Manana.wrap {
8
8
  # Weather.setup
9
9
  # Weather
10
10
  # }
@@ -16,50 +16,52 @@ require "manana/version"
16
16
  # }
17
17
  #
18
18
  class Manana
19
-
20
- # wraps an initialization block so that it can be deferred to a later time when object methods are called.
19
+ private_class_method :new
20
+
21
+ # wraps the initialization of an object so that it can be deferred to a later time when object methods are called.
21
22
  # @example wrap an object - see {https://github.com/coldnebo/manana/blob/master/samples/self_healing.rb samples/self_healing.rb}
22
- # client = Manana.deferred_init {
23
+ # client = Manana.wrap {
23
24
  # Weather.setup # initialize the class
24
25
  # Weather # return the Weather class
25
26
  # }
26
27
  #
27
28
  # @param initialization_block [Proc] object initialization. the block must return the object to be wrapped.
28
- # @return [Manana] a wrapped version of the object.
29
- def self.deferred_init(&initialization_block)
30
- Manana.new(&initialization_block)
29
+ # @return [Deferrable] a wrapped version of the object.
30
+ def self.wrap(&initialization_block)
31
+ Deferrable.send(:new,&initialization_block)
31
32
  end
32
33
 
33
- # passes any method call through to the wrapped object after ensuring that the initialization block has
34
- # successfully completed once (setting a valid instance of the object).
35
- # @note Once the initialization block succeeds, it keeps the resulting object instance for subsequent method calls.
36
- #
37
- # @example calling a wrapped object - see {https://github.com/coldnebo/manana/blob/master/samples/self_healing.rb samples/self_healing.rb}
38
- # weather = client.city_weather("02201")
39
- #
40
- def method_missing(method, *args, &block)
41
- instance = safe_get_instance
42
- instance.send(method, *args, &block);
43
- end
44
-
45
- private
34
+ # class that proxies all requests to the wrapped object, ensuring that the object has been correctly initialized first.
35
+ class Deferrable < ::BasicObject
36
+ private_class_method :new
46
37
 
47
- def initialize(&initialization_block)
48
- @mutex = Mutex.new
49
- @deferred_initialization = initialization_block
50
- end
38
+ # passes any method call through to the wrapped object after ensuring that the initialization block has
39
+ # successfully completed once (thereby initializing the wrapped object).
40
+ # @note Once the initialization block succeeds, it keeps the resulting object for subsequent method calls.
41
+ #
42
+ # @example calling a wrapped object - see {https://github.com/coldnebo/manana/blob/master/samples/self_healing.rb samples/self_healing.rb}
43
+ # weather = client.city_weather("02201")
44
+ #
45
+ def method_missing(method, *args, &block)
46
+ _object.send(method, *args, &block);
47
+ end
51
48
 
52
- def safe_get_instance
53
- @mutex.synchronize do
54
- get_instance
49
+ # allows direct access to the wrapped object -- useful for debugging
50
+ # @return [Object] the object being wrapped
51
+ def _object
52
+ @mutex.synchronize do
53
+ if @object.nil?
54
+ @object = @deferred_initialization.call
55
+ end
56
+ @object
57
+ end
55
58
  end
56
- end
57
59
 
58
- def get_instance
59
- if @instance.nil?
60
- @instance = @deferred_initialization.call
60
+ private
61
+ def initialize(&initialization_block)
62
+ @mutex = ::Mutex.new
63
+ @deferred_initialization = initialization_block
61
64
  end
62
- @instance
63
65
  end
64
66
 
65
67
  end
data/manana.gemspec CHANGED
@@ -18,7 +18,7 @@ Gem::Specification.new do |spec|
18
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
19
  spec.require_paths = ["lib"]
20
20
 
21
- spec.add_development_dependency "bundler", "~> 1.3"
21
+ spec.add_development_dependency "bundler"
22
22
  spec.add_development_dependency "rake"
23
23
  spec.add_development_dependency "minitest"
24
24
  end
@@ -31,7 +31,7 @@ end
31
31
 
32
32
  # ------------ initialization code
33
33
 
34
- client = Manana.deferred_init {
34
+ client = Manana.wrap {
35
35
  # exponential backkoff logic in the initialization block
36
36
  retries = 0
37
37
  obj = nil
@@ -44,7 +44,7 @@ mini_death_star = nil
44
44
  puts "[Vader]: requsition a new DeathStar and make it snappy!"
45
45
  # boss said requisitions have to be faster*! Manana to the rescue!
46
46
  puts Benchmark.measure {
47
- mini_death_star = Manana.deferred_init {
47
+ mini_death_star = Manana.wrap {
48
48
  DeathStar.new
49
49
  }
50
50
  }
@@ -47,7 +47,7 @@ end
47
47
 
48
48
  # Before we start, we use Manana to wrap the client setup so that method calls on the client can be self-healing in case of failure.
49
49
  # NOTE: that the caller doesn't have to deal with whether or not this initialization succeeded, they can just call the client methods repeatedly.
50
- client = Manana.deferred_init {
50
+ client = Manana.wrap {
51
51
  Weather.setup
52
52
  Weather
53
53
  }
@@ -0,0 +1,17 @@
1
+ # something like ActiveRecord::Base
2
+ class BaseKlass
3
+
4
+ def self.connected?
5
+ @@connected ||= false
6
+ end
7
+
8
+ def self.establish_connection
9
+ @@connected = true
10
+ end
11
+
12
+ def self.find
13
+ raise "not connected!" unless self.connected?
14
+ [1,2,3]
15
+ end
16
+
17
+ end
@@ -9,6 +9,7 @@ end
9
9
  $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
10
10
  require 'manana'
11
11
 
12
+
12
13
  require 'minitest/autorun'
13
14
  require 'mocha/setup'
14
15
 
data/test/test_manana.rb CHANGED
@@ -33,10 +33,10 @@ class TestManana < Minitest::Test
33
33
  end
34
34
  end
35
35
 
36
- def test_deferred_init
36
+ def test_wrap
37
37
  obj = nil
38
38
  out, err = capture_io do
39
- obj = Manana.deferred_init {
39
+ obj = Manana.wrap {
40
40
  Klass.new
41
41
  }
42
42
  end
@@ -65,11 +65,12 @@ class TestManana < Minitest::Test
65
65
  end
66
66
  end
67
67
 
68
+
68
69
  # https://github.com/coldnebo/manana/issues/1
69
70
  def test_that_init_is_threadsafe
70
71
  Klass.reset
71
72
 
72
- klass = Manana.deferred_init {
73
+ klass = Manana.wrap {
73
74
  sleep(1)
74
75
  Klass.incr
75
76
  Klass
@@ -0,0 +1,42 @@
1
+ require 'minitest_helper'
2
+ require 'base_klass'
3
+
4
+ class TestWithSubclass < Minitest::Test
5
+
6
+ # initialize a very generic example object that does some stuff in initialization and has some instance methods you can call.
7
+ def setup
8
+ BaseKlass.class_variable_set(:@@connected, false)
9
+ end
10
+
11
+ # sanity check
12
+ def test_that_things_work_without_manana
13
+ @subklass = Class.new(BaseKlass)
14
+
15
+ assert_raises RuntimeError do
16
+ res = @subklass.find
17
+ end
18
+
19
+ BaseKlass.establish_connection
20
+
21
+ res = @subklass.find
22
+ refute_empty(res)
23
+
24
+ end
25
+
26
+ def test_wrap
27
+
28
+ @subklass = Manana.wrap {
29
+ unless BaseKlass.connected?
30
+ BaseKlass.establish_connection
31
+ end
32
+ subklass = Class.new(BaseKlass)
33
+ }
34
+
35
+ res = @subklass.find
36
+ refute_empty(res)
37
+ assert(BaseKlass.connected?)
38
+
39
+ end
40
+
41
+
42
+ end
metadata CHANGED
@@ -1,62 +1,55 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: manana
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
5
- prerelease:
4
+ version: 0.5.0
6
5
  platform: ruby
7
6
  authors:
8
7
  - coldnebo
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2013-12-17 00:00:00.000000000 Z
11
+ date: 2015-04-10 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: bundler
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
- - - ~>
17
+ - - ">="
20
18
  - !ruby/object:Gem::Version
21
- version: '1.3'
19
+ version: '0'
22
20
  type: :development
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
- - - ~>
24
+ - - ">="
28
25
  - !ruby/object:Gem::Version
29
- version: '1.3'
26
+ version: '0'
30
27
  - !ruby/object:Gem::Dependency
31
28
  name: rake
32
29
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
30
  requirements:
35
- - - ! '>='
31
+ - - ">="
36
32
  - !ruby/object:Gem::Version
37
33
  version: '0'
38
34
  type: :development
39
35
  prerelease: false
40
36
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
37
  requirements:
43
- - - ! '>='
38
+ - - ">="
44
39
  - !ruby/object:Gem::Version
45
40
  version: '0'
46
41
  - !ruby/object:Gem::Dependency
47
42
  name: minitest
48
43
  requirement: !ruby/object:Gem::Requirement
49
- none: false
50
44
  requirements:
51
- - - ! '>='
45
+ - - ">="
52
46
  - !ruby/object:Gem::Version
53
47
  version: '0'
54
48
  type: :development
55
49
  prerelease: false
56
50
  version_requirements: !ruby/object:Gem::Requirement
57
- none: false
58
51
  requirements:
59
- - - ! '>='
52
+ - - ">="
60
53
  - !ruby/object:Gem::Version
61
54
  version: '0'
62
55
  description: provides a simple way to defer initialization of an object until its
@@ -67,9 +60,9 @@ executables: []
67
60
  extensions: []
68
61
  extra_rdoc_files: []
69
62
  files:
70
- - .gitignore
71
- - .travis.yml
72
- - .yardopts
63
+ - ".gitignore"
64
+ - ".travis.yml"
65
+ - ".yardopts"
73
66
  - Gemfile
74
67
  - LICENSE.txt
75
68
  - README.md
@@ -83,43 +76,40 @@ files:
83
76
  - samples/exponential_backoff.rb
84
77
  - samples/fast_startup.rb
85
78
  - samples/self_healing.rb
79
+ - test/base_klass.rb
86
80
  - test/klass.rb
87
81
  - test/minitest_helper.rb
88
82
  - test/test_manana.rb
83
+ - test/test_with_subclass.rb
89
84
  homepage: https://github.com/coldnebo/manana
90
85
  licenses:
91
86
  - MIT
87
+ metadata: {}
92
88
  post_install_message:
93
89
  rdoc_options: []
94
90
  require_paths:
95
91
  - lib
96
92
  required_ruby_version: !ruby/object:Gem::Requirement
97
- none: false
98
93
  requirements:
99
- - - ! '>='
94
+ - - ">="
100
95
  - !ruby/object:Gem::Version
101
96
  version: '0'
102
- segments:
103
- - 0
104
- hash: -3306959934859244204
105
97
  required_rubygems_version: !ruby/object:Gem::Requirement
106
- none: false
107
98
  requirements:
108
- - - ! '>='
99
+ - - ">="
109
100
  - !ruby/object:Gem::Version
110
101
  version: '0'
111
- segments:
112
- - 0
113
- hash: -3306959934859244204
114
102
  requirements: []
115
103
  rubyforge_project:
116
- rubygems_version: 1.8.25
104
+ rubygems_version: 2.4.3
117
105
  signing_key:
118
- specification_version: 3
106
+ specification_version: 4
119
107
  summary: provides a simple way to defer initialization of an object until its methods
120
108
  are called
121
109
  test_files:
110
+ - test/base_klass.rb
122
111
  - test/klass.rb
123
112
  - test/minitest_helper.rb
124
113
  - test/test_manana.rb
114
+ - test/test_with_subclass.rb
125
115
  has_rdoc: