Method: Parallel::ForkManager#finish

Defined in:
lib/parallel/forkmanager.rb

#finish(exit_code = 0, data_structure = nil) ⇒ Object

finish(exit_code, [data_structure]) – exit_code is optional

finish() closes the child process by exiting and accepts an optional exit code (default exit code is 0) which can be retrieved in the parent via callback. If you’re running the program in debug mode (max_proc == 0), this method just calls the callback.

If data_structure is provided, then data structure is serialized and passed to the parent process. See Retrieving Data Structures in the next section for more info. For example:

%w{Fred Wilma Ernie Bert Lucy Ethel Curly Moe Larry}.each {
    |person|
    # pm.start(...) here

    # ... etc ...

    # Pass along data structure to finish().
    pm.finish(0, {'person' => person})
}

Retrieving Data Structures

The ability for the parent to retrieve data structures from child processes was adapted to Parallel::ForkManager 1.5.0 (and newer) from Perl Parallel::ForkManager. This functionality was originally introduced in Perl Parallel::ForkManager 0.7.6.

Each child process may optionally send 1 data structure back to the parent. By data structure, we mean a a string, hash, or array. The contents of the data structure are written out to temporary files on disk using the Marshal dump() method. This data structure is then retrieved from within the code you send to the run_on_finish callback.

NOTE NOTE NOTE: Only serialization with Marshal and yaml are supported at this time. Future versions of Parallel::ForkManager may support expanded functionality!

There are 2 steps involved in retrieving data structures:

  1. The data structure the child wishes to send back to the parent is provided as the second argument to the finish() call. It is up to the child to decide whether or not to send anything back to the parent.

  2. The data structure is retrieved using the callback provided in the run_on_finish() method.

Data structure retrieval is not the same as returning a data structure from a method call! The data structure referenced by a given child process is serialized and written out to a file in the type specified earlier in serialize_as. If serialize_as was not specified earlier, then no serialization will be done.

The file is subseqently read back into memory and a new data structure that belongs to the parent process is created. Therefore it is recommended that you keep the returned structure small in size to mitigate any possible performance penalties.



249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
# File 'lib/parallel/forkmanager.rb', line 249

def finish(exit_code = 0, data_structure = nil)
  if @has_block
    fail "Do not use finish(...) when using blocks.  Use an explicit exit in your block instead!\n"
  end

  if in_child
    exit_code ||= 0

    unless data_structure.nil?
      @data_structure = data_structure

      the_tempfile = "#{@tempdir}Parallel-ForkManager-#{@parent_pid}-#{$PID}.txt"

      begin
        fail "Unable to serialize data!" unless _serialize_data(the_tempfile)
      rescue => e
        puts "Unable to store #{the_tempfile}: #{e.message}"
        exit 1
      end
    end

    Kernel.exit!(exit_code)
  end

  if @max_procs == 0
    on_finish($PID, exit_code, @processes[$PID], 0, 0)
    @processes.delete($PID)
  end
  0
end