fork_buddy 0.0.1 → 0.0.2

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.
@@ -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