iruby 0.2.7 → 0.5.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.
Files changed (69) hide show
  1. checksums.yaml +5 -5
  2. data/.github/workflows/ubuntu.yml +62 -0
  3. data/CHANGES +62 -0
  4. data/Gemfile +3 -1
  5. data/LICENSE +1 -1
  6. data/README.md +148 -27
  7. data/Rakefile +36 -10
  8. data/ci/Dockerfile.base.erb +41 -0
  9. data/ci/Dockerfile.main.erb +7 -0
  10. data/ci/requirements.txt +1 -0
  11. data/docker/setup.sh +15 -0
  12. data/docker/test.sh +7 -0
  13. data/iruby.gemspec +14 -18
  14. data/lib/iruby.rb +19 -3
  15. data/lib/iruby/backend.rb +22 -2
  16. data/lib/iruby/command.rb +76 -13
  17. data/lib/iruby/display.rb +69 -39
  18. data/lib/iruby/formatter.rb +5 -4
  19. data/lib/iruby/input.rb +41 -0
  20. data/lib/iruby/input/README.ipynb +502 -0
  21. data/lib/iruby/input/README.md +299 -0
  22. data/lib/iruby/input/autoload.rb +25 -0
  23. data/lib/iruby/input/builder.rb +67 -0
  24. data/lib/iruby/input/button.rb +47 -0
  25. data/lib/iruby/input/cancel.rb +32 -0
  26. data/lib/iruby/input/checkbox.rb +74 -0
  27. data/lib/iruby/input/date.rb +37 -0
  28. data/lib/iruby/input/field.rb +31 -0
  29. data/lib/iruby/input/file.rb +57 -0
  30. data/lib/iruby/input/form.rb +77 -0
  31. data/lib/iruby/input/label.rb +27 -0
  32. data/lib/iruby/input/multiple.rb +76 -0
  33. data/lib/iruby/input/popup.rb +41 -0
  34. data/lib/iruby/input/radio.rb +59 -0
  35. data/lib/iruby/input/select.rb +59 -0
  36. data/lib/iruby/input/textarea.rb +23 -0
  37. data/lib/iruby/input/widget.rb +34 -0
  38. data/lib/iruby/jupyter.rb +77 -0
  39. data/lib/iruby/kernel.rb +67 -22
  40. data/lib/iruby/ostream.rb +24 -8
  41. data/lib/iruby/session.rb +85 -67
  42. data/lib/iruby/session/cztop.rb +70 -0
  43. data/lib/iruby/session/ffi_rzmq.rb +87 -0
  44. data/lib/iruby/session/mixin.rb +47 -0
  45. data/lib/iruby/session_adapter.rb +66 -0
  46. data/lib/iruby/session_adapter/cztop_adapter.rb +45 -0
  47. data/lib/iruby/session_adapter/ffirzmq_adapter.rb +55 -0
  48. data/lib/iruby/session_adapter/pyzmq_adapter.rb +77 -0
  49. data/lib/iruby/utils.rb +5 -2
  50. data/lib/iruby/version.rb +1 -1
  51. data/run-test.sh +12 -0
  52. data/tasks/ci.rake +65 -0
  53. data/test/helper.rb +90 -0
  54. data/test/integration_test.rb +22 -11
  55. data/test/iruby/backend_test.rb +37 -0
  56. data/test/iruby/command_test.rb +207 -0
  57. data/test/iruby/jupyter_test.rb +27 -0
  58. data/test/iruby/mime_test.rb +32 -0
  59. data/test/iruby/multi_logger_test.rb +1 -2
  60. data/test/iruby/session_adapter/cztop_adapter_test.rb +20 -0
  61. data/test/iruby/session_adapter/ffirzmq_adapter_test.rb +20 -0
  62. data/test/iruby/session_adapter/session_adapter_test_base.rb +27 -0
  63. data/test/iruby/session_adapter_test.rb +91 -0
  64. data/test/iruby/session_test.rb +47 -0
  65. data/test/run-test.rb +18 -0
  66. metadata +130 -46
  67. data/.travis.yml +0 -16
  68. data/CONTRIBUTORS +0 -19
  69. data/test/test_helper.rb +0 -5
