asynchronous 3.0.1 → 4.0.0.pre
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.
- checksums.yaml +5 -13
- data/Gemfile.lock +1 -13
- data/README.md +36 -87
- data/VERSION +1 -1
- data/asynchronous.gemspec +0 -4
- data/examples/async_patterns.rb +17 -14
- data/examples/bootstrap.rb +2 -0
- data/examples/no_zombie_test.rb +5 -2
- data/examples/parallelism.rb +35 -0
- data/lib/async.rb +1 -0
- data/lib/asynchronous.rb +4 -9
- data/lib/asynchronous/concurrency.rb +33 -67
- data/lib/asynchronous/error.rb +8 -0
- data/lib/asynchronous/kernel.rb +18 -17
- data/lib/asynchronous/parallelism.rb +102 -106
- metadata +12 -45
- data/dump/async.rb +0 -4
- data/dump/shared_memory.rb +0 -138
- data/examples/array_of_value_with_native_threads.rb +0 -23
- data/examples/ruby_worker.rb +0 -54
- data/examples/shared_memory1.rb +0 -19
- data/examples/shared_memory2.rb +0 -29
- data/lib/asynchronous/clean_class.rb +0 -14
- data/lib/asynchronous/shared_memory.rb +0 -214
    
        checksums.yaml
    CHANGED
    
    | @@ -1,15 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 | 
            -
             | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
             | 
| 5 | 
            -
              data.tar.gz: !binary |-
         | 
| 6 | 
            -
                OGNlZWE3MjliNGRhMzY3NGEzZTZkMGE4M2Q3NTExZGU0NGY0OWNhMQ==
         | 
| 2 | 
            +
            SHA1:
         | 
| 3 | 
            +
              metadata.gz: 8b9e12c7186a3dc906e14faede2ecab396c1d6d1
         | 
| 4 | 
            +
              data.tar.gz: 6ce4ccbbfe6fd0bbf064e323278fec86ecd3b814
         | 
| 7 5 | 
             
            SHA512:
         | 
| 8 | 
            -
              metadata.gz:  | 
| 9 | 
            -
             | 
| 10 | 
            -
                YjMzN2U3NTBhNjMzNGM4Y2I1ODI1MDBhNTgyMTg2NzQ1YWM5YzM3MDhlNWIw
         | 
| 11 | 
            -
                ZDBiOTlkMjI2MTM4OTcwYTg0YjA3YWNlOTlmZGRhN2E3MWI2NzI=
         | 
| 12 | 
            -
              data.tar.gz: !binary |-
         | 
| 13 | 
            -
                NDRlMmNhODk3NDQ0YjkwNWY4MzJiNDNiMDQwZTg3YjNkNDE5Yzg3ZTQwYTRk
         | 
| 14 | 
            -
                OWNiZWRjZjg1NGMwODhmODE3OGU2NDNhYjQ5M2UwMTI4MzA2NWM4ZDc5OWRj
         | 
| 15 | 
            -
                ZTdhNmUxZTRmMDI5NmZjNmFjYWRiOTIwMGZmYjczNDgxYjU1YmM=
         | 
| 6 | 
            +
              metadata.gz: 69ec170beaa0e9ff62e3044f25aa67f07ef42e7b6f5b1117aad5de72f907e4244a1a58039214db3ad09ac4b93149a3ee4902ed444104968daaabc67a4856e3c6
         | 
| 7 | 
            +
              data.tar.gz: 337e7edc8238f24a442f79f33ee265fbb4d51856e9bfa755a9ae41d4f21eaea4d0d855f045a64e0b9f8e1aed1c1482e83c58efc2aa0b464fb4e26c4be20b1f3f
         | 
    
        data/Gemfile.lock
    CHANGED
    
    | @@ -1,26 +1,14 @@ | |
| 1 1 | 
             
            PATH
         | 
| 2 2 | 
             
              remote: .
         | 
| 3 3 | 
             
              specs:
         | 
