gpt4 book ai didi

ruby - 使用 postgresql gem 异步

转载 作者:数据小太阳 更新时间:2023-10-29 06:51:59 25 4
gpt4 key购买 nike

我正在使用 Goliath (由 eventmachine 提供支持)和 postgres gem pg,目前我以阻塞方式使用 pg gem:conn.exec('SELECT * FROM products')(例如)我想知道是否有更好的方法连接到 postgres 数据库?

最佳答案

pg 库提供对 PostgreSQL 异步 API 的全面支持。我添加了 an example如何使用它到 samples/ 目录:

#!/usr/bin/env ruby

require 'pg'

# This is a example of how to use the asynchronous API to query the
# server without blocking other threads. It's intentionally low-level;
# if you hooked up the PGconn#socket to some kind of reactor, you
# could make this much nicer.

TIMEOUT = 5.0 # seconds to wait for an async operation to complete
CONN_OPTS = {
:host => 'localhost',
:dbname => 'test',
:user => 'jrandom',
:password => 'banks!stealUR$',
}

# Print 'x' continuously to demonstrate that other threads aren't
# blocked while waiting for the connection, for the query to be sent,
# for results, etc. You might want to sleep inside the loop or
# comment this out entirely for cleaner output.
progress_thread = Thread.new { loop { print 'x' } }

# Output progress messages
def output_progress( msg )
puts "\n>>> #{msg}\n"
end

# Start the connection
output_progress "Starting connection..."
conn = PGconn.connect_start( CONN_OPTS ) or
abort "Unable to create a new connection!"
abort "Connection failed: %s" % [ conn.error_message ] if
conn.status == PGconn::CONNECTION_BAD

# Now grab a reference to the underlying socket so we know when the
# connection is established
socket = IO.for_fd( conn.socket )

# Track the progress of the connection, waiting for the socket to
# become readable/writable before polling it
poll_status = PGconn::PGRES_POLLING_WRITING
until poll_status == PGconn::PGRES_POLLING_OK ||
poll_status == PGconn::PGRES_POLLING_FAILED

# If the socket needs to read, wait 'til it becomes readable to
# poll again
case poll_status
when PGconn::PGRES_POLLING_READING
output_progress " waiting for socket to become readable"
select( [socket], nil, nil, TIMEOUT ) or
raise "Asynchronous connection timed out!"

# ...and the same for when the socket needs to write
when PGconn::PGRES_POLLING_WRITING
output_progress " waiting for socket to become writable"
select( nil, [socket], nil, TIMEOUT ) or
raise "Asynchronous connection timed out!"
end

# Output a status message about the progress
case conn.status
when PGconn::CONNECTION_STARTED
output_progress " waiting for connection to be made."
when PGconn::CONNECTION_MADE
output_progress " connection OK; waiting to send."
when PGconn::CONNECTION_AWAITING_RESPONSE
output_progress " waiting for a response from the server."
when PGconn::CONNECTION_AUTH_OK
output_progress " received authentication; waiting for " +
"backend start-up to finish."
when PGconn::CONNECTION_SSL_STARTUP
output_progress " negotiating SSL encryption."
when PGconn::CONNECTION_SETENV
output_progress " negotiating environment-driven " +
"parameter settings."
end

# Check to see if it's finished or failed yet
poll_status = conn.connect_poll
end

abort "Connect failed: %s" % [ conn.error_message ] unless
conn.status == PGconn::CONNECTION_OK

output_progress "Sending query"
conn.send_query( "SELECT * FROM pg_stat_activity" )

# Fetch results until there aren't any more
loop do
output_progress " waiting for a response"

# Buffer any incoming data on the socket until a full result
# is ready.
conn.consume_input
while conn.is_busy
select( [socket], nil, nil, TIMEOUT ) or
raise "Timeout waiting for query response."
conn.consume_input
end

# Fetch the next result. If there isn't one, the query is
# finished
result = conn.get_result or break

puts "\n\nQuery result:\n%p\n" % [ result.values ]
end

output_progress "Done."
conn.finish

if defined?( progress_thread )
progress_thread.kill
progress_thread.join
end

我建议您阅读有关 PQconnectStart 的文档函数和 Asynchronous Command Processing PostgreSQL 手册的部分,然后将其与上面的示例进行比较。

我以前没有使用过 EventMachine,但如果它允许您注册套接字并在它变得可读/可写时进行回调,我认为将数据库调用集成到其中会相当容易。

我一直想使用 Ilya Grigorik's article on using Fibers to clean up evented code 中的想法使异步 API 更易于使用,但这还有很长的路要走。我有 a ticket open如果您有兴趣/有动力自己做,可以跟踪它。

关于ruby - 使用 postgresql gem 异步,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5893524/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com