@@ -0,0 +1,59 @@
1
+ module IRuby
2
+ module Input
3
+ class Select < Label
4
+ needs :options, :default
5
+
6
+ builder :select do |*args, **params|
7
+ key = :select
8
+ key, *args = args if args.first.is_a? Symbol
9
+
10
+ params[:key] = unique_key(key)
11
+ params[:options] = args
12
+ params[:default] ||= false
13
+
14
+ unless params[:options].include? params[:default]
15
+ params[:options] = [nil, *params[:options].compact]
16
+ end
17
+
18
+ add_field Select.new(**params)
19
+ end
20
+
21
+ def widget_css
22
+ <<-CSS
23
+ .iruby-select {
24
+ min-width: 25%;
25
+ margin-left: 0 !important;
26
+ }
27
+ CSS
28
+ end
29
+
30
+ def widget_js
31
+ <<-JS
32
+ $('.iruby-select').change(function(){
33
+ $(this).data('iruby-value',
34
+ $(this).find('option:selected').text()
35
+ );
36
+ });
37
+ JS
38
+ end
39
+
40
+ def widget_html
41
+ widget_label do
42
+ div class: 'form-control' do
43
+ params = {
44
+ class: 'iruby-select',
45
+ :'data-iruby-key' => @key,
46
+ :'data-iruby-value' => @default
47
+ }
48
+
49
+ select **params do
50
+ @options.each do |o|
51
+ option o, selected: @default == o
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,23 @@
1
+ module IRuby
2
+ module Input
3
+ class Textarea < Field
4
+ needs rows: 5
5
+
6
+ builder :textarea do |key='textarea', **params|
7
+ params[:key] = unique_key key
8
+ add_field Textarea.new(**params)
9
+ end
10
+
11
+ def widget_html
12
+ widget_label do
13
+ textarea(
14
+ @default,
15
+ rows: @rows,
16
+ :'data-iruby-key' => @key,
17
+ class: 'form-control iruby-field'
18
+ )
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,34 @@
1
+ module IRuby
2
+ module Input
3
+ class Widget < Erector::Widget
4
+ needs key: nil
5
+
6
+ def widget_js; end
7
+ def widget_css; end
8
+ def widget_html; end
9
+ def content; widget_html; end
10
+
11
+ def self.builder method, &block
12
+ Builder.instance_eval do
13
+ define_method method, &block
14
+ end
15
+ end
16
+
17
+ def widget_join method, *args
18
+ strings = args.map do |arg|
19
+ arg.is_a?(String) ? arg : arg.send(method)
20
+ end
21
+ strings.uniq.join("\n")
22
+ end
23
+
24
+ def widget_display
25
+ IRuby.display(IRuby.html(
26
+ Erector.inline{ style raw(widget_css) }.to_html
27
+ ))
28
+
29
+ IRuby.display(IRuby.html(to_html))
30
+ IRuby.display(IRuby.javascript(widget_js))
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,77 @@
1
+ module IRuby
2
+ module Jupyter
3
+ class << self
4
+ # User's default kernelspec directory is described here:
5
+ # https://jupyter.readthedocs.io/en/latest/projects/jupyter-directories.html
6
+ def default_data_dir
7
+ case
8
+ when windows?
9
+ appdata = windows_user_appdata
10
+ if !appdata.empty?
11
+ File.join(appdata, 'jupyter')
12
+ else
13
+ jupyter_config_dir = ENV.fetch('JUPYTER_CONFIG_DIR', File.expand_path('~/.jupyter'))
14
+ File.join(jupyter_config_dir, 'data')
15
+ end
16
+ when apple?
17
+ File.expand_path('~/Library/Jupyter')
18
+ else
19
+ xdg_data_home = ENV.fetch('XDG_DATA_HOME', '')
20
+ data_home = xdg_data_home[0] ? xdg_data_home : File.expand_path('~/.local/share')
21
+ File.join(data_home, 'jupyter')
22
+ end
23
+ end
24
+
25
+ def kernelspec_dir(data_dir=nil)
26
+ data_dir ||= default_data_dir
27
+ File.join(data_dir, 'kernels')
28
+ end
29
+
30
+ private
31
+
32
+ # returns %APPDATA%
33
+ def windows_user_appdata
34
+ require 'fiddle/import'
35
+ check_windows
36
+ path = Fiddle::Pointer.malloc(2 * 300) # uint16_t[300]
37
+ csidl_appdata = 0x001a
38
+ case call_SHGetFolderPathW(Fiddle::NULL, csidl_appdata, Fiddle::NULL, 0, path)
39
+ when 0
40
+ len = (1 ... (path.size/2)).find {|i| path[2*i, 2] == "\0\0" }
41
+ path = path.to_str(2*len).encode(Encoding::UTF_8, Encoding::UTF_16LE)
42
+ else
43
+ ENV.fetch('APPDATA', '')
44
+ end
45
+ end
46
+
47
+ def call_SHGetFolderPathW(hwnd, csidl, hToken, dwFlags, pszPath)
48
+ require 'fiddle/import'
49
+ shell32 = Fiddle::Handle.new('shell32')
50
+ func = Fiddle::Function.new(
51
+ shell32['SHGetFolderPathW'],
52
+ [
53
+ Fiddle::TYPE_VOIDP,
54
+ Fiddle::TYPE_INT,
55
+ Fiddle::TYPE_VOIDP,
56
+ Fiddle::TYPE_INT,
57
+ Fiddle::TYPE_VOIDP
58
+ ],
59
+ Fiddle::TYPE_INT,
60
+ Fiddle::Importer.const_get(:CALL_TYPE_TO_ABI)[:stdcall])
61
+ func.(hwnd, csidl, hToken, dwFlags, pszPath)
62
+ end
63
+
64
+ def check_windows
65
+ raise 'the current platform is not Windows' unless windows?
66
+ end
67
+
68
+ def windows?
69
+ /mingw|mswin/ =~ RUBY_PLATFORM
70
+ end
71
+
72
+ def apple?
73
+ /darwin/ =~ RUBY_PLATFORM
74
+ end
75
+ end
76
+ end
77
+ end
data/lib/iruby/kernel.rb CHANGED
@@ -1,7 +1,6 @@
1
1
  module IRuby
