Lazy.rb 0.9.5 -- transparent futures!

On Wed, 2006-02-22 at 06:49 +0900, Jim W. wrote:

MenTaLguY wrote:
The BlankSlate class in Builder handles this without resorting to the
“evil” that lies in the heart of evil.rb. And the CVS head version of
BlankSlate also handles the module hole Andrew mentioned earlier (I
think … I just now updated it).4

Hmm, that sounds more like it. Any chance of a separate BlankSlate gem?

-mental

MenTaLguY wrote:

On Tue, 2006-02-21 at 17:33 +0900, Andrew J. wrote:

But then I discovered that methods added by including a module weren’t
trapped by method_added – so in the end, a KernellessObject (from evil.rb)
was needed (same link as above) as Async’s parent to keep the proxy clean.

Hmm, good catch. Thanks!

I wonder if it’s worth introducing a dependency on evil.rb?

The BlankSlate class in Builder handles this without resorting to the
“evil” that lies in the heart of evil.rb. And the CVS head version of
BlankSlate also handles the module hole Andrew mentioned earlier (I
think … I just now updated it).4


– Jim W.

On Wed, 22 Feb 2006 06:49:11 +0900, Jim W. [email protected]
wrote:

MenTaLguY wrote:
[snip]

I wonder if it’s worth introducing a dependency on evil.rb?

The BlankSlate class in Builder handles this without resorting to the
“evil” that lies in the heart of evil.rb. And the CVS head version of
BlankSlate also handles the module hole Andrew mentioned earlier (I
think … I just now updated it).4

That does appear to plug it – and I even recall looking at
append_features back then and not seeing it. Thanks Jim!

andrew

James Edward G. II ha scritto:

Hmm, good catch. Thanks!

I wonder if it’s worth introducing a dependency on evil.rb?

maybe just making it optional… you could even make great use of
Object#become :slight_smile:

On Wed, 2006-02-22 at 04:01 +0900, Daniel N. wrote:

In that case, what I want (I’m so damn greedy :D) is to be able to
raise the exception immediately (in a case where you damned well know
that you’re going to need the value and would prefer to fail early)
and I see that that’s trivial to implement (just have a conditional
toss the exception up in the thread if some @raise_immediately flag is
set to true).

There’s one other thing I was wondering about: What’s the prudency of
adding a method to Future to allow the Future to go back to sleep
(release the lock, pass the thread)? In this case, I’m considering
waiting for a resource that some other future/thread might be using,
or waiting for a port to get some data. (mostly implementation details
for that library I mentioned, I’ll deal with them, but I’m curious if
there’s any issue I’m forgetting).

Hmm. Could you give me some examples of the behavior you have in mind?

-mental

On Wed, 2006-02-22 at 09:07 +0900, Daniel N. wrote:

What’s the purpouse of the spinlock in synchronize?

To keep a Future’s block from evaluating several times in parallel?

s/Future/Promise/, and you’ve got it.

It ensures that each promise only ever gets evaluated once, even when
multiple threads demand its result at the same time.

Nothing to do with futures in particular; I only require threadsafe for
futures because using futures guarantees that your program will have
multiple threads.

-mental

Actually, now I’m not so sure that I read that part either…

What’s the purpouse of the spinlock in synchronize?

To keep a Future’s block from evaluating several times in parallel?

I think I thought it was to keep several futures from evaluating at
the same time.

Right, then there’s no purpouse to being able to put the lock down. I
think I thought that the lock was class level instead of instance
level.

BTW: Could you point me in the direction of some circular programming
examples? It sounds like an interesting technique, but the papers on
the net all seem to be in post script and I don’t care to futz with
GhostWriter again.

MenTaLguY wrote:

On Wed, 2006-02-22 at 06:49 +0900, Jim W. wrote:

MenTaLguY wrote:
The BlankSlate class in Builder handles this without resorting to the
“evil” that lies in the heart of evil.rb. And the CVS head version of
BlankSlate also handles the module hole Andrew mentioned earlier (I
think … I just now updated it).4

Hmm, that sounds more like it. Any chance of a separate BlankSlate gem?

Ask and ye shall receive:

gem install blankslate --source http://onestepback.org/betagems

This is a quick breakout of the BlankSlate class into its own gem. It
now sits as a top level namespace (instead of being nested in the
Builder module). It is built from the same source as Builder, so the
builder gem still includes the class physically. (Shouldn’t be a
problem unless there start to be weird version mismatches).

There are still some documentation issues (e.g. the blankslate gem RDoc
still refers to the builder README file), but give this guy a spin
around the block before I make an official release.


– Jim W.

Le 21 févr. 06, à 21:55, Jim W. a écrit :

gem install blankslate --source http://onestepback.org/betagems

irb(main):004:0> require ‘blankslate’
LoadError: No such file to load – builder
from
/usr/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:18:in
require__' from /usr/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:18:in require’
from /usr/lib/ruby/site_ruby/1.8/rubygems.rb:163:in activate' from /usr/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:23:in require’
from (irb):4

Seems that the dependency on builder is still there.

Guillaume.

Hi,

I have a feature request (along with a quick-hack solution).

