Account Options

  1. Sign in
The old Google Groups will be going away soon.
Switch to the new Google Groups.
Google Groups Home
« Groups Home
forwarding #respond_to? to the proxied object
There are currently too many topics in this group that display first. To make this topic appear first, remove this option from another topic.
There was an error processing your request. Please try again.
flag
  11 messages - Collapse all  -  Translate all to Translated (View all originals)
The group you are posting to is a Usenet group. Messages posted to this group will make your email address visible to anyone on the Internet.
Your reply message has not been sent.
Your post was successful
 
From:
To:
Cc:
Followup To:
Add Cc | Add Followup-to | Edit Subject
Subject:
Validation:
For verification purposes please type the characters you see in the picture below or the numbers you hear by clicking the accessibility icon. Listen and type the numbers you hear
 
Chuck Remes  
View profile  
 More options Sep 29 2008, 9:23 pm
From: Chuck Remes <cremes.devl...@mac.com>
Date: Mon, 29 Sep 2008 20:23:35 -0500
Local: Mon, Sep 29 2008 9:23 pm
Subject: forwarding #respond_to? to the proxied object
For a dramatis actor to work with the Observable module, it needs to  
forward respond_to?(:update) to the proxied object. The code that  
handled this before has been changed (I think since you brought  
blankslate into it).

Any idea how I can mimic this functionality now?

cr


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Steven Parkes  
View profile  
 More options Sep 29 2008, 10:26 pm
From: "Steven Parkes" <smpar...@smparkes.net>
Date: Mon, 29 Sep 2008 19:26:48 -0700
Local: Mon, Sep 29 2008 10:26 pm
Subject: RE: forwarding #respond_to? to the proxied object
Hmmm ... it's supposed to do the right thing, as of the switch to
blankslate.

I just added a spec and it worked without code changes.

Any more info on how this seems to be happening? I guess I can try with
Observable exactly ...


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Steven Parkes  
View profile  
 More options Sep 29 2008, 11:15 pm
From: "Steven Parkes" <smpar...@smparkes.net>
Date: Mon, 29 Sep 2008 20:15:18 -0700
Local: Mon, Sep 29 2008 11:15 pm
Subject: RE: forwarding #respond_to? to the proxied object
I just checked in observable_spec.rb that shows observable being used and
seems to function reasonably.

I use actors for both the observer and the observed. I think making one an
actor and not the other won't be safe and sane.

One twist is that you have to explicitly #always allow the #respond_to?
before making the #add_observer call, otherwise you'll get a deadlock
because observed wants to validate the observer before it returns, but
observer is waiting for observed to finish and won't, well, respond to
#respond_to?. You could get around this by making the add_observer call a
release call. Whether that is okay or not would depend on whether other code
assumed the handshake had completed before the constructor returned: with a
release call, you're not sure that observed has really acknowledged the
relationship, which the normal rpc method does ensure. Since it'd be nice to
have the invariant that observer's #initialize didn't finish until the
relationship was established, I'd stick with the #always call for now.

The other thing that would be interesting to consider would be making
#notify_observers make release calls.

Since the observer probably doesn't care to wait around for the notification
to complete, it makes sense to have it call out the release name, i.e., in
the observed class, add something like
      def add_observer actor
        super release( actor )
      end
You could put in code to make it work with normal non-actor objects, too,
but I don't have any sane use cases that mix actors and non-actors with
Observer, so I think that might be moot.

This doesn't actually work, though, and it comes back to the #respond_to?
call that observed makes. It wants to use the name from the add_observer
call to both to verify that observer#update method exists (though I think
this violates duck-typing) and to call it. The second case can use release
semantics but the first requires rpc semantics.

My hack is

      def add_observer actor
        release_name = release( actor )
        class << release_name
          def respond_to? message
            message == :update ? true : super
          end
        end
        super release_name
      end

This is all pretty tied to the current implementation of observer and might
do weird things if you try to add and remove observers dynamically.

This is an area that a full-on actor version of observer, with more
interesting concurrent semantics, would certainly be interesting ... but, of
course, observer already exists, so as long as it can be made work ...


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Chuck Remes  
View profile  
 More options Sep 30 2008, 3:37 pm
From: Chuck Remes <cremes.devl...@mac.com>
Date: Tue, 30 Sep 2008 14:37:34 -0500
Local: Tues, Sep 30 2008 3:37 pm
Subject: Re: forwarding #respond_to? to the proxied object
I've been playing around with this today. I had trouble getting it to  
work (the respond_to?(:update) check was failing) so I edited the  
Observable module and removed that "sanity" check. (I may submit  
something similar to it as a patch back to core since I think that  
check is superfluous.)

