extlib 0.9.5 → 0.9.6

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of extlib might be problematic. Click here for more details.

@@ -14,19 +14,25 @@ require dir / "object"
14
14
  require dir / "object_space"
15
15
 
16
16
  require dir / "string"
17
+ require dir / "symbol"
17
18
  require dir / "hash"
18
19
  require dir / "mash"
19
20
  require dir / "virtual_file"
20
21
  require dir / "logger"
21
22
  require dir / "time"
23
+ require dir / "datetime"
22
24
 
23
25
  require dir / 'assertions'
24
26
  require dir / 'blank'
27
+ require dir / 'boolean'
25
28
  require dir / 'inflection'
26
29
  require dir / 'lazy_array'
27
30
  require dir / 'module'
31
+ require dir / 'nil'
32
+ require dir / 'numeric'
28
33
  require dir / 'blank'
29
34
  require dir / 'pooling'
30
35
  require dir / 'simple_set'
31
36
  require dir / 'struct'
32
37
  require dir / 'hook'
38
+ require dir / 'symbol'
@@ -0,0 +1,11 @@
1
+ class TrueClass
2
+ def try_dup
3
+ self
4
+ end
5
+ end
6
+
7
+ class FalseClass
8
+ def try_dup
9
+ self
10
+ end
11
+ end
@@ -0,0 +1,9 @@
1
+ class DateTime
2
+ def to_time
3
+ Time.parse self.to_s
4
+ end
5
+
6
+ def to_datetime
7
+ self
8
+ end
9
+ end
@@ -6,6 +6,10 @@ class Module
6
6
  nested_const_lookup(const_name)
7
7
  end
8
8
  end
9
+
10
+ def try_dup
11
+ self
12
+ end
9
13
 
10
14
  private
11
15
 
@@ -0,0 +1,5 @@
1
+ class NilClass
2
+ def try_dup
3
+ self
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ class Numeric
2
+ def try_dup
3
+ self
4
+ end
5
+ end
@@ -129,6 +129,13 @@ class Object
129
129
  end
130
130
  end
131
131
 
132
+ # Override this in a child if it cannot be dup'ed
133
+ #
134
+ # @return <Object>
135
+ def try_dup
136
+ self.dup
137
+ end
138
+
132
139
  # @param arrayish<#include?> Container to check, to see if it includes the object.
133
140
  # @param *more<Array>:: additional args, will be flattened into arrayish
134
141
  #
@@ -141,4 +148,17 @@ class Object
141
148
  arrayish = more.unshift(arrayish) unless more.empty?
142
149
  arrayish.include?(self)
143
150
  end
151
+
152
+ # @note
153
+ # For instances of objects that don't override the #inspect method, there
154
+ # is an encoded hash to uniquely identify the object. This method
155
+ # reproduces this to be used in #inspect in order to keep the same look
156
+ # as well as provide this information.
157
+ # This is inessential, but may be useful.
158
+ #
159
+ # @return <String>
160
+ # Returns the 16-byte encoded hash for the object
161
+ def encoded_hash
162
+ (self.hash * 2).to_s(16)
163
+ end
144
164
  end
@@ -29,19 +29,21 @@ module Extlib
29
29
  @scavenger || begin
30
30
  @scavenger = Thread.new do
31
31
  loop do
32
+ # Sleep before we actually start doing anything.
33
+ # Otherwise we might clean up something we just made
34
+ sleep(scavenger_interval)
32
35
  lock.synchronize do
33
36
  pools.each do |pool|
34
37
  # This is a useful check, but non-essential, and right now it breaks lots of stuff.
35
38
  # if pool.expired?
36
39
  pool.lock.synchronize do
37
- if pool.reserved_count == 0
40
+ if pool.used.size == 0
38
41
  pool.dispose
39
42
  end
40
43
  end
41
44
  # end
42
45
  end
43
46
  end
44
- sleep(scavenger_interval)
45
47
  end # loop
46
48
  end
47
49
 
@@ -65,10 +67,7 @@ module Extlib
65
67
  @lock ||= Mutex.new
66
68
  end
67
69
 
