Class: PgBouncerRunner

Inherits:
Object
  • Object
show all
Defined in:
lib/dblink/pg_bouncer_runner.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(pg_port: 5432, pg_user: ENV['USER'], pg_password: '', pg_host: '127.0.0.1', pg_db: ENV['USER'], verbose: true) ⇒ PgBouncerRunner

Returns a new instance of PgBouncerRunner.



6
7
8
9
10
11
12
13
14
15
# File 'lib/dblink/pg_bouncer_runner.rb', line 6

def initialize(pg_port: 5432, pg_user: ENV['USER'], pg_password: '', pg_host: '127.0.0.1', pg_db: ENV['USER'], verbose: true)
  @pg_port = pg_port
  @pg_user = pg_user
  @pg_password = pg_password
  @pg_host = pg_host
  @pg_db = pg_db
  @verbose = verbose

  @pgb_port = Network.find_available_port
end

Instance Attribute Details

#pg_dbObject (readonly)

Returns the value of attribute pg_db.



2
3
4
# File 'lib/dblink/pg_bouncer_runner.rb', line 2

def pg_db
  @pg_db
end

#pg_hostObject (readonly)

Returns the value of attribute pg_host.



2
3
4
# File 'lib/dblink/pg_bouncer_runner.rb', line 2

def pg_host
  @pg_host
end

#pg_passwordObject (readonly)

Returns the value of attribute pg_password.



2
3
4
# File 'lib/dblink/pg_bouncer_runner.rb', line 2

def pg_password
  @pg_password
end

#pg_portObject (readonly)

Returns the value of attribute pg_port.



2
3
4
# File 'lib/dblink/pg_bouncer_runner.rb', line 2

def pg_port
  @pg_port
end

#pg_userObject (readonly)

Returns the value of attribute pg_user.



2
3
4
# File 'lib/dblink/pg_bouncer_runner.rb', line 2

def pg_user
  @pg_user
end

#pgb_passwordObject (readonly)

Returns the value of attribute pgb_password.



3
4
5
# File 'lib/dblink/pg_bouncer_runner.rb', line 3

def pgb_password
  @pgb_password
end

#pgb_portObject (readonly)

Returns the value of attribute pgb_port.



3
4
5
# File 'lib/dblink/pg_bouncer_runner.rb', line 3

def pgb_port
  @pgb_port
end

#pgb_userObject (readonly)

Returns the value of attribute pgb_user.



3
4
5
# File 'lib/dblink/pg_bouncer_runner.rb', line 3

def pgb_user
  @pgb_user
end

#runner_pidObject (readonly)

Returns the value of attribute runner_pid.



4
5
6
# File 'lib/dblink/pg_bouncer_runner.rb', line 4

def runner_pid
  @runner_pid
end

#runner_threadObject (readonly)

Returns the value of attribute runner_thread.



4
5
6
# File 'lib/dblink/pg_bouncer_runner.rb', line 4

def runner_thread
  @runner_thread
end

#tmp_folderObject (readonly)

Returns the value of attribute tmp_folder.



4
5
6
# File 'lib/dblink/pg_bouncer_runner.rb', line 4

def tmp_folder
  @tmp_folder
end

Instance Method Details

#create_configObject



103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/dblink/pg_bouncer_runner.rb', line 103

def create_config
  @tmp_folder = Dir.mktmpdir
  FileUtils.chmod(0777, @tmp_folder)
  pgb_config = render_template('config.ini.erb', {})
  File.open(@tmp_folder + '/config.ini', 'w') {|f| f.write(pgb_config) }

  @pgb_user = "share"
  @pgb_password = SecureRandom.hex(10)
  File.open(@tmp_folder + '/users.txt', 'w') {|f|
    f.write(%{"#{@pgb_user}" "#{@pgb_password}"})
  }
end

#make_db_url(remote_port) ⇒ Object



116
117
118
# File 'lib/dblink/pg_bouncer_runner.rb', line 116

def make_db_url(remote_port)
  "postgres://#{pgb_user}:#{pgb_password}@dblink.tk:#{remote_port}/#{pg_db}"
end

#pgbouncer_pathObject



59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/dblink/pg_bouncer_runner.rb', line 59

def pgbouncer_path
  if RUBY_PLATFORM =~ /darwin/
    BASE_DIR + '/pgbouncer'
  else

    path = `which pgbouncer 2>/dev/null`
    if path == ''
      puts "Can not find pgbouncer in your system"
      puts "Please install it"
      exit(1)
    else
      return path.strip
    end

  end
end

#runObject



17
18
19
20
21
22
23
24
25
26
27
28
29
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
55
56
57
# File 'lib/dblink/pg_bouncer_runner.rb', line 17

def run
  create_config unless @tmp_folder

  verbose_arg = @verbose ? '-v' : ''
  pgb_user_arg = CLI_OPTS[:pgbouncer_user] ? "-u #{CLI_OPTS[:pgbouncer_user]}" : ""
  pgb_command = "#{pgbouncer_path} #{verbose_arg} #{pgb_user_arg} ./config.ini"

  if @verbose
    puts "Running pgbouncer with config at: #{@tmp_folder}"
    puts "EXEC #{pgb_command}"
  end

  Dir.chdir(@tmp_folder) do
    Open3.popen3(pgb_command) {|stdin, stdout, stderr, wait_thr|
      @runner_pid = wait_thr.pid # pid of the started process.
      #p "process_started: #{pid}"
      Thread.new do
        begin
          while line = stdout.gets
            puts "STDOUT: #{line}" if @verbose
          end
        rescue Exception => error
          puts error.message
          puts error.backtrace
        end
      end
      Thread.new do
        begin
          while line = stderr.gets
            puts "STDERR: #{line}" if @verbose
          end
        rescue Exception => error
          puts error.message
          puts error.backtrace
        end
      end
      exit_status = wait_thr.value # Process::Status object returned.
      puts "pgbouncer stoped: #{exit_status}" if @verbose
    }
  end
end

#run_asyncObject



82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/dblink/pg_bouncer_runner.rb', line 82

def run_async
  @runner_thread = Thread.new do
    begin
      run
    rescue Exception => error
      puts error.message
      puts error.backtrace
    end
  end

  self
end

#stop_asyncObject



76
77
78
79
80
# File 'lib/dblink/pg_bouncer_runner.rb', line 76

def stop_async
  if @runner_pid && System.process_alive?(@runner_pid, verbose: @verbose)
    System.stop_process(@runner_pid)
  end
end

#wait_for_pidObject



95
96
97
98
99
100
101
# File 'lib/dblink/pg_bouncer_runner.rb', line 95

def wait_for_pid
  while !@runner_pid
    sleep 0.04
  end

  @runner_pid
end