Project

General

Profile

Actions

Feature #4649

closed

Adding parallel constructors to Ruby 2.0

Added by rosenfeld (Rodrigo Rosenfeld Rosas) almost 13 years ago. Updated over 11 years ago.

Status:
Rejected
Target version:
-
[ruby-core:36013]

Description

I was not sure if this was RubySpec or Feature type.

My request is to create some new syntax for easing the write of concurrent code with Ruby. The syntax could be something like this:

parallels do
task "get response from service A" do # optional description
a = IO.read("http://serviceA/request")
end
task { b = get_response_from_service_b }
end

at this point both tasks have finish, it's like a join in the threads at the end of the parallel block.

call_another_service_that_depends_on(a and b)

I am not sure, though, how to deal with scopes inside the parallel block. Traditionally in Ruby, this wouldn't work because both 'a' and 'b' would be local to the 'task' block and would not be accessible from the outside of the parallel block. If we don't want instance variables, I don't know what is the best approach for avoiding some "a=nil; b=nil" before the parallel block.

Maybe this could start as a gem, but having it implemented directly in Ruby would be awesome, specially for scripts that usually don't rely in external dependencies for simplifying distribution...

Any thoughts about this propose?


Files

feature-4649.odp (18.1 KB) feature-4649.odp Slide for presentation to Matz rosenfeld (Rodrigo Rosenfeld Rosas), 06/08/2012 03:22 AM
Actions #1

Updated by vjoel (Joel VanderWerf) almost 13 years ago

IMO this is not really about parallel computation, but about syntax and scope, and it can be solved without changing ruby.

One solution that seems fairly idiomatic to me is:

def get_response_from_service_a; "a response"; end
def get_response_from_service_b; "b response"; end

class Parallels
def initialize
@tasks = []
end
def task &task
@tasks << Thread.new(&task)
end
def values
@tasks.map {|task| task.value}
end
end

def parallels &task_block
par = Parallels.new
par.instance_eval &task_block
par.values
end

a, b = parallels do
task { get_response_from_service_a }
task { get_response_from_service_b }
end

p a, b

Updated by rosenfeld (Rodrigo Rosenfeld Rosas) almost 13 years ago

You're right Joel. Maybe the syntax I'm requesting to be included in standard Ruby should be something like:

concurrently do
task {...}
...
end

But, although the implementation is simple, having a standard idiom for that common requirement would be great. That means I wouldn't have to redefine this idiom not to rely on external gem while doing some scripting... Other than that, making it a language feature could allow some low level improvements in performance, but it is just a guess since I don't know how this could be achieved yet.

Furthermore, depending on the specs, maybe it wouldn't be necessary to do something like "a, b = concurrently do...". Being a standard idiom, someone looking at a code like this would know for sure what is happening since it is a language feature instead of an external dependency...

Also, my initial example was too simple, but I imagine possibly several variables inside each task that should be available at the end of the parallels/concurrently block.

Actions #3

Updated by naruse (Yui NARUSE) almost 13 years ago

  • Tracker changed from Misc to Feature
Actions #4

Updated by naruse (Yui NARUSE) over 12 years ago

  • Project changed from Ruby master to 14
  • Target version deleted (3.0)
Actions #5

Updated by naruse (Yui NARUSE) over 12 years ago

  • Project changed from 14 to Ruby master
Actions #6

Updated by shyouhei (Shyouhei Urabe) about 12 years ago

  • Status changed from Open to Assigned

Updated by mame (Yusuke Endoh) almost 12 years ago

Received.

You want just Kernel#concurrently and Kernel#task?
And, Kernel#concurrently returns an array that contains the result values returned by inside Kernel#tasks. Right?
The array may be shuffled, or in the same order as task definitions?

ary = concurrently do
task { 1 }
task { 2 }
task { 3 }
end
p ary #=> [1, 2, 3]

--
Yusuke Endoh

Updated by rosenfeld (Rodrigo Rosenfeld Rosas) almost 12 years ago

If we're going to care about the results of the tasks, which I think it is a good idea, although it was really yours and not mine, it only makes sense to me for the array to have the results in the same order as the tasks were defined, right?

Updated by mame (Yusuke Endoh) over 11 years ago

  • Status changed from Assigned to Rejected

Rodrigo Rosenfeld Rosas,

Sorry but this proposal was rejected at the developer meeting (7/21).

Please start it as a gem. Matz might reconsider this proposal if
your gem really becomes popular or even de facto.

--
Yusuke Endoh

Updated by rosenfeld (Rodrigo Rosenfeld Rosas) over 11 years ago

Okay, thanks for considering it :)

Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0