2
2
  class Kernel
3
3
  RED = "\e[31m"
4
- WHITE = "\e[37m"
5
4
  RESET = "\e[0m"
6
5
 
7
6
  class<< self
@@ -19,6 +18,8 @@ module IRuby
19
18
  $stdout = OStream.new(@session, :stdout)
20
19
  $stderr = OStream.new(@session, :stderr)
21
20
 
21
+ init_parent_process_poller
22
+
22
23
  @execution_count = 0
23
24
  @backend = create_backend
24
25
  @running = true
@@ -40,6 +41,7 @@ module IRuby
40
41
 
41
42
  def dispatch
42
43
  msg = @session.recv(:reply)
44
+ IRuby.logger.debug "Kernel#dispatch: msg = #{msg}"
43
45
  type = msg[:header]['msg_type']
44
46
  raise "Unknown message type: #{msg.inspect}" unless type =~ /comm_|_request\Z/ && respond_to?(type)
45
47
  begin
@@ -50,24 +52,32 @@ module IRuby
50
52
  end
51
53
  rescue Exception => e
52
54
  IRuby.logger.debug "Kernel error: #{e.message}\n#{e.backtrace.join("\n")}"
53
- @session.send(:publish, :error, error_message(e))
55
+ @session.send(:publish, :error, error_content(e))
54
56
  end
55
57
 
56
58
  def kernel_info_request(msg)