| 4 | 
            -
                asynchronous ( | 
| 5 | 
            -
                  process_shared
         | 
| 4 | 
            +
                asynchronous (4.0.0.pre)
         | 
| 6 5 |  | 
| 7 6 | 
             
            GEM
         | 
| 8 7 | 
             
              remote: http://rubygems.org/
         | 
| 9 8 | 
             
              specs:
         | 
| 10 | 
            -
                columnize (0.3.6)
         | 
| 11 | 
            -
                debugger (1.6.2)
         | 
| 12 | 
            -
                  columnize (>= 0.3.1)
         | 
| 13 | 
            -
                  debugger-linecache (~> 1.2.0)
         | 
| 14 | 
            -
                  debugger-ruby_core_source (~> 1.2.3)
         | 
| 15 | 
            -
                debugger-linecache (1.2.0)
         | 
| 16 | 
            -
                debugger-ruby_core_source (1.2.3)
         | 
| 17 | 
            -
                ffi (1.9.3)
         | 
| 18 | 
            -
                process_shared (0.2.0)
         | 
| 19 | 
            -
                  ffi (~> 1.0)
         | 
| 20 9 |  | 
| 21 10 | 
             
            PLATFORMS
         | 
| 22 11 | 
             
              ruby
         | 
| 23 12 |  | 
| 24 13 | 
             
            DEPENDENCIES
         | 
| 25 14 | 
             
              asynchronous!
         | 
| 26 | 
            -
              debugger
         | 
    
        data/README.md
    CHANGED
    
    | @@ -40,7 +40,7 @@ Like parsing (in some case) | |
| 40 40 |  | 
| 41 41 | 
             
            ```ruby
         | 
| 42 42 |  | 
| 43 | 
            -
             | 
| 43 | 
            +
            thr = async :parallelism do
         | 
| 44 44 |  | 
| 45 45 | 
             
              sleep 4
         | 
| 46 46 | 
             
              # remember, everything you
         | 
| @@ -51,8 +51,8 @@ calculation = async :parallelism do | |
| 51 51 |  | 
| 52 52 | 
             
            end
         | 
| 53 53 |  | 
| 54 | 
            -
            # to call the value | 
| 55 | 
            -
             | 
| 54 | 
            +
            # to call the value:
         | 
| 55 | 
            +
            thr.value
         | 
| 56 56 |  | 
| 57 57 | 
             
            ```
         | 
| 58 58 |  | 
| @@ -68,74 +68,40 @@ Remember well that GarbageCollector will affect the speed. | |
| 68 68 |  | 
| 69 69 | 
             
            ```ruby
         | 
| 70 70 |  | 
| 71 | 
            -
             | 
| 72 | 
            -
             | 
| 73 | 
            -
             | 
| 71 | 
            +
              thr = async { sleep 3; 4 * 3 }
         | 
| 72 | 
            +
              
         | 
| 73 | 
            +
              # to call the value:
         | 
| 74 | 
            +
              calculation = thr.value
         | 
| 74 75 |  | 
| 75 76 | 
             
            ```
         | 
| 76 77 |  | 
| 77 | 
            -
            ### Shared Memory
         | 
| 78 | 
            -
             | 
| 79 | 
            -
            By default the last value will be returned (OS) in IO.pipe,
         | 
| 80 | 
            -
            but when you need something else, there is the shared_memory!
         | 
| 81 | 
            -
             | 
| 82 | 
            -
            Shared memory is good when you want make a ruby worked on native OS thread ,
         | 
| 83 | 
            -
            but need to update data back at the mother process.
         | 
| 84 | 
            -
             | 
| 85 | 
            -
            the usecase is simple like that:
         | 
| 86 | 
            -
            ```ruby
         | 
| 87 | 
            -
             | 
| 88 | 
            -
            SharedMemory.anything_you_want_use_as_variable_name= {:some=>:object}
         | 
| 89 | 
            -
            SharedMemory.anything_you_want_use_as_variable_name #> {:some=>:object}
         | 
| 90 | 
            -
             | 
| 91 | 
            -
            # or
         | 
| 92 | 
            -
             | 
| 93 | 
            -
            shared_memory.anything_you_want_use_as_variable_name #> {:some=>:object}
         | 
| 94 | 
            -
             | 
| 95 | 
            -
            ```
         | 
| 96 | 
            -
             | 
| 97 | 
            -
            by default i set the memory allocation to 16Mb because it common usecase to me (MongoDB),
         | 
| 98 | 
            -
            but feel free to change!:
         | 
| 99 | 
            -
            ```ruby
         | 
| 100 | 
            -
             | 
| 101 | 
            -
            Asynchronous.memory_allocation_size= 1024 #INT!
         | 
| 102 | 
            -
             | 
| 103 | 
            -
            ```
         | 
| 104 | 
            -
             | 
| 105 | 
            -
            ## making shared memory obj static (constant)
         | 
| 106 | 
            -
             | 
| 107 | 
            -
            you can set a shared memory obj to be static if you dont want it to be changed later on
         | 
| 108 | 
            -
            ```ruby
         | 
| 109 | 
            -
            shared_memory.test_value= Array.new.push(:something)
         | 
| 110 | 
            -
            Asynchronous.static_variables.push :test_value
         | 
| 111 | 
            -
            shared_memory.test_value= Array.new #> this wont happen
         | 
| 112 | 
            -
            ```
         | 
| 113 | 
            -
             | 
| 114 | 
            -
             | 
| 115 78 | 
             
            ### Example
         | 
| 116 79 |  | 
| 117 | 
            -
             | 
| 118 | 
            -
             | 
| 119 | 
            -
             | 
| 120 | 
            -
             | 
| 121 | 
            -
            # you CANT modify the objects in memory only in sharedmemories,
         | 
| 122 | 
            -
            # the normal variables will only be copy on write modify
         | 
| 123 | 
            -
            # This is ideal for big operations where you need do a big process
         | 
| 124 | 
            -
            # w/o the fear of the Garbage collector slowness or the GIL lock
         | 
| 125 | 
            -
            # when you need to update objects in the memory use SharedMemory
         | 
| 126 | 
            -
            #
         | 
| 127 | 
            -
            # Remember! if the hardware only got 1 cpu, it will be like a harder
         | 
| 128 | 
            -
            # to use concurrency with an expensive memory allocation
         | 
| 129 | 
            -
            calculation = async :OS do
         | 
| 80 | 
            +
            you can use simple :p or :parallelism as nametag
         | 
| 81 | 
            +
            remember :parallelism is all about real OS thread case, 
         | 
| 82 | 
            +
            so you CANT modify the objects in the memory,
         | 
| 83 | 
            +
            the normal variables will only be copy on write modify
         | 
| 130 84 |  | 
| 131 | 
            -
             | 
| 132 | 
            -
             | 
| 85 | 
            +
            This is ideal for big operations where you need do a big process
         | 
| 86 | 
            +
            w/o the fear of the Garbage collector slowness or the GIL lock
         | 
| 87 | 
            +
            when you need to update objects in the memory use SharedMemory
         | 
| 133 88 |  | 
| 134 | 
            -
             | 
| 89 | 
            +
            Remember! if the hardware only got 1 cpu, it will be like a harder
         | 
| 90 | 
            +
            to use concurrency with an expensive memory allocation
         | 
| 135 91 |  | 
| 136 | 
            -
             | 
| 92 | 
            +
            ```ruby
         | 
| 137 93 |  | 
| 138 | 
            -
             | 
| 94 | 
            +
              thr = async :OS do
         | 
| 95 | 
            +
              
         | 
| 96 | 
            +
                sleep 4
         | 
| 97 | 
            +
                4 * 5
         | 
| 98 | 
            +
              
         | 
| 99 | 
            +
              end
         | 
| 100 | 
            +
              
         | 
| 101 | 
            +
              calculation = thr.value
         | 
| 102 | 
            +
              calculation += 1
         | 
| 103 | 
            +
              
         | 
| 104 | 
            +
              puts calculation
         | 
| 139 105 |  | 
| 140 106 | 
             
            ```
         | 
| 141 107 |  | 
| @@ -145,32 +111,15 @@ there are other examples that you can check in the exampels folder | |
| 145 111 | 
             
            ### known bugs
         | 
| 146 112 |  | 
| 147 113 | 
             
            In rare case when you get object_buffer error
         | 
| 148 | 
            -
            * use . | 
| 114 | 
            +
            * use .join method on the async variable
         | 
| 149 115 |  | 
| 150 116 | 
             
            ```ruby
         | 
| 151 | 
            -
            calculation = async :OS do
         | 
| 152 | 
            -
              sleep 4
         | 
| 153 | 
            -
              4 * 5
         | 
| 154 | 
            -
            end
         | 
| 155 117 |  | 
| 156 | 
            -
             | 
| 157 | 
            -
             | 
| 158 | 
            -
             | 
| 159 | 
            -
             | 
| 160 | 
            -
             | 
| 161 | 
            -
             | 
| 162 | 
            -
             | 
| 163 | 
            -
            SharedMemory objects not updating on chain method obj manipulation
         | 
| 164 | 
            -
             | 
| 165 | 
            -
            ```ruby
         | 
| 166 | 
            -
            shared_memory.var= {'jobs'=>[]}
         | 
| 118 | 
            +
              thr = async :OS do
         | 
| 119 | 
            +
                sleep 4
         | 
| 120 | 
            +
                4 * 5
         | 
| 121 | 
            +
              end
         | 
| 122 | 
            +
              
         | 
| 123 | 
            +
              thr.join #> thr
         | 
| 167 124 |  | 
| 168 | 
            -
             | 
| 169 | 
            -
             | 
| 170 | 
            -
            workaround is like that:
         | 
| 171 | 
            -
             | 
| 172 | 
            -
            local_variable= {'jobs'=>[]}
         | 
| 173 | 
            -
            local_variable['jobs'].push('data')
         | 
| 174 | 
            -
             | 
| 175 | 
            -
            shared_memory.var= local_variable
         | 
| 176 | 
            -
            ```
         | 
| 125 | 
            +
            ```
         | 
    
        data/VERSION
    CHANGED
    
    | @@ -1 +1 @@ | |
| 1 | 
            -
             | 
| 1 | 
            +
            4.0.0.pre
         | 
    
        data/asynchronous.gemspec
    CHANGED
    
    
    
        data/examples/async_patterns.rb
    CHANGED
    
    | @@ -1,12 +1,12 @@ | |
| 1 1 | 
             
            # Require Gemfile gems
         | 
| 2 | 
            -
            require_relative  | 
| 2 | 
            +
            require_relative 'bootstrap'
         | 
| 3 3 |  | 
| 4 4 | 
             
            # you can use simple :c also instead of :concurrency
         | 
| 5 5 | 
             
            # remember :concurrency is all about GIL case, so
         | 
| 6 6 | 
             
            # you can modify the objects in memory
         | 
| 7 7 | 
             
            # This is ideal for little operations in simultaneously or
         | 
| 8 8 | 
             
            # when you need to update objects in the memory
         | 
| 9 | 
            -
             | 
| 9 | 
            +
            thr1 = async :concurrency do
         | 
| 10 10 |  | 
| 11 11 | 
             
              sleep 2
         | 
| 12 12 | 
             
              4 * 2
         | 
| @@ -14,22 +14,24 @@ calculation = async :concurrency do | |
| 14 14 | 
             
            end
         | 
| 15 15 | 
             
            puts "hello concurrency"
         | 
| 16 16 |  | 
| 17 | 
            -
             | 
| 17 | 
            +
            calculation1 = thr1.value
         | 
| 18 | 
            +
            calculation1 += 1
         | 
| 18 19 |  | 
| 19 | 
            -
            puts  | 
| 20 | 
            +
            puts calculation1
         | 
| 20 21 |  | 
| 21 22 | 
             
            #>--------------------------------------------------
         | 
| 22 23 | 
             
            # or you can use simple {} without sym and this will be by default a
         | 
| 23 24 | 
             
            # :concurrency pattern
         | 
| 24 25 |  | 
| 25 | 
            -
             | 
| 26 | 
            +
            thr2 = async { sleep 3; 4 * 3 }
         | 
| 26 27 |  | 
| 27 28 | 
             
            puts "hello simple concurrency"
         | 
| 28 29 |  | 
| 29 | 
            -
             | 
| 30 | 
            +
            calculation2 = thr2.value
         | 
| 31 | 
            +
            calculation2 += 1
         | 
| 30 32 |  | 
| 31 33 | 
             
            # remember you have to use  to cal the return value from the code block!
         | 
| 32 | 
            -
            puts  | 
| 34 | 
            +
            puts calculation2
         | 
| 33 35 |  | 
| 34 36 |  | 
| 35 37 | 
             
            #>--------------------------------------------------
         | 
| @@ -41,7 +43,7 @@ puts calculation | |
| 41 43 | 
             
            # This is ideal for big operations where you need do a big process
         | 
| 42 44 | 
             
            # w/o the fear of the Garbage collector slowness or the GIL lock
         | 
| 43 45 | 
             
            # when you need to update objects in the memory use SharedMemory
         | 
| 44 | 
            -
             | 
| 46 | 
            +
            thr3 = async :parallelism do
         | 
| 45 47 |  | 
| 46 48 | 
             
              sleep 4
         | 
| 47 49 | 
             
              4 * 5
         | 
| @@ -49,16 +51,17 @@ calculation = async :parallelism do | |
| 49 51 | 
             
            end
         | 
| 50 52 | 
             
            puts "hello parallelism"
         | 
| 51 53 |  | 
| 52 | 
            -
             | 
| 54 | 
            +
            calculation3 = thr3.value
         | 
| 55 | 
            +
            calculation3 += 1
         | 
| 53 56 |  | 
| 54 | 
            -
            puts  | 
| 57 | 
            +
            puts calculation3
         | 
| 55 58 |  | 
| 56 59 | 
             
            #>--------------------------------------------------
         | 
| 57 60 |  | 
| 58 61 | 
             
            # more complex way
         | 
| 59 62 |  | 
| 60 63 | 
             
            puts "mixed usecase with arrays as return obj"
         | 
| 61 | 
            -
             | 
| 64 | 
            +
            thr4 = async :parallelism do
         | 
| 62 65 |  | 
| 63 66 | 
             
              sleep 4
         | 
| 64 67 | 
             
              # some big database processing brutal memory eater stuff
         | 
| @@ -66,10 +69,10 @@ calc1 = async :parallelism do | |
| 66 69 |  | 
| 67 70 | 
             
            end
         | 
| 68 71 |  | 
| 69 | 
            -
             | 
| 72 | 
            +
            thr5 = async {
         | 
| 70 73 | 
             
              [5+1,"sup!"]
         | 
| 71 74 | 
             
            }
         | 
| 72 75 |  | 
| 73 | 
            -
            puts calc1 ==  | 
| 74 | 
            -
            puts ( | 
| 76 | 
            +
            puts 'calc1 is eql calc2:',thr4.value == thr5.value
         | 
| 77 | 
            +
            puts (thr4.value+thr5.value).inspect
         | 
| 75 78 |  | 
    
        data/examples/no_zombie_test.rb
    CHANGED
    
    | @@ -1,10 +1,11 @@ | |
| 1 | 
            -
            require_relative  | 
| 1 | 
            +
            require_relative 'bootstrap'
         | 
| 2 2 |  | 
| 3 | 
            -
             | 
| 3 | 
            +
            thr = async :parallelism do
         | 
| 4 4 |  | 
| 5 5 | 
             
              # Zombie!
         | 
| 6 6 | 
             
              loop do
         | 
| 7 7 | 
             
                sleep 1
         | 
| 8 | 
            +
                puts "brains(#{$$})"
         | 
| 8 9 | 
             
              end
         | 
| 9 10 | 
             
              # inf loop
         | 
| 10 11 | 
             
              #
         | 
| @@ -13,12 +14,14 @@ end | |
| 13 14 |  | 
| 14 15 | 
             
            puts $$
         | 
| 15 16 | 
             
            Thread.new do
         | 
| 17 | 
            +
             | 
| 16 18 | 
             
              sleep 5
         | 
| 17 19 |  | 
| 18 20 | 
             
              # this want to demonstrate that,
         | 
| 19 21 | 
             
              # if the main process is killed,
         | 
| 20 22 | 
             
              # you wont leave zombies behind!
         | 
| 21 23 | 
             
              system "kill -9 #{$$}"
         | 
| 24 | 
            +
             | 
| 22 25 | 
             
            end
         | 
| 23 26 |  | 
| 24 27 | 
             
            loop do
         | 
| @@ -0,0 +1,35 @@ | |
| 1 | 
            +
            require_relative 'bootstrap'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            async1= async :OS do
         | 
| 4 | 
            +
              1000000*5
         | 
| 5 | 
            +
            end
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            async2= async :OS do
         | 
| 8 | 
            +
             | 
| 9 | 
            +
              var = ("!" * 1000000)
         | 
| 10 | 
            +
              puts "the superHuge String length in the pipe is: #{var.length}"
         | 
| 11 | 
            +
             | 
| 12 | 
            +
              var
         | 
| 13 | 
            +
            end
         | 
| 14 | 
            +
             | 
| 15 | 
            +
            async2_error= async :OS do
         | 
| 16 | 
            +
             | 
| 17 | 
            +
              raise(SystemExit)
         | 
| 18 | 
            +
              puts 'never happen, to system error happened!'
         | 
| 19 | 
            +
             | 
| 20 | 
            +
            end
         | 
| 21 | 
            +
             | 
| 22 | 
            +
            async3= async :OS do
         | 
| 23 | 
            +
              1000000*5.0
         | 
| 24 | 
            +
            end
         | 
| 25 | 
            +
             | 
| 26 | 
            +
            begin
         | 
| 27 | 
            +
              async2_error.value
         | 
| 28 | 
            +
            rescue Exception => ex
         | 
| 29 | 
            +
              puts "\n",'when error happen:',ex
         | 
| 30 | 
            +
            end
         | 
| 31 | 
            +
             | 
| 32 | 
            +
            puts "\n",'result length based on string form:'
         | 
| 33 | 
            +
            puts async1.value.to_s.length
         | 
| 34 | 
            +
            puts async2.value.to_s.length
         | 
| 35 | 
            +
            puts async3.value.to_s.length
         | 
    
        data/lib/async.rb
    ADDED
    
    | @@ -0,0 +1 @@ | |
| 1 | 
            +
            require 'asynchronous'
         | 
    
        data/lib/asynchronous.rb
    CHANGED
    
    | @@ -1,12 +1,7 @@ | |
| 1 1 | 
             
            #encoding: UTF-8
         | 
| 2 2 | 
             
            module Asynchronous
         | 
| 3 | 
            -
             | 
| 4 | 
            -
              require ' | 
| 5 | 
            -
             | 
| 6 | 
            -
              require  | 
| 7 | 
            -
              require File.join(File.dirname(__FILE__),"asynchronous","concurrency")
         | 
| 8 | 
            -
              require File.join(File.dirname(__FILE__),"asynchronous","parallelism")
         | 
| 9 | 
            -
              require File.join(File.dirname(__FILE__),"asynchronous","shared_memory")
         | 
| 10 | 
            -
              require File.join(File.dirname(__FILE__),"asynchronous","kernel")
         | 
| 11 | 
            -
             | 
| 3 | 
            +
              require 'asynchronous/error'
         | 
| 4 | 
            +
              require 'asynchronous/concurrency'
         | 
| 5 | 
            +
              require 'asynchronous/parallelism'
         | 
| 6 | 
            +
              require 'asynchronous/kernel'
         | 
| 12 7 | 
             
            end
         | 
| @@ -1,78 +1,44 @@ | |
| 1 | 
            -
             | 
| 2 | 
            -
             | 
| 3 | 
            -
             | 
| 4 | 
            -
             | 
| 5 | 
            -
             | 
| 6 | 
            -
             | 
| 7 | 
            -
             | 
| 8 | 
            -
               | 
| 9 | 
            -
             | 
| 10 | 
            -
                 | 
| 11 | 
            -
             | 
| 12 | 
            -
             | 
| 13 | 
            -
             | 
| 14 | 
            -
             | 
| 15 | 
            -
             | 
| 1 | 
            +
            # you can use simple :c also instead of :concurrency
         | 
| 2 | 
            +
            # remember :concurrency is all about GIL case, so
         | 
| 3 | 
            +
            # you can modify the objects in memory
         | 
| 4 | 
            +
            # This is ideal for little operations in simultaneously or
         | 
| 5 | 
            +
            # when you need to update objects in the memory
         | 
| 6 | 
            +
            class Asynchronous::Concurrency
         | 
| 7 | 
            +
             | 
| 8 | 
            +
              def initialize(&block)
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                @rescue_state= nil
         | 
| 11 | 
            +
                @try_count = 0
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                begin
         | 
| 14 | 
            +
                  @value= nil
         | 
| 15 | 
            +
                  @thread ||= ::Thread.new { block.call }
         | 
| 16 | 
            +
                  @rescue_state= nil
         | 
| 17 | 
            +
                rescue ThreadError
         | 
| 18 | 
            +
                  @rescue_state ||= true
         | 
| 19 | 
            +
                  @try_count += 1
         | 
| 20 | 
            +
                  if 3 <= @try_count
         | 
| 21 | 
            +
                    @value= block.call
         | 
| 16 22 | 
             
                    @rescue_state= nil
         | 
| 17 | 
            -
                   | 
| 18 | 
            -
                     | 
| 19 | 
            -
                     | 
| 20 | 
            -
                    if 3 <= @try_count
         | 
| 21 | 
            -
                      @value= callable.call
         | 
| 22 | 
            -
                      @rescue_state= nil
         | 
| 23 | 
            -
                    else
         | 
| 24 | 
            -
                      sleep 5
         | 
| 25 | 
            -
                      retry
         | 
| 26 | 
            -
                    end
         | 
| 23 | 
            +
                  else
         | 
| 24 | 
            +
                    sleep 5
         | 
| 25 | 
            +
                    retry
         | 
| 27 26 | 
             
                  end
         | 
| 28 27 | 
             
                end
         | 
| 29 28 |  | 
| 30 | 
            -
             | 
| 31 | 
            -
             | 
| 32 | 
            -
                  if @value.nil?
         | 
| 33 | 
            -
                    until @rescue_state.nil?
         | 
| 34 | 
            -
                      sleep 1
         | 
| 35 | 
            -
                    end
         | 
| 36 | 
            -
                    @value= @thread.value
         | 
| 37 | 
            -
                  end
         | 
| 38 | 
            -
             | 
| 39 | 
            -
                  return @value
         | 
| 40 | 
            -
             | 
| 41 | 
            -
                end
         | 
| 42 | 
            -
             | 
| 43 | 
            -
                def asynchronous_set_value(obj)
         | 
| 44 | 
            -
                  @value= obj
         | 
| 45 | 
            -
                end
         | 
| 46 | 
            -
                alias :asynchronous_set_value= :asynchronous_set_value
         | 
| 47 | 
            -
             | 
| 48 | 
            -
                def synchronize
         | 
| 49 | 
            -
                  asynchronous_get_value
         | 
| 50 | 
            -
                end
         | 
| 51 | 
            -
                alias :sync :synchronize
         | 
| 52 | 
            -
             | 
| 53 | 
            -
                def method_missing(method, *args)
         | 
| 54 | 
            -
             | 
| 55 | 
            -
                  new_value= asynchronous_get_value
         | 
| 56 | 
            -
             | 
| 57 | 
            -
                  begin
         | 
| 58 | 
            -
                    original_value= new_value.dup
         | 
| 59 | 
            -
                  rescue ::TypeError
         | 
| 60 | 
            -
                    original_value= new_value
         | 
| 61 | 
            -
                  end
         | 
| 29 | 
            +
              end
         | 
| 62 30 |  | 
| 63 | 
            -
             | 
| 64 | 
            -
             | 
| 65 | 
            -
             | 
| 31 | 
            +
              def join
         | 
| 32 | 
            +
                if @value.nil?
         | 
| 33 | 
            +
                  until @rescue_state.nil?
         | 
| 34 | 
            +
                    sleep 1
         | 
| 66 35 | 
             
                  end
         | 
| 67 | 
            -
             | 
| 68 | 
            -
                  return return_value
         | 
| 69 | 
            -
             | 
| 36 | 
            +
                  @value= @thread.value
         | 
| 70 37 | 
             
                end
         | 
| 38 | 
            +
              end
         | 
| 71 39 |  | 
| 72 | 
            -
             | 
| 73 | 
            -
                 | 
| 74 | 
            -
                #end
         | 
| 75 | 
            -
             | 
| 40 | 
            +
              def value
         | 
| 41 | 
            +
                join; @value
         | 
| 76 42 | 
             
              end
         | 
| 77 43 |  | 
| 78 44 | 
             
            end
         |