[Rt-commit] rt branch 5.0/fix-clear-mason-cache created. rt-5.0.2-28-g962ac0b031
BPS Git Server
git at git.bestpractical.com
Mon Dec 27 20:25:11 UTC 2021
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "rt".
The branch, 5.0/fix-clear-mason-cache has been created
at 962ac0b031b6e748de840a4fd4ef8c60dcbd86f8 (commit)
- Log -----------------------------------------------------------------
commit 962ac0b031b6e748de840a4fd4ef8c60dcbd86f8
Author: sunnavy <sunnavy at bestpractical.com>
Date: Tue Dec 28 03:26:17 2021 +0800
Test "Clear Mason Cache" functionality
diff --git a/t/web/mason-cache.t b/t/web/mason-cache.t
new file mode 100644
index 0000000000..237d77e82f
--- /dev/null
+++ b/t/web/mason-cache.t
@@ -0,0 +1,98 @@
+use strict;
+use warnings;
+
+use RT::Test tests => undef, config => 'Set($DevelMode, 0);';
+use JSON;
+use File::Temp;
+use File::Path 'make_path';
+use File::Spec;
+my $dir = File::Temp::tempdir( CLEANUP => 1 );
+my $column_map_dir = File::Spec->catdir( $dir, qw/Callbacks MasonCache Elements RT__Ticket ColumnMap/ );
+make_path($column_map_dir);
+
+my $once = File::Spec->catfile( $column_map_dir, 'Once' );
+my $hello = File::Spec->catfile( $dir, 'Hello.html' );
+
+update_mason( $once, <<'EOF' );
+<%INIT>
+$ARGS{COLUMN_MAP}{IDAndSubject} = {
+ title => 'ID-Subject',
+ value => sub { join '-', $_[0]->id, $_[0]->Subject },
+};
+</%INIT>
+EOF
+
+update_mason( $hello, 'Hello world!' );
+
+$RT::MasonLocalComponentRoot = $dir;
+
+my ( $baseurl, $m ) = RT::Test->started_ok;
+my $ticket = RT::Test->create_ticket( Queue => 'General', Subject => 'test mason cache' );
+
+$m->login;
+
+sleep 1; # Cache updates at most once per second.
+$m->post_ok( $baseurl . '/Admin/Helpers/ClearMasonCache' );
+is_deeply( from_json( $m->content ), { status => 1, message => 'Cache cleared' }, 'Cache cleared' );
+
+# Test multiple times to make sure once callback always takes effect.
+for ( 1 .. 3 ) {
+ $m->get_ok('/Search/Results.html?Query=id>0&Format=__IDAndSubject__');
+ $m->text_contains( 'ID-Subject', 'Column title' );
+ $m->text_contains( join( '-', $ticket->id, $ticket->Subject ), 'Column value' );
+}
+
+$m->get_ok('/Hello.html');
+$m->text_contains( 'Hello world!', 'Mason content' );
+
+update_mason( $once, <<'EOF' );
+<%INIT>
+$ARGS{COLUMN_MAP}{SubjectAndID} = {
+ title => 'Subject-ID',
+ value => sub { join '-', $_[0]->Subject, $_[0]->id },
+};
+</%INIT>
+EOF
+
+update_mason( $hello, 'Howdy world!' );
+
+# Test multiple times to make sure once callback always takes effect.
+for ( 1 .. 3 ) {
+ $m->get_ok('/Search/Results.html?Query=id>0&Format=__IDAndSubject__');
+ $m->text_contains( 'ID-Subject', 'Old Column title is still valid' );
+ $m->text_contains( join( '-', $ticket->id, $ticket->Subject ), 'Old Column value is still valid' );
+
+ $m->get_ok('/Search/Results.html?Query=id>0&Format=__SubjectAndID__');
+ $m->text_lacks( 'Subject-ID', 'New Column title is not yet' );
+ $m->text_lacks( join( '-', $ticket->Subject, $ticket->id ), 'New Column value is not yet' );
+}
+$m->get_ok('/Hello.html');
+$m->text_contains( 'Hello world!', 'Old mason content' );
+
+sleep 1; # Cache updates at most once per second.
+$m->post_ok( $baseurl . '/Admin/Helpers/ClearMasonCache' );
+is_deeply( from_json( $m->content ), { status => 1, message => 'Cache cleared' }, 'Cache cleared' );
+
+# Test multiple times to make sure once callback always takes effect.
+for ( 1 .. 3 ) {
+ $m->get_ok('/Search/Results.html?Query=id>0&Format=__IDAndSubject__');
+ $m->text_lacks( 'ID-Subject', 'Old Column title is gone' );
+ $m->text_lacks( join( '-', $ticket->id, $ticket->Subject ), 'Old Column value is gone' );
+
+ $m->get_ok('/Search/Results.html?Query=id>0&Format=__SubjectAndID__');
+ $m->text_contains( 'Subject-ID', 'New Column title is valid' );
+ $m->text_contains( join( '-', $ticket->Subject, $ticket->id ), 'New Column value is valid' );
+}
+
+$m->get_ok('/Hello.html');
+$m->text_contains( 'Howdy world!', 'New mason content' );
+
+done_testing();
+
+sub update_mason {
+ my $path = shift;
+ my $content = shift;
+ open my $fh, '>', $path or die $!;
+ print $fh $content;
+ close $fh;
+}
commit 3daeae3dd3f1bce12d3c48b2589a6957b40b7cce
Author: sunnavy <sunnavy at bestpractical.com>
Date: Sat Oct 2 03:50:06 2021 +0800
Use mason's remove_object_files instead of implementing it ourselves
This is to simplify our code.
diff --git a/lib/RT/Interface/Web.pm b/lib/RT/Interface/Web.pm
index c1fb39fab2..9bc3e27faf 100644
--- a/lib/RT/Interface/Web.pm
+++ b/lib/RT/Interface/Web.pm
@@ -1967,41 +1967,6 @@ sub ClientIsIE {
return RequestENV('HTTP_USER_AGENT') =~ m{MSIE|Trident/} ? 1 : 0;
}
-=head2 ClearMasonCache
-
-Delete current mason cache.
-
-=cut
-
-sub ClearMasonCache {
- require File::Path;
- require File::Spec;
- my $mason_obj_dir = File::Spec->catdir( $RT::MasonDataDir, 'obj' );
-
- my $error;
-
- # There is a race condition that other processes add new cache items while
- # remove_tree is running, which could prevent it from deleting the whole "obj"
- # directory with errors like "Directory not empty". Let's try for a few times
- # here to get around it.
-
- for ( 1 .. 10 ) {
- last unless -e $mason_obj_dir;
- File::Path::remove_tree( $mason_obj_dir, { safe => 1, error => \$error } );
- }
-
- if ( $error && @$error ) {
-
- # Only one dir is specified, so there will be only one error if any
- my ( $file, $message ) = %{ $error->[0] };
- RT->Logger->error("Failed to clear mason cache: $file => $message");
- return ( 0, HTML::Mason::Commands::loc( "Failed to clear mason cache: [_1] => [_2]", $file, $message ) );
- }
- else {
- return ( 1, HTML::Mason::Commands::loc('Cache cleared') );
- }
-}
-
package HTML::Mason::Commands;
use vars qw/$r $m %session/;
diff --git a/share/html/Admin/Helpers/ClearMasonCache b/share/html/Admin/Helpers/ClearMasonCache
index 837ac4d15e..85c3a61aa9 100644
--- a/share/html/Admin/Helpers/ClearMasonCache
+++ b/share/html/Admin/Helpers/ClearMasonCache
@@ -47,8 +47,8 @@
%# END BPS TAGGED BLOCK }}}
<%init>
-my ( $ret, $msg ) = RT::Interface::Web::ClearMasonCache();
+$m->interp->remove_object_files;
$r->content_type( 'application/json; charset=utf-8' );
-$m->out( JSON( { status => $ret, message => $msg } ) );
+$m->out( JSON( { status => 1, message => loc('Cache cleared') } ) );
$m->abort;
</%init>
commit f2fec5dc3caa4ff905cd07e6fbc0133ed508617f
Author: sunnavy <sunnavy at bestpractical.com>
Date: Thu Sep 30 07:48:20 2021 +0800
Clear callback cache too when mason cache is cleared
Without this, the callbacks could be outdated. Even worse, callbacks
that are marked as "CallbackOnce" wouldn't be called again.
Fixes: I#37248
diff --git a/lib/RT/Interface/Web.pm b/lib/RT/Interface/Web.pm
index bfe7f9e81a..c1fb39fab2 100644
--- a/lib/RT/Interface/Web.pm
+++ b/lib/RT/Interface/Web.pm
@@ -282,6 +282,7 @@ sub HandleRequest {
my $mason_cache_created = MasonCacheCreatedDate();
if ( $HTML::Mason::Commands::m->interp->{rt_mason_cache_created} ne $mason_cache_created ) {
$HTML::Mason::Commands::m->interp->flush_code_cache;
+ $HTML::Mason::Commands::m->clear_callback_cache;
$HTML::Mason::Commands::m->interp->{rt_mason_cache_created} = $mason_cache_created;
}
}
commit fd81b7868c0267dac8eb1d121c0736d3664a409c
Author: sunnavy <sunnavy at bestpractical.com>
Date: Thu Sep 30 05:48:38 2021 +0800
Store mason cache created time in mason interpreter
$m is re-initialized on every request, so we can't use it to store info
across requests. This caused flush_code_cache to be called on every
request previously.
This is also where mason stores time of static_source_touch_file. The
reason we can't directly use the mechanism of static_source_touch_file
is we need a hook to clear RT callback caches.
diff --git a/lib/RT/Interface/Web.pm b/lib/RT/Interface/Web.pm
index ce0931f35a..bfe7f9e81a 100644
--- a/lib/RT/Interface/Web.pm
+++ b/lib/RT/Interface/Web.pm
@@ -266,6 +266,10 @@ sub WebRemoteUserAutocreateInfo {
return {%user_info};
}
+sub MasonCacheCreatedDate {
+ require File::Spec;
+ return ( stat File::Spec->catdir( $RT::MasonDataDir, 'obj' ) )[9] // '';
+}
sub HandleRequest {
my $ARGS = shift;
@@ -275,11 +279,10 @@ sub HandleRequest {
Module::Refresh->refresh;
}
else {
- require File::Spec;
- my $mason_cache_created = ( stat File::Spec->catdir( $RT::MasonDataDir, 'obj' ) )[ 9 ] // '';
- if ( ( $HTML::Mason::Commands::m->{rt_mason_cache_created} // '' ) ne $mason_cache_created ) {
+ my $mason_cache_created = MasonCacheCreatedDate();
+ if ( $HTML::Mason::Commands::m->interp->{rt_mason_cache_created} ne $mason_cache_created ) {
$HTML::Mason::Commands::m->interp->flush_code_cache;
- $HTML::Mason::Commands::m->{rt_mason_cache_created} = $mason_cache_created;
+ $HTML::Mason::Commands::m->interp->{rt_mason_cache_created} = $mason_cache_created;
}
}
diff --git a/lib/RT/Interface/Web/Handler.pm b/lib/RT/Interface/Web/Handler.pm
index dd6fc31801..649be05139 100644
--- a/lib/RT/Interface/Web/Handler.pm
+++ b/lib/RT/Interface/Web/Handler.pm
@@ -120,6 +120,11 @@ sub NewHandler {
$handler->interp->set_escape( h => \&RT::Interface::Web::EscapeHTML );
$handler->interp->set_escape( u => \&RT::Interface::Web::EscapeURI );
$handler->interp->set_escape( j => \&RT::Interface::Web::EscapeJS );
+
+ if ( !RT->Config->Get('DevelMode') ) {
+ $handler->interp->{rt_mason_cache_created} = RT::Interface::Web::MasonCacheCreatedDate;
+ }
+
return($handler);
}
diff --git a/share/html/Admin/Tools/Configuration.html b/share/html/Admin/Tools/Configuration.html
index 37a3a694b2..de5ae21c40 100644
--- a/share/html/Admin/Tools/Configuration.html
+++ b/share/html/Admin/Tools/Configuration.html
@@ -165,9 +165,9 @@ for my $type (qw/Tickets Queues Transactions Groups PrivilegedUsers Unprivileged
<&|/Widgets/TitleBox, title => loc("Mason template search order") &>
-% if ( $m->{rt_mason_cache_created} ) {
+% if ( $m->interp->{rt_mason_cache_created} ) {
% my $mason_obj_date = RT::Date->new( $session{CurrentUser} );
-% $mason_obj_date->Set( Format => 'Unix', Value => $m->{rt_mason_cache_created} );
+% $mason_obj_date->Set( Format => 'Unix', Value => $m->interp->{rt_mason_cache_created} );
<div class="mason-cache">
<div class="mason-cache-info py-1 d-inline-block">
-----------------------------------------------------------------------
hooks/post-receive
--
rt
More information about the rt-commit
mailing list