fork_buddy 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,5 @@
1
+ require 'fork_buddy'
2
+
3
+ fb = ForkBuddy.new(socket: '/tmp/fork_buddy.sock', rails_env: 'test')
4
+
5
+ fb.acquire(:rspec_ready, rails_env: 'test')
@@ -0,0 +1,39 @@
1
+ require 'fork_buddy/server'
2
+
3
+ fbs = ForkBuddy::Server.start(socket: '/tmp/fork_buddy.sock') do
4
+ stage :initial {
5
+ option :rails_env
6
+ stage :require_bundler {
7
+ stage :require_application {
8
+ stage :application_loaded {
9
+ stage :rspec_ready
10
+ stage :cucumber_ready
11
+ }
12
+ }
13
+ }
14
+ }
15
+ end
16
+
17
+ fbs.stage(:initial)
18
+
19
+ require 'rubygems'
20
+ require 'bundler'
21
+
22
+ fbs.stage(:require_bundler)
23
+
24
+ Bundler.require :default, fbs.option(:rails_env)
25
+
26
+ fbs.stage(:require_application)
27
+
28
+ ENV['RAILS_ENV'] = fbs.option(:rails_env)
29
+ require 'application and stuff'
30
+
31
+ fbs.stage(:application_booted)
32
+
33
+ fbs.stage(:rspec_ready) do
34
+ require 'rspec/rails'
35
+ end
36
+
37
+ fbs.stage(:cucumber_ready) do
38
+ require 'cucumber/rails'
39
+ end
@@ -1,5 +1,106 @@
1
1
  require "fork_buddy/version"
2
+ require 'socket'
2
3
 
3
- module ForkBuddy
4
- # Your code goes here...
4
+ $_stack = []
5
+ $_children = []
6
+
7
+ module Kernel
8
+ alias_method :__fork, :fork
9
+ def fork(&block)
10
+ $_children ||= []
11
+ r = __fork(&block)
12
+ $_children << r
13
+ r
14
+ end
15
+ end
16
+
17
+ class ForkBuddy
18
+
19
+ class Server
20
+ def initialize
21
+ $socket, server = UNIXSocket.pair
22
+ if __fork
23
+ @processes = {}
24
+ begin
25
+ while line = server.recv(2**12) do
26
+ process_command(line)
27
+ end
28
+ ensure
29
+ @processes.each { |k, data|
30
+ Process.kill("QUIT", data[:pid])
31
+ }
32
+ end
33
+ end
34
+ end
35
+
36
+ def process_command(line)
37
+ data = Marshal.load(line)
38
+ puts "*** #{data.inspect}"
39
+
40
+ case data[:command]
41
+ when :register
42
+ data.delete(:command)
43
+ @processes[data[:forkpoint]] = data
44
+ when :invalidate
45
+ forkpoint = data[:forkpoint]
46
+ @processes.each { |k,v|
47
+ if k == forkpoint || v[:stack].include?(forkpoint)
48
+ Process.kill("QUIT", v[:pid])
49
+ v[:prune] = true
50
+ end
51
+ }
52
+
53
+ restart_forkpoint = @processes.find{|k,v|k==forkpoint}[1][:stack].first
54
+ restart = @processes.find{|k,v|k==restart_forkpoint}
55
+ @processes.reject!{|k,v|v[:prune]}
56
+
57
+ Process.kill("USR1", restart[1][:pid])
58
+ end
59
+ end
60
+
61
+ def forkpoint(sym, &block)
62
+ loop do
63
+ if pid = __fork
64
+ data = {
65
+ command: :register,
66
+ forkpoint: sym,
67
+ stack: $_stack,
68
+ pid: pid
69
+ }
70
+ $socket.send Marshal.dump(data), 0
71
+
72
+ # Spin until sent the USR1 signal, then run the next iteration of the loop.
73
+ Kernel.trap("USR1") { throw(:next) }
74
+ Kernel.trap("USR2") {
75
+ # Inject code somehow.
76
+ }
77
+ catch(:next) { loop { sleep 10 } }
78
+ else
79
+ forkpoint_child(block, sym)
80
+ exit(0) # end of execution reached
81
+ end
82
+ end
83
+ end
84
+
85
+ def forkpoint_child(block, sym)
86
+ Kernel.trap("QUIT") {
87
+ ($_children||[]).each { |child|
88
+ puts "*** REAPING: #{child}"
89
+ Process.kill("KILL", child) rescue nil
90
+ }
91
+ exit
92
+ }
93
+ $_stack.unshift sym
94
+ block.call
95
+ end
96
+
97
+ def invalidate(sym)
98
+ data = {
99
+ command: :invalidate,
100
+ forkpoint: sym
101
+ }
102
+ $socket.send Marshal.dump(data), 0
103
+ end
104
+
105
+ end
5
106
  end
@@ -1,3 +1,3 @@
1
1
  module ForkBuddy
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
File without changes
File without changes
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fork_buddy
3
3
  version: !ruby/object:Gem::Version
4
- hash: 29
4
+ hash: 27
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 1
10
- version: 0.0.1
9
+ - 2
10
+ version: 0.0.2
11
11
  platform: ruby
12
12
  authors:
13
13
  - Burke Libbey
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-08-19 00:00:00 Z
18
+ date: 2011-08-20 00:00:00 Z
19
19
  dependencies: []
20
20
 
21
21
  description: Write a gem description
@@ -31,9 +31,13 @@ files:
31
31
  - .gitignore
32
32
  - Gemfile
33
33
  - Rakefile
34
+ - example-client.rb
35
+ - example.rb
34
36
  - fork_buddy.gemspec
35
37
  - lib/fork_buddy.rb
36
38
  - lib/fork_buddy/version.rb
39
+ - spec/fork_buddy_spec.rb
40
+ - spec/spec_helper.rb
37
41
  homepage: ""
38
42
  licenses: []
39
43
 
@@ -67,5 +71,6 @@ rubygems_version: 1.7.2
67
71
  signing_key:
68
72
  specification_version: 3
69
73
  summary: Write a gem summary
70
- test_files: []
71
-
74
+ test_files:
75
+ - spec/fork_buddy_spec.rb
76
+ - spec/spec_helper.rb