12

I have a the following code:

FTP ... do |ftp| 
  files.each do |file| 
  ...
  ftp.put(file)
  sleep 1
  end 
end 

I'd like to run the each file in a separate thread or some parallel way. What's the correct way to do this? Would this be right?

Here's my try on the parallel gem

FTP ... do |ftp| 
  Parallel.map(files) do |file| 
  ...
  ftp.put(file)
  sleep 1
  end 
end 

The issue with parallel is puts/outputs can occur at the same time like so:

as = [1,2,3,4,5,6,7,8]
results = Parallel.map(as) do |a|
  puts a
end

How can I force puts to occur like they normally would line separated.

3
  • Usually I use threach, which uses SizedQueues hence allows you to execute a maximum amount of parallel jobs at time (peach does it too) Commented Apr 1, 2014 at 22:12
  • I just tried parallel looks but not sure if it works correctly yet. Commented Apr 1, 2014 at 22:16
  • parallel seems nice, I didn't know it, thank you Commented Apr 1, 2014 at 22:17

2 Answers 2

5

The whole point of parallelization is to run at the same time. But if there's some part of the process that you'd like to run some of the code sequentially you could use a mutex like:

semaphore = Mutex.new
as = [1,2,3,4,5,6,7,8]
results = Parallel.map(as, in_threads: 3) do |a|
  # Parallel stuff
  sleep rand
  semaphore.synchronize {
    # Sequential stuff
    puts a
  }
  # Parallel stuff
  sleep rand
end

You'll see that it prints stuff correctly but not necesarily in the same order. I used in_threads instead of in_processes (default) because Mutex doesn't work with processes. See below for an alternative if you do need processes.

References:

Sign up to request clarification or add additional context in comments.

Comments

0

In the interest of keeping it simple, here's what I'd do with built-in Thread:

results = files.map do |file|
  result = Thread.new do
    ftp.put(file)
  end
end

Note that this code assumes that ftp.put(file) returns safely. If that isn't guaranteed, you'll have to do that yourself by wrapping calls in a timeout block and have each thread return an exception if one is thrown and then at the very end of the loop have a blocking check to see that results does not contain any exceptions.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.