Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 26 additions & 9 deletions lib/concurrent/async.rb
Original file line number Diff line number Diff line change
Expand Up @@ -128,22 +128,23 @@ def self.validate_argc(obj, method, *args)

# @!visibility private
def self.included(base)
base.singleton_class.send(:alias_method, :original_new, :new)
base.send(:private_class_method, :original_new)
base.extend(ClassMethods)
base.send(:private_class_method, :new)
super(base)
end

# @!visibility private
def self.extended(base)
base.extend(ClassMethods)
base.send(:private_class_method, :new)
super(base)
end

# @!visibility private
module ClassMethods

# @deprecated
def new(*args, &block)
warn '[DEPRECATED] use the `create` method instead'
create(*args, &block)
end

def create(*args, &block)
obj = self.send(:new, *args, &block)
obj = original_new(*args, &block)
obj.send(:init_synchronization)
obj
end
Expand Down Expand Up @@ -269,6 +270,22 @@ def executor=(executor)
raise ArgumentError.new('executor has already been set')
end

# Initialize the internal serializer and other stnchronization mechanisms.
#
# @note This method *must* be called immediately upon object construction.
# This is the only way thread-safe initialization can be guaranteed.
#
# @raise [Concurrent::InitializationError] when called more than once
#
# @!visibility private
# @deprecated
def init_mutex
warn '[DEPRECATED] use the `create` method instead'
init_synchronization
rescue InitializationError
# suppress
end

private

# Initialize the internal serializer and other stnchronization mechanisms.
Expand Down
16 changes: 13 additions & 3 deletions spec/concurrent/async_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ module Concurrent
Class.new do
include Concurrent::Async
attr_accessor :accessor
def initialize(*args)
end
def echo(msg)
msg
end
Expand All @@ -34,8 +36,16 @@ def with_block

context 'object creation' do

it 'makes #new private' do
expect{ async_class.new }.to raise_error(NoMethodError)
# Will be added in 1.0 once deprecated methods are removed
#it 'makes #new private' do
# expect{ async_class.new }.to raise_error(NoMethodError)
#end

# Will be removed in 1.0 once deprecated methods are removed
it '#new delegates to #create' do
args = [:foo, 'bar', 42]
expect(async_class).to receive(:create).once.with(*args)
async_class.new(*args)
end

it 'uses #create to instanciate new objects' do
Expand All @@ -45,7 +55,7 @@ def with_block

specify '#create initializes synchronization' do
mock = async_class.create
allow(async_class).to receive(:new).and_return(mock)
allow(async_class).to receive(:original_new).and_return(mock)
expect(mock).to receive(:init_synchronization).once.with(no_args)
async_class.create
end
Expand Down