Class: NeverBlock::DB::FiberedPostgresConnection

Inherits:
PGconn
  • Object
show all
Defined in:
lib/never_block/db/fibered_postgres_connection.rb

Overview

A modified postgres connection driver builds on the original pg driver. This driver is able to register the socket at a certain backend (EM or Rev) and then whenever the query is executed within the scope of a friendly fiber it will be done in async mode and the fiber will yield

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(*args) ⇒ FiberedPostgresConnection

Creates a new postgresql connection, sets it to nonblocking and wraps the descriptor in an IO object.



21
22
23
24
25
26
# File 'lib/never_block/db/fibered_postgres_connection.rb', line 21

def initialize(*args)
  super(*args)
  @fd = socket
  @io = IO.new(socket)
  setnonblocking(true)	
end

Instance Attribute Details

#fdObject (readonly)

needed to access the sockect by the event loop



16
17
18
# File 'lib/never_block/db/fibered_postgres_connection.rb', line 16

def fd
  @fd
end

#ioObject (readonly)

needed to access the sockect by the event loop



16
17
18
# File 'lib/never_block/db/fibered_postgres_connection.rb', line 16

def io
  @io
end

Instance Method Details

#exec(sql) ⇒ Object

Assuming the use of NeverBlock fiber extensions and that the exec is run in the context of a fiber. One that have the value :neverblock set to true. All neverblock IO classes check this value, setting it to false will force the execution in a blocking way.



32
33
34
35
36
37
38
39
40
# File 'lib/never_block/db/fibered_postgres_connection.rb', line 32

def exec(sql)
  if Fiber.respond_to? :current and Fiber.current[:neverblock]		      
    self.send_query sql
    @fiber = Fiber.current		      
    Fiber.yield 
  else		      
    super(sql)
  end		
end

#process_commandObject

The callback, this is called whenever there is data available at the socket



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/never_block/db/fibered_postgres_connection.rb', line 65

def process_command
  # make sure all commands are sent
  # before attempting to read
  return unless self.flush
  self.consume_input
  unless is_busy		
    res, data = 0, []
    while res != nil
      res = self.get_result
      data << res unless res.nil?
    end
    #let the fiber continue its work		      
    @fiber.resume(data.last)
  end
end

#register_with_event_loop(loop) ⇒ Object

Attaches the connection socket to an event loop. Currently only supports EM, but Rev support will be completed soon.



45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/never_block/db/fibered_postgres_connection.rb', line 45

def register_with_event_loop(loop)
  if loop == :em
    unless EM.respond_to?(:attach)
      puts "invalide EM version, please download the modified gem from: (TBA) "
      exit
    end
    if EM.reactor_running?
      EM::attach(@io,EMConnectionHandler,self)
    else
      raise "REACTOR NOT RUNNING YA ZALAMA"
    end 
  elsif loop.class.name == "REV::Loop"
    loop.attach(RevConnectionHandler.new(socket))
  else
    raise "could not register with the event loop"
  end
end