Mojolicious-Plugin-Fondation-Model-DBIx-Async
view release on metacpan or search on metacpan
lib/Mojolicious/Plugin/Fondation/Model/DBIx/Async.pm view on Meta::CPAN
dsn => 'dbi:SQLite:dbname=data/app.db',
schema_class => 'MySchema',
workers => 2,
},
],
models => {
user => { source => 'User' },
},
}},
],
},
}
# In a controller
sub list ($self) {
$self->render_later;
$self->model('user')->search({ active => 1 })->all
->on_done(sub {
my @users = @_;
$self->render(json => [ map { $_->get_columns } @users ]);
})
->on_fail(sub { $self->reply->exception(shift) })
->retain;
}
=head1 DESCRIPTION
L<Mojolicious::Plugin::Fondation::Model::DBIx::Async> is a L<Fondation> plugin
that exposes L<DBIx::Class::Async> natively â no hashref CRUD wrapper, no
Future-to-Mojo::Promise conversion. Every call goes through a background worker
pool, keeping the L<Mojolicious> event loop responsive.
=head2 Architecture
âââââââââââââââââââââââââââââââââââââââââââââââââââ
â Mojolicious Application â
â $c->model('user') â ResultSet â
â $c->schema â DBIx::Class::Async::Schemaâ
ââââââââââââââââ¬âââââââââââââââââââââââââââââââââââ
â IO::Async::Loop::Mojo
ââââââââââââââââ¼âââââââââââââââââââââââââââââââââââ
â Worker Pool (forked processes) â
â ââââââââââ ââââââââââ ââââââââââ â
â âWorker 1â âWorker 2â âWorker Nâ â
â ââââââââââ ââââââââââ ââââââââââ â
ââââââââââââââââ¬âââââââââââââââââââââââââââââââââââ
â DBI
ââââââââââââââââ¼âââââââââââââââââââââââââââââââââââ
â Database â
âââââââââââââââââââââââââââââââââââââââââââââââââââ
Each backend is a separate L<DBIx::Class::Async::Schema> with its own
L<IO::Async::Loop::Mojo> and worker pool. Workers are forked lazily on
the first schema access and are automatically stopped on process exit.
=head2 Model discovery
During C<fondation_finalyze>, the plugin scans every loaded Fondation plugin
for a C<models> key in their configuration. Models declared by dependency
plugins are merged, with the application configuration taking priority.
Each model is validated to have a resolvable backend.
=head2 Source registration
The C<DBIx> action (L<Mojolicious::Plugin::Fondation::Model::DBIx::Async::Action::DBIx>)
auto-discovers C<Result> and C<ResultSet> classes under each plugin's
C<Schema::Result::*> and C<Schema::ResultSet::*> namespaces and registers them
on the native schema class I<before> workers are forked.
=head2 Shutdown
An C<END> block disconnects all schemas on clean process exit (Ctrl-C, C<kill>,
C<systemctl stop>), calling L<DBIx::Class::Async/disconnect> to gracefully
stop worker processes. The C<before_server_stop> hook is also emitted so
other code can react to shutdown. Only C<SIGKILL> bypasses this â no hook
can help there.
=head1 CONFIGURATION
'Fondation::Model::DBIx::Async' => {
backends => [
main => {
dsn => 'dbi:SQLite:dbname=data/app.db',
schema_class => 'MySchema',
user => '', # optional
pass => '', # optional
workers => 2, # default: 2
dbi_attrs => {}, # optional
},
logs => {
dsn => 'dbi:SQLite:dbname=data/logs.db',
schema_class => 'MyLogSchema',
workers => 1,
},
],
default_backend => 'main', # optional
models => {
user => { source => 'User' },
article => { source => 'articles', backend => 'main' },
log => { source => 'logs', backend => 'logs' },
},
},
=head3 backends
Array of name/config pairs (ordered). Each pair provides a backend name
followed by its configuration hash. Each backend requires C<dsn> and
C<schema_class>. Names are used by models and other plugins
to reference a specific connection.
Plain DSN strings are accepted as a shorthand and normalized to
C<< { dsn => $dsn } >>.
=head3 default_backend
Name of the default backend. When omitted, the first backend in the
C<backends> array is used. Models without an explicit C<backend> fall
back to this.
=head3 models
( run in 1.550 second using v1.01-cache-2.11-cpan-f4a522933cf )