Skip to content

Commit b526e4e

Browse files
committed
Implement hooks around of cell execution
The following four events are implemented in this commit. - `pre_execute` -- occurred before every code execution - `pre_run_cell` -- occurred before every non-silent code execution - `post_execute` -- occurred after every code execution - `post_run_cell` -- occurred after every non-silent code execution `pre_execute` and `post_execute` events do not take any argument. `pre_run_cell` event takes one argument, that is an `IRuby::ExecutionInfo` object. `post_run_cell` event takes one argument, that is the result of the code execution.
1 parent 229b219 commit b526e4e

File tree

2 files changed

+86
-3
lines changed

2 files changed

+86
-3
lines changed

lib/iruby/kernel.rb

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
module IRuby
2+
ExecutionInfo = Struct.new(:raw_cell, :store_history, :silent)
3+
24
class Kernel
35
RED = "\e[31m"
46
RESET = "\e[0m"
@@ -9,6 +11,13 @@ class Kernel
911

1012
attr_reader :session
1113

14+
EVENTS = [
15+
:pre_execute,
16+
:pre_run_cell,
17+
:post_run_cell,
18+
:post_execute
19+
].freeze
20+
1221
def initialize(config_file, session_adapter_name=nil)
1322
@config = MultiJson.load(File.read(config_file))
1423
IRuby.logger.debug("IRuby kernel start with config #{@config}")
@@ -20,11 +29,14 @@ def initialize(config_file, session_adapter_name=nil)
2029

2130
init_parent_process_poller
2231

32+
@events = EventManager.new(EVENTS)
2333
@execution_count = 0
2434
@backend = create_backend
2535
@running = true
2636
end
2737

38+
attr_reader :events
39+
2840
def create_backend
2941
PryBackend.new
3042
rescue Exception => e
@@ -83,18 +95,31 @@ def send_status(status)
8395

8496
def execute_request(msg)
8597
code = msg[:content]['code']
86-
@execution_count += 1 if msg[:content]['store_history']
87-
@session.send(:publish, :execute_input, code: code, execution_count: @execution_count)
98+
store_history = msg[:content]['store_history']
99+
silent = msg[:content]['silent']
100+
101+
@execution_count += 1 if store_history
102+
103+
unless silent
104+
@session.send(:publish, :execute_input, code: code, execution_count: @execution_count)
105+
end
106+
107+
events.trigger(:pre_execute)
108+
unless silent
109+
exec_info = ExecutionInfo.new(code, store_history, silent)
110+
events.trigger(:pre_run_cell, exec_info)
111+
end
88112

89113
content = {
90114
status: :ok,
91115
payload: [],
92116
user_expressions: {},
93117
execution_count: @execution_count
94118
}
119+
95120
result = nil
96121
begin
97-
result = @backend.eval(code, msg[:content]['store_history'])
122+
result = @backend.eval(code, store_history)
98123
rescue SystemExit
99124
content[:payload] << { source: :ask_exit }
100125
rescue Exception => e
@@ -103,6 +128,10 @@ def execute_request(msg)
103128
content[:status] = :error
104129
content[:execution_count] = @execution_count
105130
end
131+
132+
events.trigger(:post_execute)
133+
events.trigger(:post_run_cell, result) unless silent
134+
106135
@session.send(:reply, :execute_reply, content)
107136
@session.send(:publish, :execute_result,
108137
data: Display.display(result),

test/iruby/kernel_test.rb

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,5 +76,59 @@ def inspect
7676
}
7777
})
7878
end
79+
80+
def test_events_around_of_execute_request
81+
event_history = []
82+
83+
@kernel.events.register(:pre_execute) do
84+
event_history << :pre_execute
85+
end
86+
87+
@kernel.events.register(:pre_run_cell) do |exec_info|
88+
event_history << [:pre_run_cell, exec_info]
89+
end
90+
91+
@kernel.events.register(:post_execute) do
92+
event_history << :post_execute
93+
end
94+
95+
@kernel.events.register(:post_run_cell) do |result|
96+
event_history << [:post_run_cell, result]
97+
end
98+
99+
msg = {
100+
content: {
101+
"code" => "true",
102+
"silent" => false,
103+
"store_history" => false,
104+
"user_expressions" => {},
105+
"allow_stdin" => false,
106+
"stop_on_error" => true,
107+
}
108+
}
109+
@kernel.execute_request(msg)
110+
111+
msg = {
112+
content: {
113+
"code" => "true",
114+
"silent" => true,
115+
"store_history" => false,
116+
"user_expressions" => {},
117+
"allow_stdin" => false,
118+
"stop_on_error" => true,
119+
}
120+
}
121+
@kernel.execute_request(msg)
122+
123+
assert_equal([
124+
:pre_execute,
125+
[:pre_run_cell, IRuby::ExecutionInfo.new("true", false, false)],
126+
:post_execute,
127+
[:post_run_cell, true],
128+
:pre_execute,
129+
:post_execute
130+
],
131+
event_history)
132+
end
79133
end
80134
end

0 commit comments

Comments
 (0)