Class: Net::SSH::Connection::EventLoop

Inherits:
Object
  • Object
show all
Includes:
Loggable
Defined in:
lib/net/ssh/connection/event_loop.rb

Overview

EventLoop can be shared across multiple sessions

one issue is with blocks passed to loop, etc. they should get current session as parameter, but in case you're using multiple sessions in an event loop it doesnt makes sense and we don't pass session.

Direct Known Subclasses

SingleSessionEventLoop

Instance Attribute Summary

Attributes included from Loggable

#logger

Instance Method Summary collapse

Methods included from Loggable

#debug, #error, #fatal, #info, #lwarn

Constructor Details

#initialize(logger = nil) ⇒ EventLoop

Returns a new instance of EventLoop.


15
16
17
18
# File 'lib/net/ssh/connection/event_loop.rb', line 15

def initialize(logger = nil)
  self.logger = logger
  @sessions = []
end

Instance Method Details

#ev_preprocess(&block) ⇒ Object

Call preprocess on each session. If block given and that block retuns false then we exit the processing


48
49
50
51
52
53
54
55
# File 'lib/net/ssh/connection/event_loop.rb', line 48

def ev_preprocess(&block)
  return false if block_given? && !yield(self)

  @sessions.each(&:ev_preprocess)
  return false if block_given? && !yield(self)

  return true
end

#ev_select_and_postprocess(wait) ⇒ Object


57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/net/ssh/connection/event_loop.rb', line 57

def ev_select_and_postprocess(wait)
  owners = {}
  r = []
  w = []
  minwait = nil
  @sessions.each do |session|
    sr, sw, actwait = session.ev_do_calculate_rw_wait(wait)
    minwait = actwait if actwait && (minwait.nil? || actwait < minwait)
    r.push(*sr)
    w.push(*sw)
    sr.each { |ri| owners[ri] = session }
    sw.each { |wi| owners[wi] = session }
  end

  readers, writers, = IO.select(r, w, nil, minwait)

  fired_sessions = {}

  if readers
    readers.each do |reader|
      session = owners[reader]
      (fired_sessions[session] ||= { r: [], w: [] })[:r] << reader
    end
  end
  if writers
    writers.each do |writer|
      session = owners[writer]
      (fired_sessions[session] ||= { r: [], w: [] })[:w] << writer
    end
  end

  fired_sessions.each do |s, rw|
    s.ev_do_handle_events(rw[:r], rw[:w])
  end

  @sessions.each { |s| s.ev_do_postprocess(fired_sessions.key?(s)) }
  true
end

#process(wait = nil, &block) ⇒ Object

process until timeout if a block is given a session will be removed from loop if block returns false for that session


27
28
29
30
31
# File 'lib/net/ssh/connection/event_loop.rb', line 27

def process(wait = nil, &block)
  return false unless ev_preprocess(&block)

  ev_select_and_postprocess(wait)
end

#process_only(session, wait = nil) ⇒ Object

process the event loop but only for the sepcified session


34
35
36
37
38
39
40
41
42
43
44
# File 'lib/net/ssh/connection/event_loop.rb', line 34

def process_only(session, wait = nil)
  orig_sessions = @sessions
  begin
    @sessions = [session]
    return false unless ev_preprocess

    ev_select_and_postprocess(wait)
  ensure
    @sessions = orig_sessions
  end
end

#register(session) ⇒ Object


20
21
22
# File 'lib/net/ssh/connection/event_loop.rb', line 20

def register(session)
  @sessions << session
end