FU: Implement --monitor, add some docs; FU::Util: add fdpass functions

This commit is contained in:
Yorhel 2025-02-15 14:58:00 +01:00
parent 09fe50d2a2
commit 3e84a4f4d3
8 changed files with 480 additions and 99 deletions

View file

@ -42,7 +42,7 @@ directly with C<libpq>.
=over
=item B<< FU::Pg->connect($string) >>
=item FU::Pg->connect($string)
Connect to the PostgreSQL server and return a new C<FU::Pg::conn> object.
C<$string> can either be in key=value format or a URI, refer to L<the
@ -52,17 +52,17 @@ for the full list of supported formats and options. You may also pass an empty
string and leave the configuration up L<environment
variables|https://www.postgresql.org/docs/current/libpq-envars.html>.
=item B<< $conn->server_version >>
=item $conn->server_version
Returns the version of the PostgreSQL server as an integer in the format of
C<$major * 10000 + $minor>. For example, returns 170002 for PostgreSQL 17.2.
=item B<< $conn->lib_version >>
=item $conn->lib_version
Returns the libpq version in the same format as the C<server_version> method.
Also available directly as C<FU::Pg::lib_version()>.
=item B<< $conn->status >>
=item $conn->status
Returns a string indicating the status of the connection. Note that this method
does not verify that the connection is still alive, the status is updated after
@ -95,17 +95,17 @@ Connection is dead or otherwise unusable.
=back
=item B<< $conn->cache($enable) >>
=item $conn->cache($enable)
=item B<< $conn->text_params($enable) >>
=item $conn->text_params($enable)
=item B<< $conn->text_results($enable) >>
=item $conn->text_results($enable)
=item B<< $conn->text($enable) >>
=item $conn->text($enable)
Set the default settings for new statements created with B<< $conn->q() >>.
=item B<< $conn->cache_size($num) >>
=item $conn->cache_size($num)
Set the number of prepared statements to keep in the cache. Defaults to 256.
@ -114,7 +114,7 @@ Prepared statements that still have an active C<$st> object are not counted
towards this number. The cache works as an LRU: when it's full, the statement
that hasn't been used for the longest time is reclaimed.
=item B<< $conn->disconnect >>
=item $conn->disconnect
Close the connection. Any active transactions are rolled back and any further
attempts to use C<$conn> throw an error.
@ -125,13 +125,13 @@ attempts to use C<$conn> throw an error.
=over
=item B<< $conn->exec($sql) >>
=item $conn->exec($sql)
Execute one or more SQL commands, separated by a semicolon. Returns the number
of rows affected by the last statement or I<undef> if that information is not
available for the given command (like with C<CREATE TABLE>).
=item B<< $conn->q($sql, @params) >>
=item $conn->q($sql, @params)
Create a new SQL statement with the given C<$sql> string and an optional list
of bind parameters. C<$sql> can only hold a single statement.
@ -154,19 +154,19 @@ configuration parameters:
=over
=item B<< $st->cache($enable) >>
=item $st->cache($enable)
Enable or disable caching of the prepared statement for this particular query.
=item B<< $st->text_params($enable) >>
=item $st->text_params($enable)
Enable or disable sending bind parameters in the text format.
=item B<< $st->text_results($enable) >>
=item $st->text_results($enable)
Enable or disable receiving query results in the text format.
=item B<< $st->text($enable) >>
=item $st->text($enable)
Shorthand for setting C<text_params> and C<text_results> at the same time.
@ -176,7 +176,7 @@ Statement objects can be inspected with the following two methods:
=over
=item B<< $st->param_types >>
=item $st->param_types
Returns an arrayref of integers indicating the type (as I<oid>) of each
parameter in the given C<$sql> string. Example:
@ -187,7 +187,7 @@ parameter in the given C<$sql> string. Example:
my $oids = $conn->q('SELECT id FROM books')->params;
# $oids = []
=item B<< $st->columns >>
=item $st->columns
Returns an arrayref of hashrefs describing each column that the statement
returns.
@ -206,7 +206,7 @@ how you'd like to obtain the results:
=over
=item B<< $st->exec >>
=item $st->exec
Execute the query and return the number of rows affected. Similar to C<<
$conn->exec >>.
@ -214,7 +214,7 @@ $conn->exec >>.
my $v = $conn->q('UPDATE books SET read = true WHERE id = 1')->exec;
# $v = 1
=item B<< $st->val >>
=item $st->val
Return the first column of the first row. Throws an error if the query does not
return exactly one column, or if multiple rows are returned. Returns I<undef>
@ -223,7 +223,7 @@ if no rows are returned or if its value is I<NULL>.
my $v = $conn->q('SELECT COUNT(*) FROM books')->val;
# $v = 2
=item B<< $st->rowl >>
=item $st->rowl
Return the first row as a list. Throws an error if the query does not return
exactly one row.
@ -231,7 +231,7 @@ exactly one row.
my($id, $title) = $conn->q('SELECT id, title FROM books LIMIT 1')->rowl;
# ($id, $title) = (1, 'Revelation Space');
=item B<< $st->rowa >>
=item $st->rowa
Return the first row as an arrayref, equivalent to C<< [$st->rowl] >> but
might be slightly more efficient.
@ -239,7 +239,7 @@ might be slightly more efficient.
my $row = $conn->q('SELECT id, title FROM books LIMIT 1')->rowa;
# $row = [1, 'Revelation Space'];
=item B<< $st->rowh >>
=item $st->rowh
Return the first row as a hashref. Also throws an error if the query returns
multiple columns with the same name.
@ -247,7 +247,7 @@ multiple columns with the same name.
my $row = $conn->q('SELECT id, title FROM books LIMIT 1')->rowh;
# $row = { id => 1, title => 'Revelation Space' };
=item B<< $st->alla >>
=item $st->alla
Return all rows as an arrayref of arrayrefs.
@ -257,7 +257,7 @@ Return all rows as an arrayref of arrayrefs.
# [ 2, 'The Invincible' ],
# ];
=item B<< $st->allh >>
=item $st->allh
Return all rows as an arrayref of hashrefs. Throws an error if the query
returns multiple columns with the same name.
@ -268,7 +268,7 @@ returns multiple columns with the same name.
# { id => 2, title => 'The Invincible' },
# ];
=item B<< $st->flat >>
=item $st->flat
Return an arrayref with all rows flattened.
@ -278,7 +278,7 @@ Return an arrayref with all rows flattened.
# 2, 'The Invincible',
# ];
=item B<< $st->kvv >>
=item $st->kvv
Return a hashref where the first result column is used as key and the second
column as value. If the query only returns a single column, C<true> is used as
@ -290,7 +290,7 @@ value instead. An error is thrown if the query returns 3 or more columns.
# 2 => 'The Invincible',
# };
=item B<< $st->kva >>
=item $st->kva
Return a hashref where the first result column is used as key and the remaining
columns are stored as arrayref.
@ -301,7 +301,7 @@ columns are stored as arrayref.
# 2 => [ 'The Invincible', false ],
# };
=item B<< $st->kvh >>
=item $st->kvh
Return a hashref where the first result column is used as key and the remaining
columns are stored as hashref.
@ -355,16 +355,16 @@ Transaction methods:
=over
=item B<< $txn->exec(..) >>
=item $txn->exec(..)
=item B<< $txn->q(..) >>
=item $txn->q(..)
Run a query inside the transaction. These work the same as the respective
methods on the parent C<$conn> object.
=item B<< $txn->commit >>
=item $txn->commit
=item B<< $txn->rollback >>
=item $txn->rollback
Commit or abort the transaction. Any attempts to run queries on this
transaction object after this call will throw an error.
@ -372,13 +372,13 @@ transaction object after this call will throw an error.
Calling C<rollback> is optional, the transaction is automatically rolled back
when the object goes out of scope.
=item B<< $txn->cache($enable) >>
=item $txn->cache($enable)
=item B<< $txn->text_params($enable) >>
=item $txn->text_params($enable)
=item B<< $txn->text_results($enable) >>
=item $txn->text_results($enable)
=item B<< $txn->text($enable) >>
=item $txn->text($enable)
Set the default settings for new statements created with B<< $txn->q() >>.
@ -387,13 +387,13 @@ created. Subtransactions inherit these settings from their parent transaction.
Changing these settings within a transaction does not affect the main
connection or any already existing subtransactions.
=item B<< $txn->txn >>
=item $txn->txn
Create a subtransaction within the current transaction. A subtransaction works
exactly the same as a top-level transaction, except any changes remain
invisible to other sessions until the top-level transaction has been committed.
=item B<< $txn->status >>
=item $txn->status
Like C<< $conn->status >>, but with the following status codes:

View file

@ -4,7 +4,10 @@ use v5.36;
use FU::XS;
use Exporter 'import';
our @EXPORT_OK = qw/json_format json_parse/;
our @EXPORT_OK = qw/
json_format json_parse
fdpass_send fdpass_recv
/;
1;
__END__
@ -150,3 +153,45 @@ unnecessary features and C<#ifdef>s to support ancient perls and esoteric
configurations. Still, if you need anything not provided by these functions,
L<JSON::PP> and L<Cpanel::JSON::XS> are perfectly fine alternatives.
L<JSON::SIMD> and L<Mojo::JSON> also look like good and maintained candidates.)
=head2 File Descriptor Passing
UNIX sockets (see L<IO::Socket::UNIX>) have the fancy property of letting you
send file descriptors over them, allowing you to pass, for example, a socket
from one process to another. This is a pretty low-level operation and not
something you'll often need, but two functions to use that feature are provided
here anyway because the L<FU> supervisor uses them:
=over
=item fdpass_send($send_fd, $pass_fd, $message)
Send a message and a file descriptor (C<$pass_fd>) over the given socket
(<$send_fd>). C<$message> must not be empty, even if you don't intend to do
anything with it on receipt. Both C<$send_fd> and C<$pass_fd> must be numeric
file descriptors, as obtained by C<fileno()>.
=item ($fd, $message) = fdpass_recv($recv_fd, $max_message_len)
Read a file descriptor and message from the given C<$recv_fd>, which must be
the numeric file descriptor of a socket. This function can be used as a
replacement for C<sysread()>: the returned C<$fd> is undef if no file
descriptor was received. The returned C<$message> is undef on error or an empty
string on EOF.
Like regular socket I/O, a single C<fdpass_send()> message may be split across
multiple C<fdpass_recv()> calls; in that case the C<$fd> will only be received
on the first call.
Don't use this function if the sender may include multiple file descriptors in
a single message, weird things can happen. File descriptors received this way
do not have the C<CLOEXEC> flag and will thus survive a call to C<exec()>.
Refer to L<this wonderful
discussion|https://gist.github.com/kentonv/bc7592af98c68ba2738f4436920868dc>
for more weirdness and edge cases.
=back
See also L<IO::FDPass> for a more portable solution, although that one does not
support passing along regular data.