pry-em 0.1.1 → 0.2.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.
- data/lib/pry-em.rb +88 -38
- metadata +12 -10
data/lib/pry-em.rb
CHANGED
@@ -1,45 +1,84 @@
|
|
1
1
|
EmCommands = Pry::CommandSet.new do
|
2
2
|
|
3
|
-
|
4
|
-
EM_CONFIG = {
|
5
|
-
:keep_retval => true,
|
6
|
-
:interpolate => false,
|
7
|
-
:listing => "em",
|
8
|
-
:requires_gem => 'eventmachine'
|
9
|
-
}
|
10
|
-
|
11
|
-
command /\s*em\s*([0-9\.]*)\s*:(.*)/, EM_DESCRIPTION, EM_CONFIG do |timeout, source|
|
12
|
-
|
13
|
-
# Boot EM before eval'ing the source as it's likely to depend on the reactor.
|
14
|
-
run_em_if_necessary!
|
15
|
-
|
16
|
-
# This can happen for example if you do:
|
17
|
-
# em: EM::HttpRequest.new("http://www.google.com/").get.callback{ binding.pry }
|
18
|
-
# There ought to be a solution, but it will involve shunting either Pry or EM
|
19
|
-
# onto a new thread.
|
20
|
-
if EM.reactor_thread == Thread.current
|
21
|
-
raise "Could not wait for deferrable, you're in the EM thread!
|
22
|
-
If you don't know what to do, try `cd ..`, or just hit ctrl-C until it dies."
|
23
|
-
end
|
3
|
+
create_command /\s*em\s*([0-9\.]*)\s*:(.*)/ do
|
24
4
|
|
25
|
-
deferrable
|
5
|
+
description "Wait for a deferrable for a length of time (default 3 seconds). `em 3: EM::HttpRequest.new(url).get`"
|
6
|
+
options(
|
7
|
+
:keep_retval => true,
|
8
|
+
:interpolate => false,
|
9
|
+
:listing => "em",
|
10
|
+
:requires_gem => 'eventmachine'
|
11
|
+
)
|
26
12
|
|
27
|
-
|
28
|
-
|
13
|
+
def process(timeout, source)
|
14
|
+
# We store the retval and the em-state in globals so that we can catch exceptions
|
15
|
+
# raised in the event loop and pass them back pretending to the user that the
|
16
|
+
# exception was caused by their currently executing command.
|
17
|
+
#
|
18
|
+
# We don't want to keep turning the reactor on and off, as that would limit some
|
19
|
+
# of the things the user might want to do.
|
20
|
+
@@retval, @@em_state = [nil, :waiting]
|
29
21
|
|
30
|
-
|
31
|
-
|
22
|
+
# Boot EM before eval'ing the source as it's likely to depend on the reactor.
|
23
|
+
run_em_if_necessary!
|
24
|
+
|
25
|
+
# This can happen for example if you do:
|
26
|
+
# em: EM::HttpRequest.new("http://www.google.com/").get.callback{ binding.pry }
|
27
|
+
# There ought to be a solution, but it will involve shunting either Pry or EM
|
28
|
+
# onto a new thread.
|
29
|
+
if EM.reactor_thread == Thread.current
|
30
|
+
raise "Could not wait for deferrable, you're in the EM thread!
|
31
|
+
If you don't know what to do, try `cd ..`, or just hit ctrl-C until it dies."
|
32
|
+
end
|
33
|
+
|
34
|
+
deferrable = target.eval(source)
|
35
|
+
|
36
|
+
# TODO: Allow the user to configure the default timeout
|
37
|
+
timeout = timeout == "" ? 3 : Float(timeout)
|
38
|
+
|
39
|
+
wait_for_deferrable(deferrable, timeout) unless deferrable.nil?
|
40
|
+
end
|
32
41
|
|
33
|
-
helpers do
|
34
42
|
# Boot a new EventMachine reactor into another thread.
|
35
43
|
# This allows us to continue to interact with the user on the front-end thread,
|
36
44
|
# while they run event-machine commands in the background.
|
37
45
|
def run_em_if_necessary!
|
38
46
|
require 'eventmachine' unless defined?(EM)
|
39
|
-
|
47
|
+
unless EM.reactor_running?
|
48
|
+
Thread.new do
|
49
|
+
EM.error_handler{ |e| handle_unexpected_error(e) }
|
50
|
+
begin
|
51
|
+
EM.run
|
52
|
+
rescue Pry::RescuableException => e
|
53
|
+
handle_unexpected_error(e)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
40
57
|
sleep 0.01 until EM.reactor_running?
|
41
58
|
end
|
42
59
|
|
60
|
+
# If we were the ones to start the EM reactor, we want to catch
|
61
|
+
# any exceptions that are raised therein and tell the user about
|
62
|
+
# them.
|
63
|
+
#
|
64
|
+
# If they are still waiting for an async event, assume that this
|
65
|
+
# was in relation to that.
|
66
|
+
#
|
67
|
+
# If not, just print out the error and hope they don't get too
|
68
|
+
# confused.
|
69
|
+
def handle_unexpected_error(e)
|
70
|
+
if waiting?
|
71
|
+
@@em_state = :em_error
|
72
|
+
@@retval = e
|
73
|
+
else
|
74
|
+
output.puts "Unexpected exception from EventMachine reactor"
|
75
|
+
_pry_.last_exception = e
|
76
|
+
_pry_.show_result(e)
|
77
|
+
end
|
78
|
+
rescue => e
|
79
|
+
puts e
|
80
|
+
end
|
81
|
+
|
43
82
|
# Run a deferrable on an EM reactor in a different thread,
|
44
83
|
# sleep until it has finished, and then return the result.
|
45
84
|
#
|
@@ -50,29 +89,40 @@ EmCommands = Pry::CommandSet.new do
|
|
50
89
|
#
|
51
90
|
def wait_for_deferrable(deferrable, timeout)
|
52
91
|
|
53
|
-
|
54
|
-
|
55
|
-
EM::Timer.new(timeout) { finished ||= :timeout }
|
92
|
+
EM::Timer.new(timeout) { @@em_state = :timeout if waiting? }
|
56
93
|
|
57
94
|
[:callback, :errback].each do |method|
|
58
95
|
begin
|
59
96
|
deferrable.__send__ method do |*result|
|
60
|
-
|
61
|
-
retval = result.size > 1 ? result : result.first
|
97
|
+
@@em_state = method
|
98
|
+
@@retval = result.size > 1 ? result : result.first
|
62
99
|
end
|
63
100
|
rescue NoMethodError
|
64
|
-
output.
|
101
|
+
output.puts "WARNING: is not deferrable? #{deferrable}"
|
65
102
|
break
|
66
103
|
end
|
67
104
|
end
|
68
105
|
|
69
|
-
sleep 0.01 until
|
106
|
+
sleep 0.01 until @@em_state != :waiting
|
107
|
+
|
108
|
+
raise "Timeout after #{timeout} seconds" if @@em_state == :timeout
|
70
109
|
|
71
|
-
|
110
|
+
# Use Pry's (admittedly nascent) handling for exceptions where possible.
|
111
|
+
raise @@retval if @@em_state != :callback && Exception === @@retval
|
72
112
|
|
73
113
|
# TODO: This doesn't interact well with the pager.
|
74
|
-
output.print "#{
|
75
|
-
retval
|
114
|
+
output.print "#{@@em_state} " #=>
|
115
|
+
@@retval
|
116
|
+
|
117
|
+
# If the main thread is interrupted we must ensure that the @@em_state
|
118
|
+
# is no-longer :waiting so that handle_unexpected_error can do the
|
119
|
+
# right thing.
|
120
|
+
ensure
|
121
|
+
@@em_state = :interrupted if waiting?
|
122
|
+
end
|
123
|
+
|
124
|
+
def waiting?
|
125
|
+
@@em_state == :waiting
|
76
126
|
end
|
77
127
|
end
|
78
128
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pry-em
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
5
|
-
prerelease:
|
4
|
+
hash: 23
|
5
|
+
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
-
|
10
|
-
version: 0.
|
8
|
+
- 2
|
9
|
+
- 0
|
10
|
+
version: 0.2.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Conrad Irwin
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date:
|
18
|
+
date: 2012-02-24 00:00:00 -08:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -24,12 +24,14 @@ dependencies:
|
|
24
24
|
requirement: &id001 !ruby/object:Gem::Requirement
|
25
25
|
none: false
|
26
26
|
requirements:
|
27
|
-
- - "
|
27
|
+
- - ">"
|
28
28
|
- !ruby/object:Gem::Version
|
29
|
-
hash:
|
29
|
+
hash: 43
|
30
30
|
segments:
|
31
31
|
- 0
|
32
|
-
|
32
|
+
- 9
|
33
|
+
- 8
|
34
|
+
version: 0.9.8
|
33
35
|
type: :runtime
|
34
36
|
version_requirements: *id001
|
35
37
|
- !ruby/object:Gem::Dependency
|
@@ -88,7 +90,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
88
90
|
requirements: []
|
89
91
|
|
90
92
|
rubyforge_project:
|
91
|
-
rubygems_version: 1.
|
93
|
+
rubygems_version: 1.3.7
|
92
94
|
signing_key:
|
93
95
|
specification_version: 3
|
94
96
|
summary: Provides an em! function that can be used to play with deferrable more easily.
|