What I see is that the asynch method call (I register the released  
name in #add_observer) has quite a bit of overhead. Even though I am  
grabbing the data, shoving it into an array and then doing the asynch  
call, I see about a 5 to 7 millisecond overhead for the asynch call to  
return. If I skip the asynch call and don't do anything, the overhead  
is about 300 microseconds.  This was all measured on a dual quad-core  
system (2.66Ghz) under jruby 1.1.4 after it has had time to "warm up"  
and compile whatever it can compile via hotspot.

The difference between the two measurements is pretty significant. Is  
it spinning up a new thread every time I do an asynch call?

I looked through the docs for some controls on the thread pool size so  
I could put an upper limit on it but I didn't see any such control  
exposed. (I'm not even sure this is an issue... I'm kind of stabbing  
in the dark.)

So, it works but it is kind of pokey.

cr

On Sep 29, 2008, at 10:15 PM, Steven Parkes wrote:


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Steven Parkes  
View profile  
 More options Sep 30 2008, 4:41 pm
From: "Steven Parkes" <smpar...@smparkes.net>
Date: Tue, 30 Sep 2008 13:41:16 -0700
Local: Tues, Sep 30 2008 4:41 pm
Subject: RE: forwarding #respond_to? to the proxied object

> I've been playing around with this today. I had trouble
> getting it to  
> work (the respond_to?(:update) check was failing)

I still don't understand why this is the case. The specs run fine, so I'm
wondering what is different.

> I see about a 5 to 7 millisecond overhead for the
> asynch call to  
> return

So you're just timing the notify_observer call, using a release name, right?
Just that one single operation?

I'll look at it. It's likely there's all sorts of room for optimization
since I've been looking at functionality with clarity first.

Hmmm ... I need to look and see what, if any, support JRuby has for dtrace.
MRI does, but since the thread model for MRI is green, I'm not sure how much
performance data one can get out of dtrace in that context (works great for
tracing messages, though.)

If I had any spare time, I'd love to port the dtrace gem to java/jruby. And
a pony.


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Chuck Remes  
View profile  
 More options Sep 30 2008, 5:17 pm
From: Chuck Remes <cremes.devl...@mac.com>
Date: Tue, 30 Sep 2008 16:17:27 -0500
Local: Tues, Sep 30 2008 5:17 pm
Subject: Re: forwarding #respond_to? to the proxied object

On Sep 30, 2008, at 3:41 PM, Steven Parkes wrote:

>> I've been playing around with this today. I had trouble
>> getting it to
>> work (the respond_to?(:update) check was failing)

> I still don't understand why this is the case. The specs run fine,  
> so I'm
> wondering what is different.

I don't either. I now consider this a ruby bug in the Observable  
module, so I have "corrected" it in all my copies. I'll send a patch  
upstream and see if it gets accepted.

>> I see about a 5 to 7 millisecond overhead for the
>> asynch call to
>> return

> So you're just timing the notify_observer call, using a release  
> name, right?
> Just that one single operation?

Well, in a word, no. But I made a mistake which may render this moot.  
In my earlier email I said I was using jruby 1.1.4 when in fact I was  
using a trunk version post-1.1.4. I backed it out to the latest  
release and now all the calls are in the 300 to 700 microsecond range  
which is *much* better. I also had some crashing under the trunk  
version that I do not have now (I was getting  
java.nio.BufferOverflowException errors when writing to a file).

I'll have to look at that a bit deeper so jruby doesn't have  
regressions before they cut the 1.1.5 release.

I'll also time that one specific call to see how expensive it is as an  
asynch call versus a synchronous call.

> I'll look at it. It's likely there's all sorts of room for  
> optimization
> since I've been looking at functionality with clarity first.

This may not be low-hanging fruit anymore now that I went back to the  
1.1.4 jruby release. If you have other areas you wanted to focus on  
first, it's probably safe to do so. Sorry for (almost) sending you on  
a wild goose chase. I'll be more careful in the future.

> Hmmm ... I need to look and see what, if any, support JRuby has for  
> dtrace.
> MRI does, but since the thread model for MRI is green, I'm not sure  
> how much
> performance data one can get out of dtrace in that context (works  
> great for
> tracing messages, though.)

> If I had any spare time, I'd love to port the dtrace gem to java/
> jruby. And
> a pony.

Ponies are a lot of work. May I suggest a turtle? :)

cr


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Steven Parkes  
View profile  
 More options Sep 30 2008, 5:40 pm
From: "Steven Parkes" <smpar...@smparkes.net>
Date: Tue, 30 Sep 2008 14:40:01 -0700
Local: Tues, Sep 30 2008 5:40 pm
Subject: RE: forwarding #respond_to? to the proxied object

