Skip to content

Commit c02d403

Browse files
authored
Merge pull request #173 from SciRuby/new_session
New session
2 parents 81ae82e + eb89e2d commit c02d403

23 files changed

+723
-13
lines changed

Gemfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,5 @@ end
1515

1616
group :test do
1717
gem 'cztop'
18+
gem 'rbczmq'
1819
end

ci/Dockerfile.base.erb

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,34 @@ RUN apt-get update \
88
python3 \
99
python3-pip \
1010
python3-setuptools \
11+
libpython3.6 \
1112
&& pip3 install wheel \
1213
&& pip3 install -r /tmp/requirements.txt \
1314
&& rm -f /tmp/requirements.txt
15+
16+
# ZeroMQ version 4.1.6 and CZMQ version 3.0.2 for rbczmq
17+
RUN apt-get update \
18+
&& apt-get install -y --no-install-recommends \
19+
build-essential \
20+
file \
21+
wget \
22+
&& cd /tmp \
23+
&& wget https://github.com/zeromq/zeromq4-1/releases/download/v4.1.6/zeromq-4.1.6.tar.gz \
24+
&& wget https://archive.org/download/zeromq_czmq_3.0.2/czmq-3.0.2.tar.gz \
25+
&& tar xf zeromq-4.1.6.tar.gz \
26+
&& tar xf czmq-3.0.2.tar.gz \
27+
&& \
28+
( \
29+
cd zeromq-4.1.6 \
30+
&& ./configure \
31+
&& make install \
32+
) \
33+
&& \
34+
( \
35+
cd czmq-3.0.2 \
36+
&& wget -O 1.patch https://github.com/zeromq/czmq/commit/2594d406d8ec6f54e54d7570d7febba10a6906b2.diff \
37+
&& wget -O 2.patch https://github.com/zeromq/czmq/commit/b651cb479235751b22b8f9a822a2fc6bc1be01ab.diff \
38+
&& cat *.patch | patch -p1 \
39+
&& ./configure \
40+
&& make install \
41+
)

ci/Dockerfile.main.erb

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
FROM iruby-test-base:ruby-<%= ruby_version %>
22

3+
RUN gem install cztop \
4+
&& gem install rbczmq -- --with-system-libs
5+
36
RUN mkdir -p /iruby
47
ADD . /iruby
58
WORKDIR /iruby
6-
RUN gem install cztop && \
7-
bundle install
9+
RUN bundle install

iruby.gemspec

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ Gem::Specification.new do |s|
2626

2727
s.add_development_dependency 'rake'
2828
s.add_development_dependency 'minitest'
29+
s.add_development_dependency 'ffi-rzmq'
30+
s.add_development_dependency 'pycall', '>= 1.2.1'
2931

3032
s.add_runtime_dependency 'bond', '~> 0.5'
3133
s.add_runtime_dependency 'multi_json', '~> 1.11'

lib/iruby.rb

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,18 +15,22 @@
1515
require 'iruby/utils'
1616
require 'iruby/display'
1717
require 'iruby/comm'
18-
require 'iruby/session/mixin'
1918

20-
begin
21-
require 'iruby/session/cztop'
22-
rescue LoadError
19+
if ENV.fetch('IRUBY_OLD_SESSION', false)
20+
require 'iruby/session/mixin'
2321
begin
24-
require 'iruby/session/ffi_rzmq'
22+
require 'iruby/session/cztop'
2523
rescue LoadError
2624
begin
27-
require 'iruby/session/rbczmq'
25+
require 'iruby/session/ffi_rzmq'
2826
rescue LoadError
29-
STDERR.puts "You should install cztop, ffi_rzmq or rbczmq before running iruby notebook. See README."
27+
begin
28+
require 'iruby/session/rbczmq'
29+
rescue LoadError
30+
STDERR.puts "You should install cztop, rbczmq or ffi_rzmq before running iruby notebook. See README."
31+
end
3032
end
3133
end
34+
else
35+
require 'iruby/session'
3236
end

lib/iruby/command.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,8 @@ def print_help
9494
def run_kernel
9595
require 'iruby/logger'
9696
IRuby.logger = MultiLogger.new(*Logger.new(STDOUT))
97+
STDOUT.sync = true # FIXME: This can make the integration test.
98+
9799
@args.reject! {|arg| arg =~ /\A--log=(.*)\Z/ && IRuby.logger.loggers << Logger.new($1) }
98100
IRuby.logger.level = @args.delete('--debug') ? Logger::DEBUG : Logger::INFO
99101

lib/iruby/kernel.rb

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ def run
4040