68
- class CrossPoolError < StandardError
69
- end
70
-
71
- class OrphanedObjectError < StandardError
70
+ class InvalidResourceError < StandardError
72
71
  end
73
72
 
74
73
  class ThreadStopError < StandardError
@@ -82,11 +81,16 @@ module Extlib
82
81
 
83
82
  @__pools = Hash.new { |h,k| __pool_lock.synchronize { h[k] = Pool.new(target.pool_size, target, k) } }
84
83
  @__pool_lock = Mutex.new
84
+ @__pool_wait = ConditionVariable.new
85
85
 
86
86
  def self.__pool_lock
87
87
  @__pool_lock
88
88
  end
89
89
 
90
+ def self.__pool_wait
91
+ @__pool_wait
92
+ end
93
+
90
94
  def self.new(*args)
91
95
  @__pools[args].new
92
96
  end
@@ -106,6 +110,9 @@ module Extlib
106
110
  end
107
111
 
108
112
  class Pool
113
+ attr_reader :available
114
+ attr_reader :used
115
+
109
116
  def initialize(max_size, resource, args)
110
117
  raise ArgumentError.new("+max_size+ should be a Fixnum but was #{max_size.inspect}") unless Fixnum === max_size
111
118
  raise ArgumentError.new("+resource+ should be a Class but was #{resource.inspect}") unless Class === resource
@@ -115,44 +122,59 @@ module Extlib
115
122
  @args = args
116
123
 
117
124
  @available = []
118
- @reserved_count = 0
125
+ @used = Set.new
126
+ Extlib::Pooling::append_pool(self)
119
127
  end
120
128
 
121
129
  def lock
122
130
  @resource.__pool_lock
123
131
  end
124
132
 
133
+ def wait
134
+ @resource.__pool_wait
135
+ end
136
+
125
137
  def scavenge_interval
126
138
  @resource.scavenge_interval
127
139
  end
128
140
 
129
141
  def new
130
142
  instance = nil
131
-
132
- lock.synchronize do
133
- instance = acquire
134
- end
135
-
136
- Extlib::Pooling::append_pool(self)
137
-
138
- if instance.nil?
139
- # Account for the current thread, and the pool scavenger.
140
- if ThreadGroup::Default.list.size == 2 && @reserved_count >= @max_size
141
- raise ThreadStopError.new(size)
142
- else
143
- sleep(0.05)
144
- new
143
+ begin
144
+ lock.synchronize do
145
+ if @available.size > 0
146
+ instance = @available.pop
147
+ @used.add instance
148
+ elsif @used.size < @max_size
149
+ instance = @resource.__new(*@args)
150
+ raise InvalidResourceError.new("#{@resource} constructor created a nil object") if instance.nil?
151
+ raise InvalidResourceError.new("#{instance} is already part of the pool") if @used.include? instance
152
+ instance.instance_variable_set(:@__pool, self)
153
+ instance.instance_variable_set(:@__allocated_in_pool, Time.now)
154
+ @used.add instance
155
+ else
156
+ # Let's see whether we have multiple threads
157
+ # If we do, there is a chance we might be released
158
+ # at some point in the future and thus we wait.
159
+ # If there are no other threads, we exhaust the pool
160
+ # here and there is no more hope... So we throw an
161
+ # exception.
162
+ if ThreadGroup::Default.list.size <= 2
163
+ raise ThreadStopError.new(size)
164
+ else
165
+ wait.wait(lock)
166
+ end
167
+ end
145
168
  end
146
- else
147
- instance
148
- end
169
+ end until instance
170
+ instance
149
171
  end
150
172
 
151
173
  def release(instance)
152
174
  lock.synchronize do
153
- instance.instance_variable_set(:@__pool, nil)
154
- @reserved_count -= 1
175
+ @used.delete instance
155
176
  @available.push(instance)
177
+ wait.signal
156
178
  end
157
179
  nil
158
180
  end
@@ -160,18 +182,18 @@ module Extlib
160
182
  def delete(instance)
161
183
  lock.synchronize do
162
184
  instance.instance_variable_set(:@__pool, nil)
163
- @reserved_count -= 1
185
+ used.delete instance
164
186
  end
165
187
  nil
166
188
  end