> I don't either. I now consider this a ruby bug in the Observable  
> module, so I have "corrected" it in all my copies. I'll send a patch  
> upstream and see if it gets accepted.

Yeah, the check is (arguably) a misfeature, but it should work under
dramatis ... unless you're passing the release name to add_observer ...
which now that I think of it, that sounds like you're doing? That definitely
won't work: the observered will use that name and thus make an async call to
#respond_to?, which will always return nil.

If that's the case, we at least know what's going on. I don't like
mysteries. In code.

> I backed it out to the latest  
> release and now all the calls are in the 300 to 700
> microsecond range  
> which is *much* better.

Agreed. Almost a little too much better, but, then, it is only queuing the
task. You mentioned a thread getting spun up, and this may or may not happen
(depends on whether there are pooled threads available) but in any case,
your caller doesn't do the spin-up. It's handled by the scheduler which has
its own thread. Your calling thread should only awaken the scheduler, and
that only if it's gone to sleep with nothing to do. Actually, you might
actually start the scheduler, if it's not there yet (it gets started on
demand). In any case, only the scheduler actually creates actor threads.

That said, your call/thread (at this point) does pay the cost of determining
if the receiver is available to accept the message immediately: that is,
it's not already executing something and the actor's selective receive gate
allows it through. It needs to do this because it only awakens the scheduler
if the scheduler should activate the actor. Otherwise, it just pushes the
task on the actor's queue for later consideration.  That gate check is one
of the things I want to look at.

> I'll also time that one specific call to see how expensive it
> is as an  
> asynch call versus a synchronous call.

Yeah. That's a different kettle of fish. A sync call includes several thread
switches.

> This may not be low-hanging fruit anymore

Think of the dramatis tree as laden with low hanging fruit at this point.
I'm happy to work in the areas where overripe fruit is about to fall on
someone's head. Message queuing and dispatch are probably the most
interesting computation parts at this point, given the complexity of
selective receive.

> Ponies are a lot of work. May I suggest a turtle? :)

Hah. Made me laugh. Thanks.

 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Chuck Remes  
View profile  
 More options Oct 2 2008, 6:38 pm
From: Chuck Remes <cremes.devl...@mac.com>
Date: Thu, 02 Oct 2008 17:38:20 -0500
Local: Thurs, Oct 2 2008 6:38 pm
Subject: Re: forwarding #respond_to? to the proxied object

On Sep 30, 2008, at 4:40 PM, Steven Parkes wrote:

Wow, I need to double check my work before I post (see below too). I  
was calling #add_observer with #release which is why that was failing.  
You nailed it in one.

>> I backed it out to the latest
>> release and now all the calls are in the 300 to 700
>> microsecond range
>> which is *much* better.

> Agreed. Almost a little too much better, but, then, it is only  
> queuing the
> task.

<sigh>
I did a bunch of benchmarking yesterday and today. Here are my results.

