I am playing with a Synchronized class that automates resource locking
(code snippet can be found here: http://www.rubygarden.org/ruby?MultiThreading).
One issue arised is how to overload all (or particular) Object's (or
some ancestor's) methods by the automated way?
Syncronized extraction looks like this:
class Syncronized
def initialize( klass, *args )
@obj= klass::new( *args );
end
def to_s() @obj.to_s(); end
# What about clone(), taint(), and other?
end
It is hard work to type all the Objecs's methods by hand in spite of
their bodies are the same.
What is the better choice?
What about the "methods" method? You get an Array whith all the method-names of the current object.
Maybe something like this
class Sync
def initialze (klass, *args) @object = klass::new(*args) @object.methods.each do |m|
def m(a)
object.m(a)
end
end
end
I know, this won't run - just an idea.
···
On Mon, 10 Oct 2005 17:21:51 +0900 "S.Z." <zbl@operamail.com> wrote:
I am playing with a Synchronized class that automates resource locking
(code snippet can be found here: http://www.rubygarden.org/ruby?MultiThreading\).
One issue arised is how to overload all (or particular) Object's (or
some ancestor's) methods by the automated way?
Syncronized extraction looks like this:
class Syncronized
def initialize( klass, *args )
@obj= klass::new( *args );
end
def to_s() @obj.to_s(); end
# What about clone(), taint(), and other?
end
It is hard work to type all the Objecs's methods by hand in spite of
their bodies are the same.
What is the better choice?
--
"not using Ruby is punishment enough"
-- James Britt, 8.5.2005, ruby-talk@ruby-lang.org
I am playing with a Synchronized class that automates resource locking
(code snippet can be found here: http://www.rubygarden.org/ruby?MultiThreading\).
One issue arised is how to overload all (or particular) Object's (or
some ancestor's) methods by the automated way?
Syncronized extraction looks like this:
class Syncronized
def initialize( klass, *args )
@obj= klass::new( *args );
end
def to_s() @obj.to_s(); end
# What about clone(), taint(), and other?
end
It is hard work to type all the Objecs's methods by hand in spite of
their bodies are the same.
What is the better choice?
You can iterate all instance methods, alias each one and create a new one
calling the original one synchronized. Delegate might be helpful, too.
Note though that automatically synchronizaton of each method is not
necessarily going to make your program thread safe. Every transaction
that involves more than one method invocation won't be thread safe with
this approach - in this case you need explicit external synchronization:
# typical example
unless hash.contains_key? "foo"
# lengthy calculation
hash["foo"] = result_of_lenthy_calculation
end
Other typical examples involve scenarios where several instances have to
be changed consistently. All these are reasons why Sun stepped away from
full synchronization (Vector, StringBuffer) and added classes that do not
employ method level synchronization (ArrayList, StringBuilder), which is
more performant.
You can iterate all instance methods, alias each one and create a new one
calling the original one synchronized. Delegate might be helpful, too.
Eurica!
I need not to define, but rather to undefine the Object's methods:
undef :to_s, :taint, :clone;
Now method_missing() can operate.
Note though that automatically synchronizaton of each method is not
necessarily going to make your program thread safe. Every transaction
that involves more than one method invocation won't be thread safe with
this approach - in this case you need explicit external synchronization
Any transaction on an object can be treated as a single method call.
Transaction's body can be known only at runtime; but it is not a
problem in Ruby.
Sun stepped away from
full synchronization (Vector, StringBuffer) and added classes that do not
employ method level synchronization (ArrayList, StringBuilder), which is
more performant.
You can iterate all instance methods, alias each one and create a
new one calling the original one synchronized. Delegate might be
helpful, too.
Eurica!
I need not to define, but rather to undefine the Object's methods:
undef :to_s, :taint, :clone;
Now method_missing() can operate.
And which method do you invoke then if you undefined all those methods?
Note though that automatically synchronizaton of each method is not
necessarily going to make your program thread safe. Every
transaction that involves more than one method invocation won't be
thread safe with this approach - in this case you need explicit
external synchronization
Any transaction on an object can be treated as a single method call.
Certainly not! It might in a many scenarios but there's also a lot
scenarios where this does not apply. This statement as a general
statement is wrong.
Transaction's body can be known only at runtime; but it is not a
problem in Ruby.
What are you trying to say here?
Sun stepped away from
full synchronization (Vector, StringBuffer) and added classes that
do not employ method level synchronization (ArrayList,
StringBuilder), which is more performant.
This approach is erroprone, I think...
Not at all. It's exactly the way to go. Built in sychronization of every
method is pointless because you never get the class without
synchronization overhead. This can have serious impact on applications as
every synchronized necessitates synchronization of thread local memory
(there are some nice articles on the web on how Java VM handles
concurrency, synchronization - look for "JVM memory model").
Honestly, I'm not sure that you completely grokked concurrency. I suggest
you get yourself a copy of "Concurrent Programming in Java" if you want to
dig deeper into the matter
undef :to_s, :taint, :clone;
Now method_missing() can operate.
And which method do you invoke then if you undefined all those methods?
If I invoke to_s() on Sync object, then method_missing() will be
called because to_s() has been undefined for Sync class.
method_missing() can do all I want to be done.
Robert Klemme wrote:
S.Z. wrote:
Any transaction on an object can be treated as a single method call.
Certainly not! It might in a many scenarios but there's also a lot
scenarios where this does not apply. This statement as a general
statement is wrong.
Would you show an example in which this does not apply?
Robert Klemme wrote:
S.Z. wrote:
Transaction's body can be known only at runtime; but it is not a
problem in Ruby.
What are you trying to say here?
Excuse my poor English.
Transaction is not a method call, rather a context for several method
calls.
But, if we can put these calls to single batch and invoke it then
transacton is just a method call, except for begin/commit semantics.
In Ruby we can easily create such a batch.
Robert Klemme wrote:
Built in sychronization of every
method is pointless because you never get the class without
synchronization overhead.
It is obvious.
Rather having an ordinary object I need to construct the synchronized
one without the use of errorprone external mutexes and randevous.
As the first step, I have created Sync class to hold the object and the
sync semantics.
In the simplest case of read/write unordered buffer only per-method
synchronization is needed and therefore Sync class can solve the task.
undef :to_s, :taint, :clone;
Now method_missing() can operate.
And which method do you invoke then if you undefined all those
methods?
If I invoke to_s() on Sync object, then method_missing() will be
called because to_s() has been undefined for Sync class.
method_missing() can do all I want to be done.
Well yes, but from what I understand from your postings your aim is to
make each method synchronized automatically. Or are you saying that you
want to use a delegate pattern where method_missing is used to call the
original instance's method synchronized?
Robert Klemme wrote:
S.Z. wrote:
Any transaction on an object can be treated as a single method call.
Certainly not! It might in a many scenarios but there's also a lot
scenarios where this does not apply. This statement as a general
statement is wrong.
Would you show an example in which this does not apply?
I did already. Every scenario where at least two method calls on the same
or multiple objects have to be atomic with regard to other threads'
activities.
Robert Klemme wrote:
S.Z. wrote:
Transaction's body can be known only at runtime; but it is not a
problem in Ruby.
What are you trying to say here?
Excuse my poor English.
Transaction is not a method call, rather a context for several method
calls.
But, if we can put these calls to single batch and invoke it then
transacton is just a method call, except for begin/commit semantics.
In Ruby we can easily create such a batch.
You have that feature already with Mutex#synchronized and
Monitor#synchronized. There's also a variant as mixin (see doc ref
below).
Robert Klemme wrote:
Built in sychronization of every
method is pointless because you never get the class without
synchronization overhead.
It is obvious.
Rather having an ordinary object I need to construct the synchronized
one without the use of errorprone external mutexes and randevous.
So you're using Java's delegation approach with
Collection.synchronizedList() etc., i.e. you have a wrapper class that
does the synchronization and then delegates each method call to the real
object.
As the first step, I have created Sync class to hold the object and
the sync semantics.
from what I understand from your postings your aim is to
make each method synchronized automatically. Or are you saying that you
want to use a delegate pattern where method_missing is used to call the
original instance's method synchronized?
I want to use method_missing() to call the original methods
synchronized.
I did already. Every scenario where at least two method calls on the same
or multiple objects have to be atomic with regard to other threads'
activities.
Below you have mentioned Monitor#synchronized(), that is just a
contradiction.
You have that feature already with Mutex#synchronized and
Monitor#synchronized. There's also a variant as mixin (see doc ref
below).
Yes I have. But I dislike both. I know a better solution only for
scenarios where my Sync class can be applied. But I am looking for the
others...
So you're using Java's delegation approach
Yes, I do the same with Ruby.
You don't need to create that on your own. It's already there
I did already. Every scenario where at least two method calls on
the same or multiple objects have to be atomic with regard to other
threads' activities.
Below you have mentioned Monitor#synchronized(), that is just a
contradiction.
Where is this a contradiction?
You have that feature already with Mutex#synchronized and
Monitor#synchronized. There's also a variant as mixin (see doc ref
below).
Yes I have. But I dislike both. I know a better solution only for
scenarios where my Sync class can be applied. But I am looking for the
others...
What's your problem with these? Why do you dislike them? Why can't you
use them to implement your Sync class?
So you're using Java's delegation approach
Yes, I do the same with Ruby.
You don't need to create that on your own. It's already there
Seriously, I really don't know why you think you have to cook something
completely new while there is lots of stuff that seems to be doing what
you need. Maybe it's just a language issue but I have the feeling that
you always write at most half of what you think. That makes it really
hard to follow this thread.
Maybe it's just a language issue but I have the feeling that you always
write at most half of what you think.
i only think at most half of what i write. is that bad?
-a
···
On Thu, 13 Oct 2005, Robert Klemme wrote:
--
email :: ara [dot] t [dot] howard [at] noaa [dot] gov
phone :: 303.497.6469
Your life dwells amoung the causes of death
Like a lamp standing in a strong breeze. --Nagarjuna
Below you have mentioned Monitor#synchronized(), that is just a
contradiction.
Where is this a contradiction?
When MonitorMixin is used any transaction can be treated as single
method call (syncronize() with the block as parameter).
Why can't you use them to implement your Sync class?
I did it with the Mutex. These are the nice lowlevel mechanics, but
using it is erroprone (as it is with any lowlevel mechanic).
If you're in a producer consumer scenario use a Queue.
Oh no, please, no!
The writer must start to write only if the reader has already started
to read (otherwise data may be lost). I want a better mechanism: 1)
create obj1 and obj2; 2) assign "writer" role to the obj1 and "reader"
to the obj2; 3) create a Queue then attach obj1 and obj2 to it; 4) run
the collaboration.
What I need are more higher level Concurrent Programming Pattens
implemented in Ruby. Using Mutexes to implement these is tedious. I
want more higher level mechanics. A thread need not to wory about
whether it is alone or not, so non-concurrent code can be easily
converted to concurrent one and vise versa.
Seriously, I really don't know why you think you have to cook something
completely new while there is lots of stuff that seems to be doing what
you need.
Because the stuff is not exactly what I need. What I need is a long
story though...
Maybe it's just a language issue but I have the feeling that
you always write at most half of what you think.
"We were given two ears and one mouth so we speak only half of what we
hear".
...and yet we get two hands to type with. Darn technology.
I'd guess a 1:2 ratio of think:write is higher than most people's
threshhold. It obviously is higher than mine.
···
On 10/13/05, Ara.T.Howard <Ara.T.Howard@noaa.gov> wrote:
On Thu, 13 Oct 2005, Robert Klemme wrote:
<snip>
> Maybe it's just a language issue but I have the feeling that you always
> write at most half of what you think.
i only think at most half of what i write. is that bad?
-a
--
===============================================================================
> email :: ara [dot] t [dot] howard [at] noaa [dot] gov
> phone :: 303.497.6469
> Your life dwells amoung the causes of death
> Like a lamp standing in a strong breeze. --Nagarjuna