brew vendor-gems: commit updates.
This commit is contained in:
parent
115976c16e
commit
25dcb7e675
@ -3,7 +3,7 @@ require 'rbconfig'
|
|||||||
ruby_engine = defined?(RUBY_ENGINE) ? RUBY_ENGINE : 'ruby'
|
ruby_engine = defined?(RUBY_ENGINE) ? RUBY_ENGINE : 'ruby'
|
||||||
ruby_version = RbConfig::CONFIG["ruby_version"]
|
ruby_version = RbConfig::CONFIG["ruby_version"]
|
||||||
path = File.expand_path('..', __FILE__)
|
path = File.expand_path('..', __FILE__)
|
||||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/concurrent-ruby-1.1.9/lib/concurrent-ruby"
|
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/concurrent-ruby-1.1.10/lib/concurrent-ruby"
|
||||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/i18n-1.10.0/lib"
|
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/i18n-1.10.0/lib"
|
||||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/minitest-5.15.0/lib"
|
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/minitest-5.15.0/lib"
|
||||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/tzinfo-2.0.4/lib"
|
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/tzinfo-2.0.4/lib"
|
||||||
|
|||||||
@ -0,0 +1,5 @@
|
|||||||
|
# This file is here so that there is a file with the same name as the gem that
|
||||||
|
# can be required by Bundler.require. Applications should normally
|
||||||
|
# require 'concurrent'.
|
||||||
|
|
||||||
|
require_relative "concurrent"
|
||||||
@ -272,6 +272,7 @@ module Concurrent
|
|||||||
obj.send(:init_synchronization)
|
obj.send(:init_synchronization)
|
||||||
obj
|
obj
|
||||||
end
|
end
|
||||||
|
ruby2_keywords :new if respond_to?(:ruby2_keywords, true)
|
||||||
end
|
end
|
||||||
private_constant :ClassMethods
|
private_constant :ClassMethods
|
||||||
|
|
||||||
@ -170,6 +170,7 @@ module Concurrent
|
|||||||
alias_method :compare_and_swap, :compare_and_set
|
alias_method :compare_and_swap, :compare_and_set
|
||||||
alias_method :swap, :get_and_set
|
alias_method :swap, :get_and_set
|
||||||
end
|
end
|
||||||
|
TruffleRubyAtomicReference
|
||||||
when Concurrent.on_rbx?
|
when Concurrent.on_rbx?
|
||||||
# @note Extends `Rubinius::AtomicReference` version adding aliases
|
# @note Extends `Rubinius::AtomicReference` version adding aliases
|
||||||
# and numeric logic.
|
# and numeric logic.
|
||||||
@ -19,7 +19,7 @@ module Concurrent
|
|||||||
# t1 = Thread.new do
|
# t1 = Thread.new do
|
||||||
# puts "t1 is waiting"
|
# puts "t1 is waiting"
|
||||||
# event.wait(1)
|
# event.wait(1)
|
||||||
# puts "event ocurred"
|
# puts "event occurred"
|
||||||
# end
|
# end
|
||||||
#
|
#
|
||||||
# t2 = Thread.new do
|
# t2 = Thread.new do
|
||||||
@ -30,8 +30,8 @@ module Concurrent
|
|||||||
# [t1, t2].each(&:join)
|
# [t1, t2].each(&:join)
|
||||||
#
|
#
|
||||||
# # prints:
|
# # prints:
|
||||||
# # t2 calling set
|
|
||||||
# # t1 is waiting
|
# # t1 is waiting
|
||||||
|
# # t2 calling set
|
||||||
# # event occurred
|
# # event occurred
|
||||||
class Event < Synchronization::LockableObject
|
class Event < Synchronization::LockableObject
|
||||||
|
|
||||||
@ -23,7 +23,14 @@ module Concurrent
|
|||||||
|
|
||||||
synchronize do
|
synchronize do
|
||||||
try_acquire_timed(permits, nil)
|
try_acquire_timed(permits, nil)
|
||||||
nil
|
end
|
||||||
|
|
||||||
|
return unless block_given?
|
||||||
|
|
||||||
|
begin
|
||||||
|
yield
|
||||||
|
ensure
|
||||||
|
release(permits)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -48,13 +55,22 @@ module Concurrent
|
|||||||
Utility::NativeInteger.ensure_integer_and_bounds permits
|
Utility::NativeInteger.ensure_integer_and_bounds permits
|
||||||
Utility::NativeInteger.ensure_positive permits
|
Utility::NativeInteger.ensure_positive permits
|
||||||
|
|
||||||
synchronize do
|
acquired = synchronize do
|
||||||
if timeout.nil?
|
if timeout.nil?
|
||||||
try_acquire_now(permits)
|
try_acquire_now(permits)
|
||||||
else
|
else
|
||||||
try_acquire_timed(permits, timeout)
|
try_acquire_timed(permits, timeout)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
return acquired unless block_given?
|
||||||
|
return unless acquired
|
||||||
|
|
||||||
|
begin
|
||||||
|
yield
|
||||||
|
ensure
|
||||||
|
release(permits)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# @!macro semaphore_method_release
|
# @!macro semaphore_method_release
|
||||||
@ -267,12 +267,10 @@ module Concurrent
|
|||||||
# running right now, AND no writers who came before us still waiting to
|
# running right now, AND no writers who came before us still waiting to
|
||||||
# acquire the lock
|
# acquire the lock
|
||||||
# Additionally, if any read locks have been taken, we must hold all of them
|
# Additionally, if any read locks have been taken, we must hold all of them
|
||||||
if c == held
|
if held > 0 && @Counter.compare_and_set(1, c+RUNNING_WRITER)
|
||||||
# If we successfully swap the RUNNING_WRITER bit on, then we can go ahead
|
# If we are the only one reader and successfully swap the RUNNING_WRITER bit on, then we can go ahead
|
||||||
if @Counter.compare_and_set(c, c+RUNNING_WRITER)
|
@HeldCount.value = held + WRITE_LOCK_HELD
|
||||||
@HeldCount.value = held + WRITE_LOCK_HELD
|
return true
|
||||||
return true
|
|
||||||
end
|
|
||||||
elsif @Counter.compare_and_set(c, c+WAITING_WRITER)
|
elsif @Counter.compare_and_set(c, c+WAITING_WRITER)
|
||||||
while true
|
while true
|
||||||
# Now we have successfully incremented, so no more readers will be able to increment
|
# Now we have successfully incremented, so no more readers will be able to increment
|
||||||
@ -16,14 +16,16 @@ module Concurrent
|
|||||||
# @!macro semaphore_method_acquire
|
# @!macro semaphore_method_acquire
|
||||||
#
|
#
|
||||||
# Acquires the given number of permits from this semaphore,
|
# Acquires the given number of permits from this semaphore,
|
||||||
# blocking until all are available.
|
# blocking until all are available. If a block is given,
|
||||||
|
# yields to it and releases the permits afterwards.
|
||||||
#
|
#
|
||||||
# @param [Fixnum] permits Number of permits to acquire
|
# @param [Fixnum] permits Number of permits to acquire
|
||||||
#
|
#
|
||||||
# @raise [ArgumentError] if `permits` is not an integer or is less than
|
# @raise [ArgumentError] if `permits` is not an integer or is less than
|
||||||
# one
|
# one
|
||||||
#
|
#
|
||||||
# @return [nil]
|
# @return [nil, BasicObject] Without a block, `nil` is returned. If a block
|
||||||
|
# is given, its return value is returned.
|
||||||
|
|
||||||
# @!macro semaphore_method_available_permits
|
# @!macro semaphore_method_available_permits
|
||||||
#
|
#
|
||||||
@ -41,7 +43,9 @@ module Concurrent
|
|||||||
#
|
#
|
||||||
# Acquires the given number of permits from this semaphore,
|
# Acquires the given number of permits from this semaphore,
|
||||||
# only if all are available at the time of invocation or within
|
# only if all are available at the time of invocation or within
|
||||||
# `timeout` interval
|
# `timeout` interval. If a block is given, yields to it if the permits
|
||||||
|
# were successfully acquired, and releases them afterward, returning the
|
||||||
|
# block's return value.
|
||||||
#
|
#
|
||||||
# @param [Fixnum] permits the number of permits to acquire
|
# @param [Fixnum] permits the number of permits to acquire
|
||||||
#
|
#
|
||||||
@ -51,8 +55,10 @@ module Concurrent
|
|||||||
# @raise [ArgumentError] if `permits` is not an integer or is less than
|
# @raise [ArgumentError] if `permits` is not an integer or is less than
|
||||||
# one
|
# one
|
||||||
#
|
#
|
||||||
# @return [Boolean] `false` if no permits are available, `true` when
|
# @return [true, false, nil, BasicObject] `false` if no permits are
|
||||||
# acquired a permit
|
# available, `true` when acquired a permit. If a block is given, the
|
||||||
|
# block's return value is returned if the permits were acquired; if not,
|
||||||
|
# `nil` is returned.
|
||||||
|
|
||||||
# @!macro semaphore_method_release
|
# @!macro semaphore_method_release
|
||||||
#
|
#
|
||||||
@ -106,6 +112,8 @@ module Concurrent
|
|||||||
# releasing a blocking acquirer.
|
# releasing a blocking acquirer.
|
||||||
# However, no actual permit objects are used; the Semaphore just keeps a
|
# However, no actual permit objects are used; the Semaphore just keeps a
|
||||||
# count of the number available and acts accordingly.
|
# count of the number available and acts accordingly.
|
||||||
|
# Alternatively, permits may be acquired within a block, and automatically
|
||||||
|
# released after the block finishes executing.
|
||||||
#
|
#
|
||||||
# @!macro semaphore_public_api
|
# @!macro semaphore_public_api
|
||||||
# @example
|
# @example
|
||||||
@ -140,6 +148,19 @@ module Concurrent
|
|||||||
# # Thread 4 releasing semaphore
|
# # Thread 4 releasing semaphore
|
||||||
# # Thread 1 acquired semaphore
|
# # Thread 1 acquired semaphore
|
||||||
#
|
#
|
||||||
|
# @example
|
||||||
|
# semaphore = Concurrent::Semaphore.new(1)
|
||||||
|
#
|
||||||
|
# puts semaphore.available_permits
|
||||||
|
# semaphore.acquire do
|
||||||
|
# puts semaphore.available_permits
|
||||||
|
# end
|
||||||
|
# puts semaphore.available_permits
|
||||||
|
#
|
||||||
|
# # prints:
|
||||||
|
# # 1
|
||||||
|
# # 0
|
||||||
|
# # 1
|
||||||
class Semaphore < SemaphoreImplementation
|
class Semaphore < SemaphoreImplementation
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
Binary file not shown.
@ -75,28 +75,31 @@ module Concurrent
|
|||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
# Handler which executes the `fallback_policy` once the queue size
|
# Returns an action which executes the `fallback_policy` once the queue
|
||||||
# reaches `max_queue`.
|
# size reaches `max_queue`. The reason for the indirection of an action
|
||||||
|
# is so that the work can be deferred outside of synchronization.
|
||||||
#
|
#
|
||||||
# @param [Array] args the arguments to the task which is being handled.
|
# @param [Array] args the arguments to the task which is being handled.
|
||||||
#
|
#
|
||||||
# @!visibility private
|
# @!visibility private
|
||||||
def handle_fallback(*args)
|
def fallback_action(*args)
|
||||||
case fallback_policy
|
case fallback_policy
|
||||||
when :abort
|
when :abort
|
||||||
raise RejectedExecutionError
|
lambda { raise RejectedExecutionError }
|
||||||
when :discard
|
when :discard
|
||||||
false
|
lambda { false }
|
||||||
when :caller_runs
|
when :caller_runs
|
||||||
begin
|
lambda {
|
||||||
yield(*args)
|
begin
|
||||||
rescue => ex
|
yield(*args)
|
||||||
# let it fail
|
rescue => ex
|
||||||
log DEBUG, ex
|
# let it fail
|
||||||
end
|
log DEBUG, ex
|
||||||
true
|
end
|
||||||
|
true
|
||||||
|
}
|
||||||
else
|
else
|
||||||
fail "Unknown fallback policy #{fallback_policy}"
|
lambda { fail "Unknown fallback policy #{fallback_policy}" }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -71,9 +71,16 @@ module Concurrent
|
|||||||
# @return [Integer] Number of tasks that may be enqueued before reaching `max_queue` and rejecting
|
# @return [Integer] Number of tasks that may be enqueued before reaching `max_queue` and rejecting
|
||||||
# new tasks. A value of -1 indicates that the queue may grow without bound.
|
# new tasks. A value of -1 indicates that the queue may grow without bound.
|
||||||
|
|
||||||
|
# @!macro thread_pool_executor_method_prune_pool
|
||||||
|
# Prune the thread pool of unneeded threads
|
||||||
|
#
|
||||||
|
# What is being pruned is controlled by the min_threads and idletime
|
||||||
|
# parameters passed at pool creation time
|
||||||
|
#
|
||||||
|
# This is a no-op on some pool implementation (e.g. the Java one). The Ruby
|
||||||
|
# pool will auto-prune each time a new job is posted. You will need to call
|
||||||
|
# this method explicitely in case your application post jobs in bursts (a
|
||||||
|
# lot of jobs and then nothing for long periods)
|
||||||
|
|
||||||
# @!macro thread_pool_executor_public_api
|
# @!macro thread_pool_executor_public_api
|
||||||
#
|
#
|
||||||
@ -111,6 +118,9 @@ module Concurrent
|
|||||||
#
|
#
|
||||||
# @!method can_overflow?
|
# @!method can_overflow?
|
||||||
# @!macro executor_service_method_can_overflow_question
|
# @!macro executor_service_method_can_overflow_question
|
||||||
|
#
|
||||||
|
# @!method prune_pool
|
||||||
|
# @!macro thread_pool_executor_method_prune_pool
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -20,7 +20,7 @@ if Concurrent.on_jruby?
|
|||||||
|
|
||||||
def post(*args, &task)
|
def post(*args, &task)
|
||||||
raise ArgumentError.new('no block given') unless block_given?
|
raise ArgumentError.new('no block given') unless block_given?
|
||||||
return handle_fallback(*args, &task) unless running?
|
return fallback_action(*args, &task).call unless running?
|
||||||
@executor.submit Job.new(args, task)
|
@executor.submit Job.new(args, task)
|
||||||
true
|
true
|
||||||
rescue Java::JavaUtilConcurrent::RejectedExecutionException
|
rescue Java::JavaUtilConcurrent::RejectedExecutionException
|
||||||
@ -93,6 +93,10 @@ if Concurrent.on_jruby?
|
|||||||
super && !@executor.isTerminating
|
super && !@executor.isTerminating
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# @!macro thread_pool_executor_method_prune_pool
|
||||||
|
def prune_pool
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def ns_initialize(opts)
|
def ns_initialize(opts)
|
||||||
@ -16,10 +16,16 @@ module Concurrent
|
|||||||
|
|
||||||
def post(*args, &task)
|
def post(*args, &task)
|
||||||
raise ArgumentError.new('no block given') unless block_given?
|
raise ArgumentError.new('no block given') unless block_given?
|
||||||
synchronize do
|
deferred_action = synchronize {
|
||||||
# If the executor is shut down, reject this task
|
if running?
|
||||||
return handle_fallback(*args, &task) unless running?
|
ns_execute(*args, &task)
|
||||||
ns_execute(*args, &task)
|
else
|
||||||
|
fallback_action(*args, &task)
|
||||||
|
end
|
||||||
|
}
|
||||||
|
if deferred_action
|
||||||
|
deferred_action.call
|
||||||
|
else
|
||||||
true
|
true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -93,13 +93,8 @@ module Concurrent
|
|||||||
end
|
end
|
||||||
|
|
||||||
# @!visibility private
|
# @!visibility private
|
||||||
def ready_worker(worker)
|
def ready_worker(worker, last_message)
|
||||||
synchronize { ns_ready_worker worker }
|
synchronize { ns_ready_worker worker, last_message }
|
||||||
end
|
|
||||||
|
|
||||||
# @!visibility private
|
|
||||||
def worker_not_old_enough(worker)
|
|
||||||
synchronize { ns_worker_not_old_enough worker }
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# @!visibility private
|
# @!visibility private
|
||||||
@ -112,6 +107,11 @@ module Concurrent
|
|||||||
synchronize { @completed_task_count += 1 }
|
synchronize { @completed_task_count += 1 }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# @!macro thread_pool_executor_method_prune_pool
|
||||||
|
def prune_pool
|
||||||
|
synchronize { ns_prune_pool }
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
# @!visibility private
|
# @!visibility private
|
||||||
@ -156,10 +156,11 @@ module Concurrent
|
|||||||
if ns_assign_worker(*args, &task) || ns_enqueue(*args, &task)
|
if ns_assign_worker(*args, &task) || ns_enqueue(*args, &task)
|
||||||
@scheduled_task_count += 1
|
@scheduled_task_count += 1
|
||||||
else
|
else
|
||||||
handle_fallback(*args, &task)
|
return fallback_action(*args, &task)
|
||||||
end
|
end
|
||||||
|
|
||||||
ns_prune_pool if @next_gc_time < Concurrent.monotonic_time
|
ns_prune_pool if @next_gc_time < Concurrent.monotonic_time
|
||||||
|
nil
|
||||||
end
|
end
|
||||||
|
|
||||||
# @!visibility private
|
# @!visibility private
|
||||||
@ -192,7 +193,7 @@ module Concurrent
|
|||||||
# @!visibility private
|
# @!visibility private
|
||||||
def ns_assign_worker(*args, &task)
|
def ns_assign_worker(*args, &task)
|
||||||
# keep growing if the pool is not at the minimum yet
|
# keep growing if the pool is not at the minimum yet
|
||||||
worker = (@ready.pop if @pool.size >= @min_length) || ns_add_busy_worker
|
worker, _ = (@ready.pop if @pool.size >= @min_length) || ns_add_busy_worker
|
||||||
if worker
|
if worker
|
||||||
worker << [task, args]
|
worker << [task, args]
|
||||||
true
|
true
|
||||||
@ -223,7 +224,7 @@ module Concurrent
|
|||||||
def ns_worker_died(worker)
|
def ns_worker_died(worker)
|
||||||
ns_remove_busy_worker worker
|
ns_remove_busy_worker worker
|
||||||
replacement_worker = ns_add_busy_worker
|
replacement_worker = ns_add_busy_worker
|
||||||
ns_ready_worker replacement_worker, false if replacement_worker
|
ns_ready_worker replacement_worker, Concurrent.monotonic_time, false if replacement_worker
|
||||||
end
|
end
|
||||||
|
|
||||||
# creates new worker which has to receive work to do after it's added
|
# creates new worker which has to receive work to do after it's added
|
||||||
@ -242,29 +243,21 @@ module Concurrent
|
|||||||
# handle ready worker, giving it new job or assigning back to @ready
|
# handle ready worker, giving it new job or assigning back to @ready
|
||||||
#
|
#
|
||||||
# @!visibility private
|
# @!visibility private
|
||||||
def ns_ready_worker(worker, success = true)
|
def ns_ready_worker(worker, last_message, success = true)
|
||||||
task_and_args = @queue.shift
|
task_and_args = @queue.shift
|
||||||
if task_and_args
|
if task_and_args
|
||||||
worker << task_and_args
|
worker << task_and_args
|
||||||
else
|
else
|
||||||
# stop workers when !running?, do not return them to @ready
|
# stop workers when !running?, do not return them to @ready
|
||||||
if running?
|
if running?
|
||||||
@ready.push(worker)
|
raise unless last_message
|
||||||
|
@ready.push([worker, last_message])
|
||||||
else
|
else
|
||||||
worker.stop
|
worker.stop
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# returns back worker to @ready which was not idle for enough time
|
|
||||||
#
|
|
||||||
# @!visibility private
|
|
||||||
def ns_worker_not_old_enough(worker)
|
|
||||||
# let's put workers coming from idle_test back to the start (as the oldest worker)
|
|
||||||
@ready.unshift(worker)
|
|
||||||
true
|
|
||||||
end
|
|
||||||
|
|
||||||
# removes a worker which is not in not tracked in @ready
|
# removes a worker which is not in not tracked in @ready
|
||||||
#
|
#
|
||||||
# @!visibility private
|
# @!visibility private
|
||||||
@ -278,10 +271,17 @@ module Concurrent
|
|||||||
#
|
#
|
||||||
# @!visibility private
|
# @!visibility private
|
||||||
def ns_prune_pool
|
def ns_prune_pool
|
||||||
return if @pool.size <= @min_length
|
now = Concurrent.monotonic_time
|
||||||
|
stopped_workers = 0
|
||||||
last_used = @ready.shift
|
while !@ready.empty? && (@pool.size - stopped_workers > @min_length)
|
||||||
last_used << :idle_test if last_used
|
worker, last_message = @ready.first
|
||||||
|
if now - last_message > self.idletime
|
||||||
|
stopped_workers += 1
|
||||||
|
@ready.shift
|
||||||
|
worker << :stop
|
||||||
|
else break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
@next_gc_time = Concurrent.monotonic_time + @gc_interval
|
@next_gc_time = Concurrent.monotonic_time + @gc_interval
|
||||||
end
|
end
|
||||||
@ -330,19 +330,10 @@ module Concurrent
|
|||||||
|
|
||||||
def create_worker(queue, pool, idletime)
|
def create_worker(queue, pool, idletime)
|
||||||
Thread.new(queue, pool, idletime) do |my_queue, my_pool, my_idletime|
|
Thread.new(queue, pool, idletime) do |my_queue, my_pool, my_idletime|
|
||||||
last_message = Concurrent.monotonic_time
|
|
||||||
catch(:stop) do
|
catch(:stop) do
|
||||||
loop do
|
loop do
|
||||||
|
|
||||||
case message = my_queue.pop
|
case message = my_queue.pop
|
||||||
when :idle_test
|
|
||||||
if (Concurrent.monotonic_time - last_message) > my_idletime
|
|
||||||
my_pool.remove_busy_worker(self)
|
|
||||||
throw :stop
|
|
||||||
else
|
|
||||||
my_pool.worker_not_old_enough(self)
|
|
||||||
end
|
|
||||||
|
|
||||||
when :stop
|
when :stop
|
||||||
my_pool.remove_busy_worker(self)
|
my_pool.remove_busy_worker(self)
|
||||||
throw :stop
|
throw :stop
|
||||||
@ -350,9 +341,7 @@ module Concurrent
|
|||||||
else
|
else
|
||||||
task, args = message
|
task, args = message
|
||||||
run_task my_pool, task, args
|
run_task my_pool, task, args
|
||||||
last_message = Concurrent.monotonic_time
|
my_pool.ready_worker(self, Concurrent.monotonic_time)
|
||||||
|
|
||||||
my_pool.ready_worker(self)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -16,10 +16,10 @@ module Concurrent
|
|||||||
|
|
||||||
# @return [Array]
|
# @return [Array]
|
||||||
def execute(*args)
|
def execute(*args)
|
||||||
synchronize do
|
success = true
|
||||||
success = false
|
value = reason = nil
|
||||||
value = reason = nil
|
|
||||||
|
|
||||||
|
synchronize do
|
||||||
begin
|
begin
|
||||||
value = @task.call(*args)
|
value = @task.call(*args)
|
||||||
success = true
|
success = true
|
||||||
@ -27,9 +27,9 @@ module Concurrent
|
|||||||
reason = ex
|
reason = ex
|
||||||
success = false
|
success = false
|
||||||
end
|
end
|
||||||
|
|
||||||
[success, value, reason]
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
[success, value, reason]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -281,7 +281,6 @@ module Concurrent
|
|||||||
each_pair { |k, v| return k if v == value }
|
each_pair { |k, v| return k if v == value }
|
||||||
nil
|
nil
|
||||||
end unless method_defined?(:key)
|
end unless method_defined?(:key)
|
||||||
alias_method :index, :key if RUBY_VERSION < '1.9'
|
|
||||||
|
|
||||||
# Is map empty?
|
# Is map empty?
|
||||||
# @return [true, false]
|
# @return [true, false]
|
||||||
@ -58,29 +58,42 @@ module Concurrent
|
|||||||
# @example Basic usage
|
# @example Basic usage
|
||||||
#
|
#
|
||||||
# require 'concurrent'
|
# require 'concurrent'
|
||||||
# require 'thread' # for Queue
|
# require 'csv'
|
||||||
# require 'open-uri' # for open(uri)
|
# require 'open-uri'
|
||||||
#
|
#
|
||||||
# class Ticker
|
# class Ticker
|
||||||
# def get_year_end_closing(symbol, year)
|
# def get_year_end_closing(symbol, year, api_key)
|
||||||
# uri = "http://ichart.finance.yahoo.com/table.csv?s=#{symbol}&a=11&b=01&c=#{year}&d=11&e=31&f=#{year}&g=m"
|
# uri = "https://www.alphavantage.co/query?function=TIME_SERIES_MONTHLY&symbol=#{symbol}&apikey=#{api_key}&datatype=csv"
|
||||||
# data = open(uri) {|f| f.collect{|line| line.strip } }
|
# data = []
|
||||||
# data[1].split(',')[4].to_f
|
# csv = URI.parse(uri).read
|
||||||
# end
|
# if csv.include?('call frequency')
|
||||||
|
# return :rate_limit_exceeded
|
||||||
|
# end
|
||||||
|
# CSV.parse(csv, headers: true) do |row|
|
||||||
|
# data << row['close'].to_f if row['timestamp'].include?(year.to_s)
|
||||||
|
# end
|
||||||
|
# year_end = data.first
|
||||||
|
# year_end
|
||||||
|
# rescue => e
|
||||||
|
# p e
|
||||||
|
# end
|
||||||
# end
|
# end
|
||||||
#
|
#
|
||||||
# # Future
|
# api_key = ENV['ALPHAVANTAGE_KEY']
|
||||||
# price = Concurrent::Future.execute{ Ticker.new.get_year_end_closing('TWTR', 2013) }
|
# abort(error_message) unless api_key
|
||||||
# price.state #=> :pending
|
|
||||||
# sleep(1) # do other stuff
|
|
||||||
# price.value #=> 63.65
|
|
||||||
# price.state #=> :fulfilled
|
|
||||||
#
|
#
|
||||||
# # ScheduledTask
|
# # Future
|
||||||
# task = Concurrent::ScheduledTask.execute(2){ Ticker.new.get_year_end_closing('INTC', 2013) }
|
# price = Concurrent::Future.execute{ Ticker.new.get_year_end_closing('TWTR', 2013, api_key) }
|
||||||
# task.state #=> :pending
|
# price.state #=> :pending
|
||||||
# sleep(3) # do other stuff
|
# price.pending? #=> true
|
||||||
# task.value #=> 25.96
|
# price.value(0) #=> nil (does not block)
|
||||||
|
#
|
||||||
|
# sleep(1) # do other stuff
|
||||||
|
#
|
||||||
|
# price.value #=> 63.65 (after blocking if necessary)
|
||||||
|
# price.state #=> :fulfilled
|
||||||
|
# price.fulfilled? #=> true
|
||||||
|
# price.value #=> 63.65
|
||||||
#
|
#
|
||||||
# @example Successful task execution
|
# @example Successful task execution
|
||||||
#
|
#
|
||||||
@ -4,9 +4,7 @@ module Concurrent
|
|||||||
# @!visibility private
|
# @!visibility private
|
||||||
# @!macro internal_implementation_note
|
# @!macro internal_implementation_note
|
||||||
LockableObjectImplementation = case
|
LockableObjectImplementation = case
|
||||||
when Concurrent.on_cruby? && Concurrent.ruby_version(:<=, 1, 9, 3)
|
when Concurrent.on_cruby?
|
||||||
MonitorLockableObject
|
|
||||||
when Concurrent.on_cruby? && Concurrent.ruby_version(:>, 1, 9, 3)
|
|
||||||
MutexLockableObject
|
MutexLockableObject
|
||||||
when Concurrent.on_jruby?
|
when Concurrent.on_jruby?
|
||||||
JRubyLockableObject
|
JRubyLockableObject
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user