Class: Riak::Node::Console

Inherits:
Object show all
Includes:
Util::Translation
Defined in:
lib/riak/node/console.rb

Overview

Eases working with the Erlang console when attached to the Riak node.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Util::Translation

#i18n_scope, #t

Constructor Details

#initialize(pipedir, nodename) ⇒ Console

Creates a Riak::Node::Console from the IO pipes connected to the node.

Parameters:

  • pipedir (String, Pathname)

    path to the pipes opened by run_erl

  • nodename (String)

    the name of the node the Console will be attached to

Raises:

  • (ArgumentError)


30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/riak/node/console.rb', line 30

def initialize(pipedir, nodename)
  @nodename = nodename
  @mutex = Mutex.new
  @prompt = /\(#{Regexp.escape(nodename)}\)\d+>\s*/
  pipedir = Pathname(pipedir)
  pipedir.children.each do |path|
    if path.pipe?
      if path.fnmatch("*.r") # Read pipe
        # debug "Found read pipe: #{path}"
        @rfile ||= path
      elsif path.fnmatch("*.w") # Write pipe
        # debug "Found write pipe: #{path}"
        @wfile ||= path
      end
    else
      debug "Non-pipe found! #{path}"
    end
  end
  raise ArgumentError, t('no_pipes', :path => pipedir.to_s) if [@rfile, @wfile].any? {|p| p.nil? }

  begin
    debug "Opening write pipe."
    @w = open_write_pipe
    @w.sync = true
    read_ready = false
    # Using threads, we get around JRuby's blocking-open
    # behavior. The main thread pumps the write pipe full of
    # data so that run_erl will start echoing it into the read
    # pipe once we have started the open. On non-JVM rubies,
    # O_NONBLOCK works and we proceed as expected.
    Thread.new do
      debug "Opening read pipe."
      @r = open_read_pipe
      read_ready = true
    end
    Thread.pass
    @w.print "\n" until read_ready
    command "ok."
    debug "Initialized console: #{@r.inspect} #{@w.inspect}"
  rescue => e
    debug e.message
    close
    raise t('no_pipes', :path => pipedir.to_s) + "[ #{e.message} ]"
  end
end

Instance Attribute Details

#nodenameString

Returns the name of the connected node.

Returns:

  • (String)

    the name of the connected node



17
18
19
# File 'lib/riak/node/console.rb', line 17

def nodename
  @nodename
end

Class Method Details

.open(node) ⇒ Console

Opens a Riak::Node::Console by connecting to the node.

Returns:



21
22
23
# File 'lib/riak/node/console.rb', line 21

def self.open(node)
  new node.pipe, node.name
end

Instance Method Details

#closeObject

Closes the console by detaching from the pipes.



112
113
114
115
116
# File 'lib/riak/node/console.rb', line 112

def close
  @r.close if @r && !@r.closed?
  @w.close if @w && !@w.closed?
  freeze
end

#command(cmd) ⇒ Object

Sends an Erlang command to the console

Parameters:

  • cmd (String)

    an Erlang expression to send to the node



78
79
80
81
82
83
84
85
86
87
88
# File 'lib/riak/node/console.rb', line 78

def command(cmd)
  @mutex.synchronize do
    begin
      debug "Sending command #{cmd.inspect}"
      @w.print "#{cmd}\n"
      wait_for_erlang_prompt
    rescue SystemCallError
      close
    end
  end
end

#open?Boolean

Detects whether the console connection is still open, that is, if the node hasn’t disconnected from the other side of the pipe.

Returns:

  • (Boolean)


93
94
95
# File 'lib/riak/node/console.rb', line 93

def open?
  (@r && !@r.closed?) && (@w && !@w.closed?)
end

#wait_for(pattern) ⇒ Object

Scans the output of the console for the given pattern.

Parameters:

  • pattern (String, Regexp)

    the pattern to scan for



106
107
108
109
# File 'lib/riak/node/console.rb', line 106

def wait_for(pattern)
  debug "Scanning for #{pattern.inspect}"
  @r.expect(pattern)
end

#wait_for_erlang_promptObject

Scans the output of the console until an Erlang shell prompt is found. Called by #command to ensure that the submitted command succeeds.



100
101
102
# File 'lib/riak/node/console.rb', line 100

def wait_for_erlang_prompt
  wait_for @prompt
end