167
189
 
168
190
  def size
169
- @available.size + @reserved_count
191
+ @used.size + @available.size
170
192
  end
171
193
  alias length size
172
194
 
173
195
  def inspect
174
- "#<Extlib::Pooling::Pool<#{@resource.name}> available=#{@available.size} reserved_count=#{@reserved_count}>"
196
+ "#<Extlib::Pooling::Pool<#{@resource.name}> available=#{@available.size} used=#{@used.size} size=#{@max_size}>"
175
197
  end
176
198
 
177
199
  def flush!
@@ -190,7 +212,7 @@ module Extlib
190
212
  # lock.synchronize do
191
213
  # @available.each do |instance|
192
214
  # if instance.instance_variable_get(:@__allocated_in_pool) + scavenge_interval < Time.now
193
- # instance.dispose
215
+ # instance.release
194
216
  # @available.delete(instance)
195
217
  # end
196
218
  # end
@@ -199,31 +221,6 @@ module Extlib
199
221
  # end
200
222
  # end
201
223
 
202
- def reserved_count
203
- @reserved_count
204
- end
205
-
206
- private
207
-
208
- def acquire
209
- instance = if !@available.empty?
210
- @available.pop
211
- elsif size < @max_size
212
- @resource.__new(*@args)
213
- else
214
- nil
215
- end
216
-
217
- if instance.nil?
218
- instance
219
- else
220
- raise CrossPoolError.new(instance) if instance.instance_variable_get(:@__pool)
221
- @reserved_count += 1
222
- instance.instance_variable_set(:@__pool, self)
223
- instance.instance_variable_set(:@__allocated_in_pool, Time.now)
224
- instance
225
- end
226
- end
227
224
  end
228
225
 
229
226
  def self.scavenger_interval
@@ -0,0 +1,17 @@
1
+ class Symbol
2
+
3
+ def try_dup
4
+ self
5
+ end
6
+
7
+ ##
8
+ # @param o<String, Symbol> The path component to join with the string.
9
+ #
10
+ # @return <String> The original path concatenated with o.
11
+ #
12
+ # @example
13
+ # :merb/"core_ext" #=> "merb/core_ext"
14
+ def /(o)
15
+ File.join(self.to_s, o.to_s)
16
+ end
17
+ end
@@ -9,4 +9,11 @@ class Time
9
9
  self.xmlschema.to_json
10
10
  end
11
11
 
12
+ def to_time
13
+ self
14
+ end
15
+
16
+ def to_datetime
17
+ DateTime.parse self.to_s
18
+ end
12
19
  end
@@ -1,3 +1,3 @@
1
1
  module Extlib
2
- VERSION = "0.9.5"
2
+ VERSION = "0.9.6"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: extlib
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.5
4
+ version: 0.9.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sam Smoot
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2008-08-26 00:00:00 +03:00
12
+ date: 2008-09-09 00:00:00 +03:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -38,7 +38,9 @@ files:
38
38
  - lib/extlib
39
39
  - lib/extlib/assertions.rb
40
40
  - lib/extlib/blank.rb
41
+ - lib/extlib/boolean.rb
41
42
  - lib/extlib/class.rb
43
+ - lib/extlib/datetime.rb
42
44
  - lib/extlib/hash.rb
43
45
  - lib/extlib/hook.rb
44
46
  - lib/extlib/inflection.rb
@@ -46,6 +48,8 @@ files:
46
48
  - lib/extlib/logger.rb
47
49
  - lib/extlib/mash.rb
48
50
  - lib/extlib/module.rb
51
+ - lib/extlib/nil.rb
52
+ - lib/extlib/numeric.rb
49
53
  - lib/extlib/object.rb
50
54
  - lib/extlib/object_space.rb
51
55
  - lib/extlib/pathname.rb
@@ -54,6 +58,7 @@ files:
54
58
  - lib/extlib/simple_set.rb
55
59
  - lib/extlib/string.rb
56
60
  - lib/extlib/struct.rb
61
+ - lib/extlib/symbol.rb
57
62
  - lib/extlib/tasks
58
63
  - lib/extlib/tasks/release.rb
59
64
  - lib/extlib/time.rb