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 )