This repository is private.
All pages are served over SSL and all pushing and pulling is done over SSH.
No one may fork, clone, or view it unless they are added as a member.
Every repository with this icon (
) is private.
Every repository with this icon (
This repository is public.
Anyone may fork, clone, or view it.
Every repository with this icon (
) is public.
Every repository with this icon (
commit 6dc7ddaac0a48e20d09c3aa93f66b485b06d902c
tree f20a82f205f4607fdf936dc2e0bfd3e32027918a
parent ba398122f154b4a5186f6ad687ad1adb5a936919
tree f20a82f205f4607fdf936dc2e0bfd3e32027918a
parent ba398122f154b4a5186f6ad687ad1adb5a936919
| 66a29ece » | sam | 2008-05-07 | 1 | require 'set' | |
| 2 | |||||
| 32686eda » | sam | 2008-05-06 | 3 | class Object | |
| 4 | |||||
| 5 | module Pooling | ||||
| 6 | |||||
| 721c5d3b » | sam | 2008-05-07 | 7 | class MustImplementDisposeError < StandardError | |
| 8 | end | ||||
| 9 | |||||
| 32686eda » | sam | 2008-05-06 | 10 | def self.included(target) | |
| 11 | target.extend(ClassMethods) | ||||
| 12 | end | ||||
| 13 | |||||
| 069209c8 » | sam | 2008-05-07 | 14 | def release | |
| 66a29ece » | sam | 2008-05-07 | 15 | @__pool.release(self) | |
| 16 | end | ||||
| 069209c8 » | sam | 2008-05-07 | 17 | ||
| 32686eda » | sam | 2008-05-06 | 18 | class Pools | |
| 19 | |||||
| 20 | attr_reader :type | ||||
| 6dc7ddaa » | sam | 2008-05-07 | 21 | attr_accessor :size | |
| 32686eda » | sam | 2008-05-06 | 22 | ||
| 6dc7ddaa » | sam | 2008-05-07 | 23 | def initialize(type, size = 4) | |
| 32686eda » | sam | 2008-05-06 | 24 | @type = type | |
| 6dc7ddaa » | sam | 2008-05-07 | 25 | @size = size | |
| 26 | @pools = Hash.new { |h,k| h[k] = Pool.new(@size, @type, k) } | ||||
| 32686eda » | sam | 2008-05-06 | 27 | end | |
| 28 | |||||
| 29 | def flush! | ||||
| 30 | @pools.each_pair do |args,pool| | ||||
| 31 | pool.flush! | ||||
| 32 | end | ||||
| 33 | |||||
| 34 | @pools.clear | ||||
| 35 | self | ||||
| 36 | end | ||||
| 37 | |||||
| 38 | def [](*args) | ||||
| 39 | @pools[*args] | ||||
| 40 | end | ||||
| 41 | |||||
| 42 | class Pool | ||||
| 43 | |||||
| 44 | attr_reader :type, :available, :reserved | ||||
| 45 | |||||
| 6dc7ddaa » | sam | 2008-05-07 | 46 | def initialize(size, type, initializer) | |
| 47 | @size = size | ||||
| 32686eda » | sam | 2008-05-06 | 48 | @type = type | |
| 66a29ece » | sam | 2008-05-07 | 49 | @initializer = initializer | |
| 50 | @lock = Mutex.new | ||||
| 32686eda » | sam | 2008-05-06 | 51 | @available = [] | |
| 66a29ece » | sam | 2008-05-07 | 52 | @reserved = Set.new | |
| 32686eda » | sam | 2008-05-06 | 53 | end | |
| 54 | |||||
| 55 | def flush! | ||||
| 6dc7ddaa » | sam | 2008-05-07 | 56 | @lock.synchronize do | |
| 57 | reserved.each do |instance| | ||||
| 58 | if @reserved.delete?(instance) | ||||
| 59 | @available << instance | ||||
| 60 | end | ||||
| 61 | end | ||||
| 32686eda » | sam | 2008-05-06 | 62 | ||
| 6dc7ddaa » | sam | 2008-05-07 | 63 | available.each do |instance| | |
| 64 | instance.dispose | ||||
| 65 | end | ||||
| 32686eda » | sam | 2008-05-06 | 66 | ||
| 6dc7ddaa » | sam | 2008-05-07 | 67 | @available = [] | |
| 68 | @reserved = Set.new | ||||
| 69 | end | ||||
| 32686eda » | sam | 2008-05-06 | 70 | end | |
| 069209c8 » | sam | 2008-05-07 | 71 | ||
| 66a29ece » | sam | 2008-05-07 | 72 | def new | |
| 6dc7ddaa » | sam | 2008-05-07 | 73 | if @available.empty? | |
| 74 | @lock.synchronize do | ||||
| 75 | instance = nil | ||||
| 76 | |||||
| 77 | if @available.empty? | ||||
| 78 | if @reserved.size < @size | ||||
| 79 | instance = @type.allocate | ||||
| 80 | instance.send(:initialize, *@initializer) | ||||
| 81 | at_exit { instance.dispose } | ||||
| 82 | instance.instance_variable_set("@__pool", self) | ||||
| 83 | else | ||||
| 84 | # until(instance) do | ||||
| 85 | # TODO: Need to wait for an instance to become available, | ||||
| 86 | # but to do that we need to not use a synchronization block. | ||||
| 87 | # end | ||||
| 88 | |||||
| 89 | instance = @type.allocate | ||||
| 90 | instance.send(:initialize, *@initializer) | ||||
| 91 | at_exit { instance.dispose } | ||||
| 92 | instance.instance_variable_set("@__pool", self) | ||||
| 93 | end | ||||
| 94 | else | ||||
| 95 | instance = @available.pop | ||||
| 96 | end | ||||
| 97 | |||||
| 98 | @reserved << instance | ||||
| 99 | instance | ||||
| 069209c8 » | sam | 2008-05-07 | 100 | end | |
| 6dc7ddaa » | sam | 2008-05-07 | 101 | else | |
| 102 | aquire_instance! | ||||
| 069209c8 » | sam | 2008-05-07 | 103 | end | |
| 104 | end | ||||
| 105 | |||||
| 66a29ece » | sam | 2008-05-07 | 106 | def release(instance) | |
| 107 | @lock.synchronize do | ||||
| 108 | if @reserved.delete?(instance) | ||||
| 109 | @available << instance | ||||
| 069209c8 » | sam | 2008-05-07 | 110 | end | |
| 111 | end | ||||
| 112 | return nil | ||||
| 113 | end | ||||
| 114 | |||||
| 115 | private | ||||
| 6dc7ddaa » | sam | 2008-05-07 | 116 | def aquire_instance! | |
| 117 | instance = nil | ||||
| 118 | |||||
| 119 | @lock.synchronize do | ||||
| 120 | instance = @available.pop | ||||
| 121 | raise StandardError.new("Concurrency Error!") unless instance | ||||
| 122 | @reserved << instance | ||||
| 123 | end | ||||
| 124 | |||||
| 125 | instance | ||||
| 069209c8 » | sam | 2008-05-07 | 126 | end | |
| 32686eda » | sam | 2008-05-06 | 127 | end | |
| 128 | end | ||||
| 129 | |||||
| 130 | module ClassMethods | ||||
| 721c5d3b » | sam | 2008-05-07 | 131 | ||
| 132 | def new(*args) | ||||
| 133 | unless instance_methods.include?("dispose") | ||||
| 134 | raise MustImplementDisposeError.new("#{self.name} must implement a `dispose' instance-method.") | ||||
| 135 | end | ||||
| 069209c8 » | sam | 2008-05-07 | 136 | ||
| 66a29ece » | sam | 2008-05-07 | 137 | pools[*args].new | |
| 069209c8 » | sam | 2008-05-07 | 138 | # uri = uri.is_a?(String) ? Addressable::URI::parse(uri) : uri | |
| 139 | # DataObjects.const_get(uri.scheme.capitalize)::Connection.acquire(uri) | ||||
| 721c5d3b » | sam | 2008-05-07 | 140 | end | |
| 141 | |||||
| 32686eda » | sam | 2008-05-06 | 142 | def pools | |
| 143 | @pools ||= Pools.new(self) | ||||
| 144 | end | ||||
| 145 | end | ||||
| 146 | |||||
| 147 | end | ||||
| 148 | |||||
| 149 | end | ||||