synchronous actor (not called with #release)
30 to 45 ms per call
40% CPU charge for the process

asynchronous actor (called with #release)
4 to 8 ms per call
10% CPU charge for the process

synchronous non-actor
0.2 to 15 ms per call
4% CPU charge

dummy/empty method
(I commented out the call to the actor/non-actor and measured the  
overhead of the surrounding code)
200 to 500 microseconds

So, my last email misstated the overhead for the call to an asynch  
actor. The overhead of calling #update on a released actor ranges from  
3.5 ms to 7.8 ms as near as I can tell (4 ms minus 500 microseconds).  
That's pretty heavy.

My code is invoked on average about every 50 milliseconds. Sometimes  
it is called as quickly as every 150 microseconds. The vast majority  
of these calls result in very little work, so it finished in around  
200 microseconds. Every 50th (or 100th or 400th, user configurable)  
call, it has to do quite a bit more work. This invocation takes  
between 9 and 15 ms. This is the one I wanted to speed up because I  
don't want to miss another signal by "blocking" for 9 to 15 ms;  
turning it into an asynch call would allow me to return control to the  
event handler quicker so I wouldn't miss any transient signals.

Moving to an asynch actor slows down my most common case by an order  
of magnitude. It "speeds up" the less common case by allowing control  
to return to the program faster (4 to 8 ms versus 9 to 15 ms) but the  
juice ain't worth the squeeze right now. I'll need to stick to my non-
actor configuration until I get a chance to look at the scheduler and  
look for optimizations.

Yes, as evidenced by the benchmark results posted above. Using an  
actor synchronously isn't an option for me at all.

>> This may not be low-hanging fruit anymore

> Think of the dramatis tree as laden with low hanging fruit at this  
> point.
> I'm happy to work in the areas where overripe fruit is about to fall  
> on
> someone's head. Message queuing and dispatch are probably the most
> interesting computation parts at this point, given the complexity of
> selective receive.

Looks like it still needs some TLC. I will start poking at it early  
next week... the remainder of this week is doing some cleanup on  
failing tests that have been failing for too long. Gotta get all that  
code tightened up again. :(

cr


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Steven Parkes  
View profile  
 More options Oct 2 2008, 8:13 pm
From: "Steven Parkes" <smpar...@smparkes.net>
Date: Thu, 2 Oct 2008 17:13:46 -0700
Local: Thurs, Oct 2 2008 8:13 pm
Subject: RE: forwarding #respond_to? to the proxied object

> I did a bunch of benchmarking yesterday and today. Here are
> my results.

Well, this is a bit more of what I expected ...

> synchronous actor (not called with #release)

This is a very complex operation, including two message queues and a few
thread context switches. It's always going to be much worse than a function
call, using any thread mechanism.

> 30 to 45 ms per call
> 40% CPU charge for the process

What exactly do these numbers mean? 30-45 ms is the delta of the time before
and after the call? That makes sense, but what is CPU charge?

> 3.5 ms to 7.8 ms as near as I can tell (4 ms minus 500 microseconds).

So, you're talking about a factor of 8, right?

It can be improved, I'm sure, but I'm not sure how much. I don't actually
know how long Java's synchronization primitives take and how well they're
handled in JRuby.

But at least now we have some interesting questions for which someone cares
about the answers.


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Chuck Remes  
View profile  
 More options Oct 2 2008, 8:50 pm
From: Chuck Remes <cremes.devl...@mac.com>
Date: Thu, 02 Oct 2008 19:50:27 -0500
Local: Thurs, Oct 2 2008 8:50 pm
Subject: Re: forwarding #respond_to? to the proxied object

On Oct 2, 2008, at 7:13 PM, Steven Parkes wrote:

>> 30 to 45 ms per call
>> 40% CPU charge for the process

> What exactly do these numbers mean? 30-45 ms is the delta of the  
> time before
> and after the call? That makes sense, but what is CPU charge?

All of these numbers are referring to the duration of the call. I  
saved the time before the method call and computed the duration of it.

"CPU charge" is the percentage of CPU consumed by the process as  
reported by top.

>> 3.5 ms to 7.8 ms as near as I can tell (4 ms minus 500 microseconds).

> So, you're talking about a factor of 8, right?

Yes.

> It can be improved, I'm sure, but I'm not sure how much. I don't  
> actually
> know how long Java's synchronization primitives take and how well  
> they're
> handled in JRuby.

> But at least now we have some interesting questions for which  
> someone cares
> about the answers.

Cool, I'll help.

cr


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Steven Parkes  
View profile  
 More options Oct 3 2008, 12:30 am
From: "Steven Parkes" <smpar...@smparkes.net>
Date: Thu, 2 Oct 2008 21:30:46 -0700
Local: Fri, Oct 3 2008 12:30 am
Subject: RE: forwarding #respond_to? to the proxied object
This is really kind of fun.

You have to be pretty careful about letting jruby warm up. With the pingpong
example, it's kinda fun because it gets faster the longer it runs and since
pingpong prints out a message periodically, you can see it happen.

This is on a slightly optimized version which I'll check in, but I suspect
the changes aren't terribly relevant (they're about a 15% speedup on
pingpong.)

With the jruby warm up, when I run an instrumented version of pingpoing, the
first release call takes 2.5ms on a 2GHz Opteron. The last call (when doing
5000 volleys) takes 250us.

It's not possible to do a head-to-head comparison with the serial code since
the latter is recursive. But if you step back and average the wall clock
time against the number of volleys for a large number of volleys, the actor
version ends up averaging less that 220us per call. That's the sum of the
send, the (implicit) receive, and the task execution (which just sends
another message, but that's removed by the average).

The serial code gets as low as 62us per volley on average, so there's still
a factor of 4 here, which, since the pingpong tasks don't do anything, isn't
that bad (if I haven't messed up my interpretation). This kind of a
worst-case grain-size.

This is all with JRuby 1.1.4, Sun JDK 1.6.0.07, and giving JRuby -J-server
-J-Xss512m.

As a comparison, 1.8.6 can get the serial code as low as 13us per volley.
The actor version runs at about 315us per volley (everybody seems to know
1.8.6 threads have some real limitations ...)

Under (some version of) 1.9, the serial code gets as low as 6us per volley
and the actor version, 100us per volley.

This is all very preliminary, of course ...


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
End of messages
« Back to Discussions « Newer topic     Older topic »