Module: PG::EM::Client::ConnectWatcher

Defined in:
lib/pg/em/client/connect_watcher.rb

Overview

This module is used as a handler to ::EM.watch connection socket and it performs connection handshake with postgres server asynchronously.

Author

Rafal Michalski

Instance Method Summary collapse

Instance Method Details

#initialize(client, deferrable, is_reset) ⇒ Object



11
12
13
14
15
16
17
18
19
20
21
22
23
24
# File 'lib/pg/em/client/connect_watcher.rb', line 11

def initialize(client, deferrable, is_reset)
  @client = client
  @deferrable = deferrable
  @is_reset = is_reset
  @poll_method = is_reset ? :reset_poll : :connect_poll
  if (timeout = client.connect_timeout) > 0
    @timer = ::EM::Timer.new(timeout) do
      detach
      @deferrable.protect do
        @client.raise_error ConnectionBad, "timeout expired (async)"
      end
    end
  end
end

#poll_connection_and_checkObject Also known as: notify_writable, notify_readable



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
# File 'lib/pg/em/client/connect_watcher.rb', line 30

def poll_connection_and_check
  case @client.__send__(@poll_method)
  when PG::PGRES_POLLING_READING
    self.notify_readable = true
    self.notify_writable = false
    return
  when PG::PGRES_POLLING_WRITING
    self.notify_writable = true
    self.notify_readable = false
    return
  when PG::PGRES_POLLING_OK
    polling_ok = true if @client.status == PG::CONNECTION_OK
  end
  @timer.cancel if @timer
  detach
  @deferrable.protect do
    @client.raise_error ConnectionBad unless polling_ok
    @client.set_default_encoding unless reconnecting?
    if on_connect = @client.on_connect
      succeed_connection_with_hook(on_connect)
    else
      succeed_connection
    end
  end
end

#reconnecting?Boolean

Returns:

  • (Boolean)


26
27
28
# File 'lib/pg/em/client/connect_watcher.rb', line 26

def reconnecting?
  @is_reset
end

#succeed_connectionObject



56
57
58
# File 'lib/pg/em/client/connect_watcher.rb', line 56

def succeed_connection
  ::EM.next_tick { @deferrable.succeed @client }
end

#succeed_connection_with_hook(on_connect) ⇒ Object



60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/pg/em/client/connect_watcher.rb', line 60

def succeed_connection_with_hook(on_connect)
  ::EM.next_tick do
    Fiber.new do
      # call on_connect handler and fail if it raises an error
      begin
        returned_df = on_connect.call(@client, true, reconnecting?)
      rescue => ex
        @deferrable.fail ex
      else
        if returned_df.respond_to?(:callback) && returned_df.respond_to?(:errback)
          # the handler returned a deferrable
          returned_df.callback { @deferrable.succeed @client }
          # fail when handler's deferrable fails
          returned_df.errback { |ex| @deferrable.fail ex }
        else
          @deferrable.succeed @client
        end
      end
    end.resume
  end
end