57
59
  @session.send(:reply, :kernel_info_reply,
58
60
  protocol_version: '5.0',
59
61
  implementation: 'iruby',
60
- banner: "IRuby #{IRuby::VERSION}",
61
62
  implementation_version: IRuby::VERSION,
62
63
  language_info: {
63
64
  name: 'ruby',
64
65
  version: RUBY_VERSION,
65
66
  mimetype: 'application/x-ruby',
66
- file_extension: 'rb'
67
- })
67
+ file_extension: '.rb'
68
+ },
69
+ banner: "IRuby #{IRuby::VERSION} (with #{@session.description})",
70
+ help_links: [
71
+ {
72
+ text: "Ruby Documentation",
73
+ url: "https://ruby-doc.org/"
74
+ }
75
+ ],
76
+ status: :ok)
68
77
  end
69
78
 
70
79
  def send_status(status)
80
+ IRuby.logger.debug "Send status: #{status}"
71
81
  @session.send(:publish, :status, execution_state: status)
72
82
  end
73
83
 
@@ -88,8 +98,10 @@ module IRuby
88
98
  rescue SystemExit
89
99
  content[:payload] << { source: :ask_exit }
90
100
  rescue Exception => e
91
- content = error_message(e)
101
+ content = error_content(e)
92
102
  @session.send(:publish, :error, content)
103
+ content[:status] = :error
104
+ content[:execution_count] = @execution_count
93
105
  end
94
106
  @session.send(:reply, :execute_reply, content)
95
107
  @session.send(:publish, :execute_result,
@@ -98,26 +110,33 @@ module IRuby
98
110
  execution_count: @execution_count) unless result.nil? || msg[:content]['silent']
99
111
  end
100
112
 
101
- def error_message(e)
102
- { status: :error,
103
- ename: e.class.to_s,
113
+ def error_content(e)
114
+ rindex = e.backtrace.rindex{|line| line.start_with?(@backend.eval_path)} || -1
115
+ backtrace = SyntaxError === e && rindex == -1 ? [] : e.backtrace[0..rindex]
116
+ { ename: e.class.to_s,
104
117
  evalue: e.message,
105
- traceback: ["#{RED}#{e.class}#{RESET}: #{e.message}", *e.backtrace.map { |l| "#{WHITE}#{l}#{RESET}" }],
106
- execution_count: @execution_count }
118
+ traceback: ["#{RED}#{e.class}#{RESET}: #{e.message}", *backtrace] }
119
+ end
120
+
121
+ def is_complete_request(msg)
122
+ # FIXME: the code completeness should be judged by using ripper or other Ruby parser
123
+ @session.send(:reply, :is_complete_reply,
124
+ status: :unknown)
107
125
  end
108
126
 
109
127
  def complete_request(msg)
110
128
  # HACK for #26, only complete last line
111
129
  code = msg[:content]['code']
112
- if start = code.rindex("\n")
130
+ if start = code.rindex(/\s|\R/)
113
131
  code = code[start+1..-1]
114
132
  start += 1
115
133
  end
116
134
  @session.send(:reply, :complete_reply,
117
135
  matches: @backend.complete(code),
118
- status: :ok,
119
136
  cursor_start: start.to_i,
120
- cursor_end: msg[:content]['cursor_pos'])
137
+ cursor_end: msg[:content]['cursor_pos'],
138
+ metadata: {},
139
+ status: :ok)
121
140
  end
122
141
 
123
142
  def connect_request(msg)
@@ -136,14 +155,8 @@ module IRuby
136
155
  end
137
156
 
138
157
  def inspect_request(msg)
139
- result = @backend.eval(msg[:content]['code'])
140
- @session.send(:reply, :inspect_reply,
141
- status: :ok,
142
- data: Display.display(result),
143
- metadata: {})
144
- rescue Exception => e
145
- IRuby.logger.warn "Inspection error: #{e.message}\n#{e.backtrace.join("\n")}"
146
- @session.send(:reply, :inspect_reply, status: :error)
158
+ # not yet implemented. See (#119).
159
+ @session.send(:reply, :inspect_reply, status: :ok, found: false, data: {}, metadata: {})
147
160
  end
148
161
 
149
162
  def comm_open(msg)
@@ -161,5 +174,37 @@ module IRuby
161
174
  Comm.comm[comm_id].handle_close(msg[:content]['data'])
