Mutex

Hi all,
I’ve been reading the RailsDispatch blog, and have been looking at this
code.

class BlacklistConstraint
def initialize
@ips = Blacklist.retrieve_ips
@mutex = Mutex.new
@last_update = Time.now
end

def matches?(request)
@mutex.synchronize do
if (Time.now - @last_update) > 3600
@ips = Blacklist.retrieve_ips
@last_update = Time.now
end
end

[email protected]?(request.remote_ip)

end
end

What interests me is the ‘matches?’ method, specifically the
mutex.synchronize block. I’m wondering what is the benefit of this code,
and how it works?

Is it so other attempts to call Blacklist.retrieve_ips are blocked, and
if so, should the mutex be implemented in the Blacklist class?

thanks for reading.

Oliver C. wrote:

What interests me is the ‘matches?’ method, specifically the
mutex.synchronize block. I’m wondering what is the benefit of this code,
and how it works?

Is it so other attempts to call Blacklist.retrieve_ips are blocked, and
if so, should the mutex be implemented in the Blacklist class?

Only one instance of the code inside @mutex.synchronize { … } can be
executing at any one time (“mutex” = “mutual exclusion”)

Without this mutex, it would be possible that two threads which called
BlacklistConstraint#matches? concurrently, when the cache is more than 1
hour old, could end up calling Blacklist.retrieve_ips concurrently.

This might not be catastrophic if Blacklist.retrieve_ips were
thread-safe, but it would be wasteful. (Presumably
Blacklist.retrieve_ips is an expensive operation, given that it is being
cached)