M
Mike Bethany
[Note: parts of this message were removed to make it a legal post.]
Threadsafing a mixin module without using self.new or initialize.
Project: Eventable - https://github.com/mikbe/eventable
Background: https://github.com/mikbe/eventable/issues/4
Problem Description:
I need to threadsafe access to an instance variable, an array. To do so I've
wrapped all methods that access the array in a mutex.synchronize block. The
problem is I'm creating the mutex in each function using @eventable_mutex
||= Mutex.new which could cause collisions if two threads try to use a
method that creates the mutex simultaneously.
I've verified this could happen: https://gist.github.com/1031308
Since this is a mixin module I can't use initialize to create the mutex
instance variable and I don't want to use trapself.new because if the class
uses this method itself then the instance variable will never be created. My
aversion to using self.new to create the instance variable is this: if I
redefine a method to fix an issue it's not unreasonable for someone else to
do the same thing. If their doing exactly what I did breaks what I did then
it's a bad fix. (see https://github.com/mikbe/eventable/pull/3)
So, my current idea for a solution is to create a class level mutex for the
inheriting class that locks on the creation of the mutex, for instance:
https://gist.github.com/1031419. This seems ugly though and I'm fairly new
to Ruby so I'm wondering if I've missed, or simply don't know about,
something that would be a better solution.
Threadsafing a mixin module without using self.new or initialize.
Project: Eventable - https://github.com/mikbe/eventable
Background: https://github.com/mikbe/eventable/issues/4
Problem Description:
I need to threadsafe access to an instance variable, an array. To do so I've
wrapped all methods that access the array in a mutex.synchronize block. The
problem is I'm creating the mutex in each function using @eventable_mutex
||= Mutex.new which could cause collisions if two threads try to use a
method that creates the mutex simultaneously.
I've verified this could happen: https://gist.github.com/1031308
Since this is a mixin module I can't use initialize to create the mutex
instance variable and I don't want to use trapself.new because if the class
uses this method itself then the instance variable will never be created. My
aversion to using self.new to create the instance variable is this: if I
redefine a method to fix an issue it's not unreasonable for someone else to
do the same thing. If their doing exactly what I did breaks what I did then
it's a bad fix. (see https://github.com/mikbe/eventable/pull/3)
So, my current idea for a solution is to create a class level mutex for the
inheriting class that locks on the creation of the mutex, for instance:
https://gist.github.com/1031419. This seems ugly though and I'm fairly new
to Ruby so I'm wondering if I've missed, or simply don't know about,
something that would be a better solution.