162
175
  Comm.comm.delete(comm_id)
163
176
  end
177
+
178
+ private
179
+
180
+ def init_parent_process_poller
181
+ pid = ENV.fetch('JPY_PARENT_PID', 0).to_i
182
+ return unless pid > 1
183
+
184
+ case RUBY_PLATFORM
185
+ when /mswin/, /mingw/
186
+ # TODO
187
+ else
188
+ @parent_poller = start_parent_process_pollar_unix
189
+ end
190
+ end
191
+
192
+ def start_parent_process_pollar_unix
193
+ Thread.start do
194
+ IRuby.logger.warn("parent process poller thread started.")
195
+ loop do
196
+ begin
197
+ current_ppid = Process.ppid
198
+ if current_ppid == 1
199
+ IRuby.logger.warn("parent process appears to exited, shutting down.")
200
+ exit!(1)
201
+ end
202
+ sleep 1
203
+ rescue Errno::EINTR
204
+ # ignored
205
+ end
206
+ end
207
+ end
208
+ end
164
209
  end
165
210
  end
data/lib/iruby/ostream.rb CHANGED
@@ -25,22 +25,38 @@ module IRuby
25
25
  alias_method :next, :read
26
26
  alias_method :readline, :read
27
27
 
28
- def write(s)
29
- raise 'I/O operation on closed file' unless @session
30
- @session.send(:publish, :stream, name: @name, text: s.to_s)
31
- nil
28
+ def write(*obj)
29
+ str = build_string { |sio| sio.write(*obj) }
30
+ session_send(str)
32
31
  end
33
32
  alias_method :<<, :write
34
33
  alias_method :print, :write
35
34
 
36
- def puts(*lines)
37
- lines = [''] if lines.empty?
38
- lines.each { |s| write("#{s}\n")}
39
- nil
35
+ def printf(format, *obj)
36
+ str = build_string { |sio| sio.printf(format, *obj) }
37
+ session_send(str)
38
+ end
39
+
40
+ def puts(*obj)
41
+ str = build_string { |sio| sio.puts(*obj) }
42
+ session_send(str)
40
43
  end
41
44
 
42
45
  def writelines(lines)
43
46
  lines.each { |s| write(s) }
44
47
  end
48
+
49
+ private
50
+
51
+ def build_string
52
+ StringIO.open { |sio| yield(sio); sio.string }
53
+ end
54
+
55
+ def session_send(str)
56
+ raise 'I/O operation on closed file' unless @session
57
+
58
+ @session.send(:publish, :stream, name: @name, text: str)
59
+ nil
60
+ end
45
61
  end
46
62
  end
data/lib/iruby/session.rb CHANGED
@@ -1,98 +1,116 @@
1
+ require 'iruby/session_adapter'
2
+ require 'iruby/session/mixin'
3
+
4
+ require 'securerandom'
5
+
1
6
  module IRuby
2
7
  class Session
3
- DELIM = '<IDS|MSG>'
8
+ include SessionSerialize
9
+
10
+ def initialize(config, adapter_name=nil)
11
+ @config = config
12
+ @adapter = create_session_adapter(config, adapter_name)
4
13
 
5
- def initialize(config)
6
- c = ZMQ::Context.new
14
+ setup
15
+ setup_sockets
16
+ setup_heartbeat
17
+ setup_security
18
+ end
7
19
 
8
- connection = "#{config['transport']}://#{config['ip']}:%d"
9
- reply_socket = c.socket(:ROUTER)
10
- reply_socket.bind(connection % config['shell_port'])
20
+ attr_reader :adapter, :config
11
21
 
12
- pub_socket = c.socket(:PUB)
13
- pub_socket.bind(connection % config['iopub_port'])
22
+ def description
23
+ "#{@adapter.name} session adapter"
24
+ end
14
25
 
15
- Thread.new do
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
16
51
  begin
