Dancer2-Plugin-DBIC-Async
view release on metacpan or search on metacpan
lib/Dancer2/Plugin/DBIC/Async.pm view on Meta::CPAN
package Dancer2::Plugin::DBIC::Async;
$Dancer2::Plugin::DBIC::Async::VERSION = '0.06';
$Dancer2::Plugin::DBIC::Async::AUTHORITY = 'cpan:MANWAR';
use strict;
use warnings;
use feature 'state';
use Dancer2::Plugin;
use IO::Async::Loop;
use DBIx::Class::Async::Schema;
use Module::Runtime qw(use_module);
=encoding utf8
=head1 NAME
Dancer2::Plugin::DBIC::Async - High-concurrency DBIx::Class bridge for Dancer2
=head1 VERSION
Version 0.06
=head1 BENEFITS
The primary benefit of this plugin is B<Concurrency Throughput>. Unlike traditional
database plugins that block your Dancer2 worker during a query, this plugin
delegates I/O to a background worker pool.
=head2 Non-Blocking I/O (Concurrency)
In a traditional sync app, if a database query takes B<500ms>, that L<Dancer2>
worker is B<"busy"> and cannot accept any other incoming requests for that
B<half a second>.
=over 4
=item Sync
B<10 workers> can handle exactly B<10 simultaneous long-running queries>. The
11th user must wait in the B<TCP queue>.
=item Async
A single worker can initiate dozens of database queries. While the database is
processing the data, the worker remains free to handle other incoming requests
or perform other I/O tasks.
=back
=head2 Parallelism within a Single Route
With the sync plugin, if you need to fetch data from five different tables that don't depend on
each other, you must do them sequentially. With the async plugin, you can fire all five queries
simultaneously.
# Regular Sync (Total time = sum of all queries)
my $user = rset('User')->find(1);
my $posts = rset('Post')->search({ uid => 1 });
my $friends = rset('Friend')->search({ uid => 1 });
# Async (Total time = the time of the single slowest query)
my $user_f = async_rs('User')->find(1);
my $posts_f = async_rs('Post')->search({ uid => 1 });
my $friends_f = async_rs('Friend')->search({ uid => 1 });
# Wait for all to finish
my ($user, $posts, $friends) = Future->wait_all($user_f, $posts_f, $friends_f)->get;
=head2 Key Technical Differences
=over 4
=item B<Context Switching>
In the sync version, the operating system might pause the process (context switch)
while waiting for the disk. In the async version, the Event Loop (L<IO::Async>) manages
this, which is much lighter on the CPU.
=item B<Wait vs. Block>
In the async version, we use B<wait_all> or B<then>. This tells the server:
B<"Keep this request in mind, but go help other users until the data comes back.">
=item B<Error Handling>
L<Futures> have built-in B<on_fail> handlers, making it easier to manage database
timeouts without crashing the whole worker process.
=back
=head2 Better Resource Utilisation
( run in 0.921 second using v1.01-cache-2.11-cpan-39bf76dae61 )