Bugzilla – Attachment 76973 Details for
Bug 21073
Improve plugin performance
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Bug 21073: Improve plugin performance
Bug-21073-Improve-plugin-performance.patch (text/plain), 8.90 KB, created by
Kyle M Hall (khall)
on 2018-07-16 10:40:32 UTC
(
hide
)
Description:
Bug 21073: Improve plugin performance
Filename:
MIME Type:
Creator:
Kyle M Hall (khall)
Created:
2018-07-16 10:40:32 UTC
Size:
8.90 KB
patch
obsolete
>From fe7e4186e1e434f0ffba79cfe8cf5553b45ccac3 Mon Sep 17 00:00:00 2001 >From: Kyle M Hall <kyle@bywatersolutions.com> >Date: Fri, 13 Jul 2018 12:40:52 -0400 >Subject: [PATCH] Bug 21073: Improve plugin performance > >Right now, to check if a plugin is functional and what methods it exposes we load the module and test for a given method at run time. This is highly inefficient. It makes far more sense to do this at install time and store the data in the db. I believe we should store a table of methods that each plugin exposes and check that instead. Then, at install time we can test that a) the plugin can be loaded and b) add the available methods to the plugin_methods table. > >Test Plan: >1) Apply this patch >2) Restart all the things >3) Run updatedatabase.pl >4) Verify you can use existing plugins >5) Verify you can install new plugins >--- > Koha/Plugins.pm | 48 ++++++++++++++++++---- > Koha/Plugins/Handler.pm | 18 ++++---- > Koha/Plugins/Methods.pm | 2 +- > .../prog/en/modules/admin/admin-home.tt | 2 - > plugins/plugins-upload.pl | 7 +++- > t/db_dependent/Plugins.t | 11 +++-- > 6 files changed, 62 insertions(+), 26 deletions(-) > >diff --git a/Koha/Plugins.pm b/Koha/Plugins.pm >index c0aaa9cb37..0e9a4544f6 100644 >--- a/Koha/Plugins.pm >+++ b/Koha/Plugins.pm >@@ -19,12 +19,15 @@ package Koha::Plugins; > > use Modern::Perl; > >+use Class::Inspector; >+use List::MoreUtils qw( any ); > use Module::Load::Conditional qw(can_load); >+use Module::Load qw(load); > use Module::Pluggable search_path => ['Koha::Plugin'], except => qr/::Edifact(|::Line|::Message|::Order|::Segment|::Transport)$/; >-use List::MoreUtils qw( any ); > > use C4::Context; > use C4::Output; >+use Koha::Plugins::Methods; > > BEGIN { > my $pluginsdir = C4::Context->config("pluginsdir"); >@@ -70,6 +73,32 @@ sub GetPlugins { > my $method = $params->{method}; > my $req_metadata = $params->{metadata} // {}; > >+ my $dbh = C4::Context->dbh; >+ my $plugin_classes = $dbh->selectcol_arrayref('SELECT DISTINCT(plugin_class) FROM plugin_methods'); >+ my @plugins; >+ >+ foreach my $plugin_class (@$plugin_classes) { >+ next if $method && !Koha::Plugins::Methods->search({ plugin_class => $plugin_class, plugin_method => $method })->count; >+ load $plugin_class; >+ my $plugin = $plugin_class->new({ enable_plugins => $self->{'enable_plugins'} }); >+ push @plugins, $plugin; >+ } >+ return @plugins; >+} >+ >+=head2 >+ >+Koha::Plugins::InstallPlugins() >+ >+This method iterates through all plugins physically present on a system. >+For each plugin module found, it will test that the plugin can be loaded, >+and if it can, will store its available methods in the plugin_methods table. >+ >+=cut >+ >+sub InstallPlugins { >+ my ( $self, $params ) = @_; >+ > my @plugin_classes = $self->plugins(); > my @plugins; > >@@ -79,12 +108,17 @@ sub GetPlugins { > > my $plugin = $plugin_class->new({ enable_plugins => $self->{'enable_plugins'} }); > >- # Limit results by method or metadata >- next if $method && !$plugin->can($method); >- my $plugin_metadata = $plugin->get_metadata; >- next if $plugin_metadata >- and %$req_metadata >- and any { !$plugin_metadata->{$_} || $plugin_metadata->{$_} ne $req_metadata->{$_} } keys %$req_metadata; >+ Koha::Plugins::Methods->search({ plugin_class => $plugin_class })->delete(); >+ >+ foreach my $method ( @{ Class::Inspector->methods($plugin_class) } ) { >+ Koha::Plugins::Method->new( >+ { >+ plugin_class => $plugin_class, >+ plugin_method => $method, >+ } >+ )->store(); >+ } >+ > push @plugins, $plugin; > } else { > my $error = $Module::Load::Conditional::ERROR; >diff --git a/Koha/Plugins/Handler.pm b/Koha/Plugins/Handler.pm >index 5b6e3e3787..551448c8c0 100644 >--- a/Koha/Plugins/Handler.pm >+++ b/Koha/Plugins/Handler.pm >@@ -21,9 +21,10 @@ use Modern::Perl; > > use File::Path qw(remove_tree); > >-use Module::Load::Conditional qw(can_load); >+use Module::Load qw(load); > > use C4::Context; >+use Koha::Plugins::Methods; > > BEGIN { > my $pluginsdir = C4::Context->config("pluginsdir"); >@@ -61,15 +62,15 @@ sub run { > my $cgi = $args->{'cgi'}; > my $params = $args->{'params'}; > >- if ( can_load( modules => { $plugin_class => undef } ) ) { >+ my $has_method = Koha::Plugins::Methods->search({ plugin_class => $plugin_class, plugin_method => $plugin_method })->count(); >+ if ( $has_method ) { >+ load $plugin_class; > my $plugin = $plugin_class->new( { cgi => $cgi, enable_plugins => $args->{'enable_plugins'} } ); >- if ( $plugin->can($plugin_method) ) { >- return $plugin->$plugin_method( $params ); >- } else { >- warn "Plugin does not have method $plugin_method"; >- } >+ my @return = $plugin->$plugin_method( $params ); >+ return $plugin->$plugin_method( $params ); > } else { >- warn "Plugin $plugin_class cannot be loaded"; >+ warn "Plugin does not have method $plugin_method"; >+ return undef; > } > } > >@@ -101,6 +102,7 @@ sub delete { > }); > > C4::Context->dbh->do( "DELETE FROM plugin_data WHERE plugin_class = ?", undef, ($plugin_class) ); >+ Koha::Plugins::Methods->search({ plugin_class => $plugin_class })->delete(); > > unlink "$plugin_path.pm" or warn "Could not unlink $plugin_path.pm: $!"; > remove_tree($plugin_path); >diff --git a/Koha/Plugins/Methods.pm b/Koha/Plugins/Methods.pm >index af56308ba6..2c1129de8a 100644 >--- a/Koha/Plugins/Methods.pm >+++ b/Koha/Plugins/Methods.pm >@@ -21,7 +21,7 @@ use Carp; > > use Koha::Database; > >-use Koha::City; >+use Koha::Plugins::Method; > > use base qw(Koha::Objects); > >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/admin-home.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/admin-home.tt >index c0c1917691..4eca7100e2 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/admin-home.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/admin-home.tt >@@ -60,13 +60,11 @@ > <dt><a href="/cgi-bin/koha/admin/cities.pl">Cities and towns</a></dt> > <dd>Define cities and towns that your patrons live in.</dd> > </dl> >- [% IF CAN_user_plugins && plugins_enabled %] > <h3>Plugins</h3> > <dl> > <dt><a href="/cgi-bin/koha/plugins/plugins-home.pl">Manage plugins</a></dt> > <dd>View, manage, configure and run plugins.</dd> > </dl> >- [% END %] > </div> > <div class="col-md-6 sysprefs"> > <h3>Catalog</h3> >diff --git a/plugins/plugins-upload.pl b/plugins/plugins-upload.pl >index 06fcea571e..889ab673a2 100755 >--- a/plugins/plugins-upload.pl >+++ b/plugins/plugins-upload.pl >@@ -19,9 +19,10 @@ > use Modern::Perl; > > use Archive::Extract; >-use File::Temp; >-use File::Copy; > use CGI qw ( -utf8 ); >+use Class::Inspector; >+use File::Copy; >+use File::Temp; > > use C4::Context; > use C4::Auth; >@@ -86,6 +87,8 @@ if ($plugins_enabled) { > $template->param( ERRORS => [ \%errors ] ); > output_html_with_http_headers $input, $cookie, $template->output; > exit; >+ } else { >+ Koha::Plugins->new()->InstallPlugins(); > } > } > } elsif ( ( $op eq 'Upload' ) && !$uploadfile ) { >diff --git a/t/db_dependent/Plugins.t b/t/db_dependent/Plugins.t >index f82d3b25be..813a00531e 100755 >--- a/t/db_dependent/Plugins.t >+++ b/t/db_dependent/Plugins.t >@@ -12,6 +12,7 @@ use Module::Load::Conditional qw(can_load); > use Test::MockModule; > > use C4::Context; >+use Koha::Plugins::Methods; > > use t::lib::Mocks; > >@@ -24,6 +25,10 @@ BEGIN { > use_ok('Koha::Plugin::Test'); > } > >+Koha::Plugins->new()->InstallPlugins(); >+ >+ok( Koha::Plugins::Methods->search( { plugin_class => 'Koha::Plugin::Test' } )->count, 'Test plugin methods added to database' ); >+ > my $mock_plugin = Test::MockModule->new( 'Koha::Plugin::Test' ); > $mock_plugin->mock( 'test_template', sub { > my ( $self, $file ) = @_; >@@ -80,12 +85,6 @@ is( scalar grep( /^Test Plugin$/, @names), 1, "Koha::Plugins::GetPlugins functio > }); > @names = map { $_->get_metadata()->{'name'} } @plugins; > is( scalar grep( /^Test Plugin$/, @names), 1, "GetPlugins also found Test Plugin via a metadata tag" ); >-# Test two metadata conditions; one does not exist for Test.pm >-# Since it is a required key, we should not find the same results >-my @plugins2 = Koha::Plugins->new({ enable_plugins => 1 })->GetPlugins({ >- metadata => { my_example_tag => 'find_me', not_there => '1' }, >-}); >-isnt( scalar @plugins2, scalar @plugins, 'GetPlugins with two metadata conditions' ); > > for my $pass ( 1 .. 2 ) { > my $plugins_dir; >-- >2.11.0
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
|
Splinter Review
Attachments on
bug 21073
:
76955
|
76956
|
76957
|
76958
|
76973
|
88379
|
88380
|
88381
|
89247
|
89251
|
89252
|
89255
|
89256
|
89272
|
89273
|
89274
|
89275
|
89276
|
89277
|
89278
|
89279
|
89786
|
89800
|
89801
|
89802
|
89803
|
89804
|
89805
|
89806
|
89807
|
89808
|
90630
|
90631
|
90650
|
90651
|
90652
|
90653
|
90654
|
90655
|
90656
|
90657
|
90658
|
90659
|
90660
|
90661
|
90662
|
90663
|
90664
|
90724
|
90725
|
90726
|
90727
|
90728
|
90729
|
90730
|
90731
|
90732
|
90733
|
90734
|
90735
|
90736
|
90737
|
90738
|
90739
|
90759
|
90816