Class: Fibril::NonBlockingIOWrapper

Inherits:
Object
  • Object
show all
Defined in:
lib/fibril/non_blocking_io_wrapper.rb

Direct Known Subclasses

ForkedNonBlockingIOWrapper

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(&block) ⇒ NonBlockingIOWrapper

Returns a new instance of NonBlockingIOWrapper.



11
12
13
14
15
16
17
18
19
20
21
22
23
# File 'lib/fibril/non_blocking_io_wrapper.rb', line 11

def initialize(*, &block)
  self.response_queue = []
  self.fibrils = []
  define_singleton_method(:loop, &block)
  future{
    begin
      loop()
    rescue Exception => e
      puts "Exception occurred in thead #{Thread.current} : #{e.message}"
      puts e.backtrace
    end
  }
end

Instance Attribute Details

#fibrilsObject

A Non block IO wrapper allows you to execute a blocking IO loop inside a separate thread and receive all inputs inside one or more Fibrils.

This allows you to have multiple block IO loops operating in parallel whilst still processing all resulting messages in the main thread.



9
10
11
# File 'lib/fibril/non_blocking_io_wrapper.rb', line 9

def fibrils
  @fibrils
end

#guardObject

A Non block IO wrapper allows you to execute a blocking IO loop inside a separate thread and receive all inputs inside one or more Fibrils.

This allows you to have multiple block IO loops operating in parallel whilst still processing all resulting messages in the main thread.



9
10
11
# File 'lib/fibril/non_blocking_io_wrapper.rb', line 9

def guard
  @guard
end

#response_queueObject

A Non block IO wrapper allows you to execute a blocking IO loop inside a separate thread and receive all inputs inside one or more Fibrils.

This allows you to have multiple block IO loops operating in parallel whilst still processing all resulting messages in the main thread.



9
10
11
# File 'lib/fibril/non_blocking_io_wrapper.rb', line 9

def response_queue
  @response_queue
end

#resultObject

A Non block IO wrapper allows you to execute a blocking IO loop inside a separate thread and receive all inputs inside one or more Fibrils.

This allows you to have multiple block IO loops operating in parallel whilst still processing all resulting messages in the main thread.



9
10
11
# File 'lib/fibril/non_blocking_io_wrapper.rb', line 9

def result
  @result
end

Instance Method Details

#awaitObject



50
51
52
53
54
55
56
57
58
59
# File 'lib/fibril/non_blocking_io_wrapper.rb', line 50

def await
  ##
  # Set all fibrils into waiting state until there is something in the response queue
  ##
  Fibril.current.yield{|f| self.fibrils << f} until self.response_queue.any?
  ##
  # Return values from the response queue
  ##
  self.response_queue.shift
end

#ingest(*args) ⇒ Object

Add the ingested message to the response queue and schedule all fibrils waiting on events to receive messages



40
41
42
43
44
45
46
47
48
# File 'lib/fibril/non_blocking_io_wrapper.rb', line 40

def ingest(*args)
  begin
    self.response_queue << args
    self.fibrils.shift.enqueue while self.fibrils.any?
  rescue Exception => e
    puts "Exception occurred when ingesting from #{self} : #{e.message}"
    puts e.backtrace
  end
end

#receive(*args) ⇒ Object

Receive a message from the async IO loop if a message is sent, otherwise return a reference to the ingest method



28
29
30
31
32
33
34
# File 'lib/fibril/non_blocking_io_wrapper.rb', line 28

def receive(*args)
  if args.any?
    ingest(*args)
  else
    method(:ingest)
  end
end