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


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

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


54
55
56
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
# File 'lib/net/ssh/connection/event_loop.rb', line 54

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
# 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