Module: Forkoff

Extended by:
Forkoff
Included in:
Forkoff
Defined in:
lib/forkoff.rb

Defined Under Namespace

Classes: Error

Instance Method Summary collapse

Instance Method Details

#defaultObject


16
17
18
# File 'lib/forkoff.rb', line 16

def default
  @default ||= { 'processes' => 2 }
end

#doneObject


8
9
10
# File 'lib/forkoff.rb', line 8

def done
  @done ||= Object.new
end

#fileObject


24
25
26
# File 'lib/forkoff.rb', line 24

def file 
  'file'
end

#file_result(*args, &block) ⇒ Object


111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
# File 'lib/forkoff.rb', line 111

def file_result *args, &block
  tmpfile do |fd|
    pid = fork

    unless pid
      result =
        begin
          block.call(*args)
        rescue Object => e
          e
        end
      fd.write( Marshal.dump( result ) )
      exit
    end

    Process.waitpid pid
    fd.rewind
    data = fd.read
    result = Marshal.load( data )
    return result
  end
end

#hostnameObject


40
41
42
43
# File 'lib/forkoff.rb', line 40

def hostname
  require 'socket'
  @hostname ||= (Socket.gethostname rescue 'localhost.localdomain')
end

#pidObject


28
29
30
# File 'lib/forkoff.rb', line 28

def pid
  @pid ||= Process.pid
end

#pipeObject


20
21
22
# File 'lib/forkoff.rb', line 20

def pipe
  'pipe'
end

#pipe_result(*args, &block) ⇒ Object


83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/forkoff.rb', line 83

def pipe_result *args, &block
  r, w = IO.pipe
  pid = fork

  unless pid
    r.close
    result =
      begin
        block.call(*args)
      rescue Object => e
        e
      end
    w.write( Marshal.dump( result ) )
    w.close
    exit
  end

  w.close
  data = ''
  while(( buf = r.read(8192) ))
    data << buf
  end
  result = Marshal.load( data )
  r.close
  Process.waitpid pid
  return result
end

#ppidObject


32
33
34
# File 'lib/forkoff.rb', line 32

def ppid
  @ppid ||= Process.ppid
end

#readyObject


12
13
14
# File 'lib/forkoff.rb', line 12

def ready
  @ready ||= Object.new
end

#tidObject


36
37
38
# File 'lib/forkoff.rb', line 36

def tid
  Thread.current.object_id.abs
end

#tmpdirObject


45
46
47
48
# File 'lib/forkoff.rb', line 45

def tmpdir
  require 'tmpdir'
  @tmpdir ||= Dir.tmpdir
end

#tmpdir=(tmpdir) ⇒ Object


50
51
52
# File 'lib/forkoff.rb', line 50

def tmpdir= tmpdir
  @tmpdir = tmpdir.to_s
end

#tmpfile(&block) ⇒ Object

Raises:


54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/forkoff.rb', line 54

def tmpfile &block
  basename = [hostname, pid, ppid, tid, rand].join('-') 
  tmp = File.join(tmpdir, basename)

  fd = nil
  flags = File::CREAT|File::EXCL|File::RDWR

  42.times do
    begin
      fd = open tmp, flags
      break
    rescue Object
      sleep rand
    end
  end
  raise Error, "could not create tmpfile" unless fd

  if block
    begin
      return block.call(fd)
    ensure
      fd.close unless fd.closed? rescue nil
      FileUtils.rm_rf tmp rescue nil
    end
  else
    return fd
  end
end

#versionObject


4
5
6
# File 'lib/forkoff.rb', line 4

def version
  '1.1.0'
end