17
- hb_socket = c.socket(:REP)
18
- hb_socket.bind(connection % config['hb_port'])
19
- ZMQ.proxy(hb_socket, hb_socket)
52
+ # NOTE: this loop is copied from CZTop's old session code
53
+ @adapter.heartbeat_loop(@hb_socket)
20
54
  rescue Exception => e
21
55
  IRuby.logger.fatal "Kernel heartbeat died: #{e.message}\n#{e.backtrace.join("\n")}"
22
56
  end
23
57
  end
58
+ end
24
59
 
25
- @sockets = { publish: pub_socket, reply: reply_socket }
26
- @session = SecureRandom.uuid
27
- unless config['key'].to_s.empty? || config['signature_scheme'].to_s.empty?
28
- raise 'Unknown signature scheme' unless config['signature_scheme'] =~ /\Ahmac-(.*)\Z/
29
- @hmac = OpenSSL::HMAC.new(config['key'], OpenSSL::Digest.new($1))
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))
30
68
  end
31
69
  end
32
70
 
33
- # Build and send a message
34
- def send(socket, type, content)
35
- idents =
36
- if socket == :reply && @last_recvd_msg
37
- @last_recvd_msg[:idents]
38
- else
39
- type == :stream ? "stream.#{content[:name]}" : type
40
- end
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
41
78
  header = {
42
- msg_type: type,
79
+ msg_type: message_type,
43
80
  msg_id: SecureRandom.uuid,
44
81
  username: 'kernel',
45
- session: @session,
82
+ session: @session_id,
46
83
  version: '5.0'
47
84
  }
48
- @sockets[socket].send_message(serialize(idents, header, content))
85
+ @adapter.send(sock, serialize(idents, header, content))
49
86
  end
50
87
 
51
- # Receive a message and decode it
52
- def recv(socket)
53
- @last_recvd_msg = unserialize(@sockets[socket].recv_message)
88
+ def recv(socket_type)
89
+ sock = check_socket_type(socket_type)
90
+ data = @adapter.recv(sock)
91
+ @last_recvd_msg = unserialize(data)
54
92
  end
55
93
 
56
- private
57
-
58
- def serialize(idents, header, content)
59
- msg = [MultiJson.dump(header),
60
- MultiJson.dump(@last_recvd_msg ? @last_recvd_msg[:header] : {}),
61
- '{}',
62
- MultiJson.dump(content || {})]
63
- frames = ([*idents].compact.map(&:to_s) << DELIM << sign(msg)) + msg
64
- IRuby.logger.debug "Sent #{frames.inspect}"
65
- ZMQ::Message(*frames)
94
+ def recv_input
95
+ sock = check_socket_type(:stdin)
96
+ data = @adapter.recv(sock)
97
+ unserialize(data)[:content]["value"]
66
98
  end
67
99
 
68
- def unserialize(msg)
69
- raise 'no message received' unless msg
70
- frames = msg.to_a.map(&:to_s)
71
- IRuby.logger.debug "Received #{frames.inspect}"
72
-
73
- i = frames.index(DELIM)
74
- idents, msg_list = frames[0..i-1], frames[i+1..-1]
75
-
76
- minlen = 5
77
- raise 'malformed message, must have at least #{minlen} elements' unless msg_list.length >= minlen
78
- s, header, parent_header, metadata, content, buffers = *msg_list
79
- raise 'Invalid signature' unless s == sign(msg_list[1..-1])
80
- {
81
- idents: idents,
82
- header: MultiJson.load(header),
83
- parent_header: MultiJson.load(parent_header),
84
- metadata: MultiJson.load(metadata),
85
- content: MultiJson.load(content),
86
- buffers: buffers
87
- }
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
88
109
  end
89
110
 
90
- # Sign using HMAC
91
- def sign(list)
92
- return '' unless @hmac
93
- @hmac.reset
94
- list.each {|m| @hmac.update(m) }
95
- @hmac.hexdigest
111
+ def create_session_adapter(config, adapter_name)
112
+ adapter_class = SessionAdapter.select_adapter_class(adapter_name)
113
+ adapter_class.new(config)
96
114
  end
97
115
  end
98
116
  end