Drop dependency on mutex_m

It used to be stdlib but is being extracted in modern rubies.

Overall its usefulness is dubious. In all cases it is included in
Rails, it's only for the `synchronize` method, but end up exposing
a dozen other useless methods.

In the end just using a Mutex is clearer and simpler.

In some cases we can even get away with a single mutex in a constant.
This commit is contained in:
Jean Boussier 2023-10-17 17:46:48 +02:00
parent 633eb5a9f4
commit bcdeea5da7
6 changed files with 13 additions and 24 deletions

@ -91,7 +91,6 @@ PATH
drb
i18n (>= 1.6, < 2)
minitest (>= 5.1)
mutex_m
tzinfo (~> 2.0)
rails (7.2.0.alpha)
actioncable (= 7.2.0.alpha)
@ -342,7 +341,6 @@ GEM
msgpack (1.7.0)
multi_json (1.15.0)
multipart-post (2.2.3)
mutex_m (0.1.2)
mysql2 (0.5.5)
net-http-persistent (4.0.1)
connection_pool (~> 2.2)

@ -84,11 +84,7 @@ module ParamsWrapper
EXCLUDE_PARAMETERS = %w(authenticity_token _method utf8)
require "mutex_m"
class Options < Struct.new(:name, :format, :include, :exclude, :klass, :model) # :nodoc:
include Mutex_m
def self.from_hash(hash)
name = hash[:name]
format = Array(hash[:format])
@ -99,6 +95,7 @@ def self.from_hash(hash)
def initialize(name, format, include, exclude, klass, model) # :nodoc:
super
@mutex = Mutex.new
@include_set = include
@name_set = name
end
@ -111,7 +108,7 @@ def include
return super if @include_set
m = model
synchronize do
@mutex.synchronize do
return super if @include_set
@include_set = true
@ -144,7 +141,7 @@ def name
return super if @name_set
m = model
synchronize do
@mutex.synchronize do
return super if @name_set
@name_set = true

@ -1,6 +1,5 @@
# frozen_string_literal: true
require "mutex_m"
require "active_support/core_ext/enumerable"
module ActiveRecord
@ -24,7 +23,7 @@ module AttributeMethods
RESTRICTED_CLASS_METHODS = %w(private public protected allocate new name parent superclass)
class GeneratedAttributeMethods < Module # :nodoc:
include Mutex_m
LOCK = Monitor.new
end
class << self
@ -68,7 +67,7 @@ def generate_alias_attributes # :nodoc:
superclass.generate_alias_attributes unless superclass == Base
return if @alias_attributes_mass_generated
generated_attribute_methods.synchronize do
GeneratedAttributeMethods::LOCK.synchronize do
return if @alias_attributes_mass_generated
ActiveSupport::CodeGenerator.batch(generated_attribute_methods, __FILE__, __LINE__) do |code_generator|
aliases_by_attribute_name.each do |old_name, new_names|
@ -127,7 +126,7 @@ def define_attribute_methods # :nodoc:
return false if @attribute_methods_generated
# Use a mutex; we don't want two threads simultaneously trying to define
# attribute methods.
generated_attribute_methods.synchronize do
GeneratedAttributeMethods::LOCK.synchronize do
return false if @attribute_methods_generated
superclass.define_attribute_methods unless base_class?
super(attribute_names)
@ -136,7 +135,7 @@ def define_attribute_methods # :nodoc:
end
def undefine_attribute_methods # :nodoc:
generated_attribute_methods.synchronize do
GeneratedAttributeMethods::LOCK.synchronize do
super if defined?(@attribute_methods_generated) && @attribute_methods_generated
@attribute_methods_generated = false
@alias_attributes_mass_generated = false

@ -1,6 +1,5 @@
# frozen_string_literal: true
require "mutex_m"
require "active_support/core_ext/module/delegation"
module ActiveRecord
@ -67,10 +66,10 @@ def generated_relation_methods
end
class GeneratedRelationMethods < Module # :nodoc:
include Mutex_m
MUTEX = Mutex.new
def generate_method(method)
synchronize do
MUTEX.synchronize do
return if method_defined?(method)
if /\A[a-zA-Z_]\w*[!?]?\z/.match?(method) && !DELEGATION_RESERVED_METHOD_NAMES.include?(method.to_s)

@ -41,6 +41,5 @@
s.add_dependency "minitest", ">= 5.1"
s.add_dependency "base64"
s.add_dependency "drb"
s.add_dependency "mutex_m"
s.add_dependency "bigdecimal"
end

@ -1,6 +1,5 @@
# frozen_string_literal: true
require "mutex_m"
require "concurrent/map"
require "set"
require "active_support/core_ext/object/try"
@ -45,15 +44,13 @@ def iterate_guarding_exceptions(listeners)
#
# This class is thread safe. All methods are reentrant.
class Fanout
include Mutex_m
def initialize
@mutex = Mutex.new
@string_subscribers = Concurrent::Map.new { |h, k| h.compute_if_absent(k) { [] } }
@other_subscribers = []
@all_listeners_for = Concurrent::Map.new
@groups_for = Concurrent::Map.new
@silenceable_groups_for = Concurrent::Map.new
super
end
def inspect # :nodoc:
@ -63,7 +60,7 @@ def inspect # :nodoc:
def subscribe(pattern = nil, callable = nil, monotonic: false, &block)
subscriber = Subscribers.new(pattern, callable || block, monotonic)
synchronize do
@mutex.synchronize do
case pattern
when String
@string_subscribers[pattern] << subscriber
@ -79,7 +76,7 @@ def subscribe(pattern = nil, callable = nil, monotonic: false, &block)
end
def unsubscribe(subscriber_or_name)
synchronize do
@mutex.synchronize do
case subscriber_or_name
when String
@string_subscribers[subscriber_or_name].clear
@ -294,7 +291,7 @@ def publish_event(event)
def all_listeners_for(name)
# this is correctly done double-checked locking (Concurrent::Map's lookups have volatile semantics)
@all_listeners_for[name] || synchronize do
@all_listeners_for[name] || @mutex.synchronize do
# use synchronisation when accessing @subscribers
@all_listeners_for[name] ||=
@string_subscribers[name] + @other_subscribers.select { |s| s.subscribed_to?(name) }