4141
def dispatch
4242
msg = @session.recv(:reply)
43+
IRuby.logger.debug "Kernel#dispatch: msg = #{msg}"
4344
type = msg[:header]['msg_type']
4445
raise "Unknown message type: #{msg.inspect}" unless type =~ /comm_|_request\Z/ && respond_to?(type)
4546
begin
@@ -57,7 +58,7 @@ def kernel_info_request(msg)
5758
@session.send(:reply, :kernel_info_reply,
5859
protocol_version: '5.0',
5960
implementation: 'iruby',
60-
banner: "IRuby #{IRuby::VERSION}",
61+
banner: "IRuby #{IRuby::VERSION} (with #{@session.description})",
6162
implementation_version: IRuby::VERSION,
6263
language_info: {
6364
name: 'ruby',
@@ -68,6 +69,7 @@ def kernel_info_request(msg)
6869
end
6970

7071
def send_status(status)
72+
IRuby.logger.debug "Send status: #{status}"
7173
@session.send(:publish, :status, execution_state: status)
7274
end
7375

lib/iruby/session.rb

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
require 'iruby/session_adapter'
2+
require 'iruby/session/mixin'
3+
4+
require 'securerandom'
5+
6+
module IRuby
7+
class Session
8+
include SessionSerialize
9+
10+
def initialize(config, adapter_name=nil)
11+
@config = config
12+
@adapter = create_session_adapter(config, adapter_name)
13+
14+
setup
15+
setup_sockets
16+
setup_heartbeat
17+
setup_security
18+
end
19+
20+
attr_reader :adapter, :config
21+
22+
def description
23+
"#{@adapter.name} session adapter"
24+
end
25+
26+
def setup
27+
end
28+
29+
def setup_sockets
30+
protocol, host = config.values_at('transport', 'ip')
31+
shell_port = config['shell_port']
32+
iopub_port = config['iopub_port']
33+
stdin_port = config['stdin_port']
34+
35+
@shell_socket, @shell_port = @adapter.make_router_socket(protocol, host, shell_port)
36+
@iopub_socket, @iopub_port = @adapter.make_pub_socket(protocol, host, iopub_port)
37+
@stdin_socket, @stdin_port = @adapter.make_router_socket(protocol, host, stdin_port)
38+
39+
@sockets = {
40+
publish: @iopub_socket,
41+
reply: @shell_socket,
42+
stdin: @stdin_socket
43+
}
44+
end
45+
46+
def setup_heartbeat
47+
protocol, host = config.values_at('transport', 'ip')
48+
hb_port = config['hb_port']
49+
@hb_socket, @hb_port = @adapter.make_rep_socket(protocol, host, hb_port)
50+
@heartbeat_thread = Thread.start do
51+
begin
52+
# NOTE: this loop is copied from CZTop's old session code
53+
@adapter.heartbeat_loop(@hb_socket)
54+
rescue Exception => e
55+
IRuby.logger.fatal "Kernel heartbeat died: #{e.message}\n#{e.backtrace.join("\n")}"
56+
end
57+
end
58+
end
59+
60+
def setup_security
61+
@session_id = SecureRandom.uuid
62+
unless config['key'].empty? || config['signature_scheme'].empty?
63+
unless config['signature_scheme'] =~ /\Ahmac-/
64+
raise "Unknown signature_scheme: #{config['signature_scheme']}"
65+
end
66+
digest_algorithm = config['signature_scheme'][/\Ahmac-(.*)\Z/, 1]
67+
@hmac = OpenSSL::HMAC.new(config['key'], OpenSSL::Digest.new(digest_algorithm))
68+
end
69+
end
70+
71+
def send(socket_type, message_type, content)
72+
sock = check_socket_type(socket_type)
73+
idents = if socket_type == :reply && @last_recvd_msg
74+
@last_recvd_msg[:idents]
75+
else
76+
message_type == :stream ? "stream.#{content[:name]}" : message_type
77+
end
78+
header = {
79+
msg_type: message_type,
80+
msg_id: SecureRandom.uuid,
81+
username: 'kernel',
82+
session: @session_id,
83+
version: '5.0'
84+
}
85+
@adapter.send(sock, serialize(idents, header, content))
86+
end
87+
88+
def recv(socket_type)
89+
sock = check_socket_type(socket_type)
90+
data = @adapter.recv(sock)
91+
@last_recvd_msg = unserialize(data)
92+
end
93+
94+
def recv_input
95+
sock = check_socket_type(:stdin)
96+
data = @adapter.recv(sock)
97+
unserialize(data)[:content]["value"]
98+
end
99+
100+
private
101+
102+
def check_socket_type(socket_type)
103+
case socket_type
104+
when :publish, :reply, :stdin
105+
@sockets[socket_type]
106+
else
107+
raise ArgumentError, "Invalid socket type #{socket_type}"
108+
end
109+
end
110+
111+
def create_session_adapter(config, adapter_name)
112+
adapter_class = SessionAdapter.select_adapter_class(adapter_name)
113+
adapter_class.new(config)
114+
end
115+
end
116+
end

lib/iruby/session/cztop.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@ def initialize(config)
3636
end
3737
end
3838

39+
def description
40+
'old-stle session using cztop'
41+
end
42+
3943
# Build and send a message
4044
def send(socket, type, content)
4145
idents =

lib/iruby/session/rbczmq.rb

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@ def initialize(config)
3838
end
3939
end
4040

41+
def description
42+
'old-stle session using rbczmq'
43+
end
44+
4145
# Build and send a message
4246
def send(socket, type, content)
4347
idents =
@@ -53,7 +57,7 @@ def send(socket, type, content)
5357
session: @session,
5458
version: '5.0'
5559
}
56-
@sockets[socket].send_message(ZMQ::Message(*serialize(idents, header, content)))
60+
@sockets[socket].send_message(ZMQ.Message(*serialize(idents, header, content)))
5761
end
5862

5963
# Receive a message and decode it

0 commit comments

Comments
 (0)