Please ignore if this is already done or sounds crazy. :slight_smile:

Problem: All the promises I make, cannot have any arguments ! !

So something like this is what I have in mind:

x = promise(“CUSTOMERS”) { |table_name|
long_running_query(table_name)}

Admitedly, in this one-liner it does not make much sense. But if the
block had many many lines of code and referred to the block variable at
multiple places, suddenly it would be mean more to me.

I have attached my hackish solution without really thinking all the
way thru.
Thanks,

– Shashank

MenTaLguY [email protected] wrote:
I’d like to announce a new version of lazy.rb – this one offering
thread safety and transparent futures!

Here’s the web site, complete with gem and tarball downloads, plus a bit
of documentation:

http://moonbase.rydia.net/software/lazy.rb/

Bug reports would be very, very welcome.

Guillaume M. wrote:

Le 21 f�vr. 06, � 21:55, Jim W. a �crit :

gem install blankslate --source http://onestepback.org/betagems

irb(main):004:0> require ‘blankslate’
LoadError: No such file to load – builder

Dang! Autorequire bit me again.

Ok, I think I fixed it. Give it another try.


– Jim W.

On Wed, 2006-02-22 at 15:27 +0900, Jim W. wrote:

Ok, I think I fixed it. Give it another try.

ERROR: While executing gem … (YAML::Error)
Invalid object explicitly tagged !ruby/Object: “requir”

-mental

On Wed, 2006-02-22 at 14:14 -0800, Shashank D. wrote:

Problem: All the promises I make, cannot have any arguments ! !

So something like this is what I have in mind:

x = promise(“CUSTOMERS”) { |table_name|
long_running_query(table_name)}

Hmm. Would this work?

table_name = “CUSTOMERS”
x = promise { long_running_query(table_name) }

-mental

MenTaLguY wrote:

On Wed, 2006-02-22 at 15:27 +0900, Jim W. wrote:

Ok, I think I fixed it. Give it another try.

ERROR: While executing gem … (YAML::Error)
Invalid object explicitly tagged !ruby/Object: “requir”

Ahhh … Interesting.

I’ve tracked this down to a corrupt compressed gem index on my beta
server. My home box wasn’t getting it because it uses a unreleased
version of RubyGems that does incremental downloads of the individual
gem specs rather than grabbing the massive gem index all the time.

This might also explain an unrelated issue I was having with testing
RubyGems. I think this bug has made my day.

Now all I have to do is fix it.

Thanks.


– Jim W.

Mental, could I perchance persuade you to add an optional parameter to
the Future initializer that accepts a block to be run inside the
rescue clause of the Future’s thread?

The situation I am specifically thinking of is this:

I have a number of objects that will want the value resulting from the
Future. I know all of these objects WILL need to access that value.
Because the computation in the Future is very expensive, I would like
to raise exceptions on those objects as soon as the thread is caught
so that they can begin handling the error as soon as possible.

So, at the time of the exception, I can lock down the current
subscribers list and then fire off the exception to each of them.
Something like this:

future(lambda{|exception| lock.synchronize{subscribers.each{|s|
s.raise(exception)}}}){holy_crap_long_execution}

Quoting Daniel N. [email protected]:

Mental, could I perchance persuade you to add an optional
parameter to
the Future initializer that accepts a block to be run inside the
rescue clause of the Future’s thread?

future(lambda{|exception| lock.synchronize{subscribers.each{|s|
s.raise(exception)}}}){holy_crap_long_execution}

How about:

future {
begin
holy_crap_long_execution
rescue Exception => exception
lock.synchronize do
subscribers.each { |s| s.raise( exception ) }
end
raise
end
}

?

That might be a bit longer, but it seems clearer what’s going on.

-mental

On Fri, 2006-02-24 at 10:13 +0900, Jim W. wrote:

Yep, it was a bug in the new RubyGems server-side indexing software.
Should be fixed now. Give it another try…

gem install blankslate -s http://onestepback.org/betagems

Hmm. Okay, for lazy.rb there are a couple things I would need from
BlankSlate:

  • the ability to “let through” a few additional methods
    (just Object#class at the moment, but there may be more later)

  • to be able to hide Object#instance_eval

Maybe the best thing would be a factory that creates customized
BlankSlate-like classes, roughly similar to the way Struct works.

Thoughts?

-mental

Jim W. wrote:

MenTaLguY wrote:

On Wed, 2006-02-22 at 15:27 +0900, Jim W. wrote:

Ok, I think I fixed it. Give it another try.

ERROR: While executing gem … (YAML::Error)
Invalid object explicitly tagged !ruby/Object: “requir”

Ahhh … Interesting.

I’ve tracked this down to a corrupt compressed gem index on my beta
server. My home box wasn’t getting it because it uses a unreleased
version of RubyGems that does incremental downloads of the individual
gem specs rather than grabbing the massive gem index all the time.

This might also explain an unrelated issue I was having with testing
RubyGems. I think this bug has made my day.

Now all I have to do is fix it.

Yep, it was a bug in the new RubyGems server-side indexing software.
Should be fixed now. Give it another try…

gem install blankslate -s http://onestepback.org/betagems


– Jim W.

Good idea, thanks!