ThreadSafety
ThreadSafety/ClassAndModuleAttributes
Enabled by default | Safe | Supports autocorrection | Version Added | Version Changed |
---|---|---|---|---|
Enabled |
Yes |
No |
- |
- |
Avoid mutating class and module attributes.
They are implemented by class variables, which are not thread-safe.
ThreadSafety/ClassInstanceVariable
Enabled by default | Safe | Supports autocorrection | Version Added | Version Changed |
---|---|---|---|---|
Enabled |
Yes |
No |
- |
- |
Avoid class instance variables.
Examples
# bad
class User
def self.notify(info)
@info = validate(info)
Notifier.new(@info).deliver
end
end
class Model
class << self
def table_name(name)
@table_name = name
end
end
end
class Host
%i[uri port].each do |key|
define_singleton_method("#{key}=") do |value|
instance_variable_set("@#{key}", value)
end
end
end
module Example
module ClassMethods
def test(params)
@params = params
end
end
end
module Example
class_methods do
def test(params)
@params = params
end
end
end
module Example
module_function
def test(params)
@params = params
end
end
module Example
def test(params)
@params = params
end
module_function :test
end
ThreadSafety/DirChdir
Enabled by default | Safe | Supports autocorrection | Version Added | Version Changed |
---|---|---|---|---|
Enabled |
Yes |
No |
- |
- |
Avoid using Dir.chdir
due to its process-wide effect.
If AllowCallWithBlock
(disabled by default) option is enabled,
calling Dir.chdir
with block will be allowed.
ThreadSafety/MutableClassInstanceVariable
Enabled by default | Safe | Supports autocorrection | Version Added | Version Changed |
---|---|---|---|---|
Enabled |
Yes |
Always (Unsafe) |
- |
- |
Checks whether some class instance variable isn’t a mutable literal (e.g. array or hash).
It is based on Style/MutableConstant from RuboCop. See https://github.com/rubocop/rubocop/blob/master/lib/rubocop/cop/style/mutable_constant.rb
Class instance variables are a risk to threaded code as they are shared between threads. A mutable object such as an array or hash may be updated via an attr_reader so would not be detected by the ThreadSafety/ClassAndModuleAttributes cop.
Strict mode can be used to freeze all class instance variables, rather than just literals. Strict mode is considered an experimental feature. It has not been updated with an exhaustive list of all methods that will produce frozen objects so there is a decent chance of getting some false positives. Luckily, there is no harm in freezing an already frozen object.
ThreadSafety/RackMiddlewareInstanceVariable
Enabled by default | Safe | Supports autocorrection | Version Added | Version Changed |
---|---|---|---|---|
Enabled |
Yes |
No |
- |
- |
Avoid instance variables in rack middleware.
Middlewares are initialized once, meaning any instance variables are shared between executor threads. To avoid potential race conditions, it’s recommended to design middlewares to be stateless or to implement proper synchronization mechanisms.
Examples
# bad
class CounterMiddleware
def initialize(app)
@app = app
@counter = 0
end
def call(env)
app.call(env)
ensure
@counter += 1
end
end
# good
class CounterMiddleware
def initialize(app)
@app = app
@counter = Concurrent::AtomicReference.new(0)
end
def call(env)
app.call(env)
ensure
@counter.update { |ref| ref + 1 }
end
end
class IdentityMiddleware
def initialize(app)
@app = app
end
def call(env)
app.call(env)
end
end