process_starter 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. data/lib/process_starter.rb +90 -0
  2. metadata +67 -0
@@ -0,0 +1,90 @@
1
+ # 2012 (c) LineAct / www.lineact.com
2
+
3
+ module ProcessStarter
4
+ begin require 'posix/spawn' rescue LoadError; end
5
+
6
+ WINRUN = (RUBY_PLATFORM =~ /mswin|mingw/) ? true : false # run in windows?
7
+ HAVE_SPAWN = defined?(spawn) # have Ruby 1.9 spawn method
8
+ HAVE_POSIX_SPAWN = defined?(POSIX::Spawn::spawn) # loaded posix/spawn lib
9
+
10
+ def log(m)
11
+ defined?(RAILS_DEFAULT_LOGGER) ? RAILS_DEFAULT_LOGGER.info(m) : puts m
12
+ end
13
+
14
+ # Starts the process
15
+ # not waiting for it's finish, so child process run in parralel
16
+ # not inheritting file descriptors, so it finds and closes all opened handels
17
+ # works in windows and linux
18
+ def self.start(s)
19
+ log.info "**************** INVOKING EXTERNAL COMMAND #{s}, WINRUN IS #{WINRUN}, HAVE_POSIX_SPAWN IS #{HAVE_POSIX_SPAWN}, HAVE_SPAWN is #{HAVE_SPAWN}"
20
+ if WINRUN
21
+ if system("psexec -d #{s}")
22
+ log.info "Executed using PSEXEC"
23
+ elsif system("start cmd /c #{s}")
24
+ log.info "Executed using START cmd /c (inherits descriptors (?) - bad)"
25
+ else
26
+ log.info "Execute failed!"
27
+ end
28
+ else
29
+ log.info "Executing in Linux style"
30
+ if HAVE_POSIX_SPAWN
31
+ close_them = Hash[ close_io().map {|x| [x, :close]} ]
32
+ log.info "POSIX::Spawn::spawn with close descriptors: #{close_them.inspect}"
33
+ pid = POSIX::Spawn::spawn( s, close_them)
34
+ elsif HAVE_SPAWN
35
+ # we hope on http://www.ruby-doc.org/core-1.9.3/Process.html#method-c-spawn
36
+ # [close_others => true] option
37
+ # TODO: check it
38
+ log.info "Ruby 1.9 spawn"
39
+ spawn( s )
40
+ else
41
+ log.info "fork{ close_io; exec }"
42
+ Process.detach fork{
43
+ close_io(true)
44
+ exec(s)
45
+ }
46
+ end
47
+
48
+ end
49
+ end
50
+
51
+ # based on close_io from: http://daemons.rubyforge.org/Daemonize.html
52
+ def self.close_io( do_close=false )
53
+ close_them = []
54
+ # Make sure all input/output streams are closed
55
+ # Part I: close all IO objects (except for STDIN/STDOUT/STDERR)
56
+ ObjectSpace.each_object(IO) do |io|
57
+ unless [STDIN, STDOUT, STDERR].include?(io)
58
+ begin
59
+ # puts "os #{io.to_i}, and="
60
+ # puts io.fcntl(Fcntl::F_GETFD) & Fcntl::FD_CLOEXEC
61
+ if (not io.closed?) and (io.fcntl(Fcntl::F_GETFD) & Fcntl::FD_CLOEXEC) == 0
62
+ close_them << io.to_i
63
+ io.close if do_close
64
+ end
65
+ rescue ::Exception
66
+ end
67
+ end
68
+ end
69
+ # puts close_them.inspect
70
+
71
+ # Make sure all input/output streams are closed
72
+ # Part II: close all file decriptors (except for STDIN/STDOUT/STDERR)
73
+ ios = Array.new(8192) {|i| IO.for_fd(i) rescue nil}.compact
74
+ ios.each do |io|
75
+ # puts "qqq"
76
+ # puts io.to_i
77
+ next if io.fileno < 3
78
+ # puts "checking flag"
79
+ # puts io.fcntl(Fcntl::F_GETFD) & Fcntl::FD_CLOEXEC
80
+ next if (io.fcntl(Fcntl::F_GETFD) & Fcntl::FD_CLOEXEC != 0)
81
+ # puts "adding"
82
+ close_them << io.to_i
83
+ io.close if do_close
84
+ end
85
+ # puts close_them.inspect
86
+
87
+ close_them.uniq
88
+ end
89
+
90
+ end
metadata ADDED
@@ -0,0 +1,67 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: process_starter
3
+ version: !ruby/object:Gem::Version
4
+ hash: 23
5
+ prerelease:
6
+ segments:
7
+ - 1
8
+ - 0
9
+ - 0
10
+ version: 1.0.0
11
+ platform: ruby
12
+ authors:
13
+ - Pavel Vasev
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2012-09-21 00:00:00 +06:00
19
+ default_executable:
20
+ dependencies: []
21
+
22
+ description: A gem to start process in parallel plus dont inherit handles plus both in windows/linux plus learn me to make gems
23
+ email: pavel.vasev@gmail.com
24
+ executables: []
25
+
26
+ extensions: []
27
+
28
+ extra_rdoc_files: []
29
+
30
+ files:
31
+ - lib/process_starter.rb
32
+ has_rdoc: true
33
+ homepage: http://rubygems.org/gems/process_starter
34
+ licenses: []
35
+
36
+ post_install_message:
37
+ rdoc_options: []
38
+
39
+ require_paths:
40
+ - lib
41
+ required_ruby_version: !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ hash: 3
47
+ segments:
48
+ - 0
49
+ version: "0"
50
+ required_rubygems_version: !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ hash: 3
56
+ segments:
57
+ - 0
58
+ version: "0"
59
+ requirements: []
60
+
61
+ rubyforge_project:
62
+ rubygems_version: 1.5.2
63
+ signing_key:
64
+ specification_version: 3
65
+ summary: Hola!
66
+ test_files: []
67
+