Lucas Werkmeister (WMDE) has uploaded a new change for review. (
https://gerrit.wikimedia.org/r/351876 )
Change subject: Allow callback functions for creating jobs
......................................................................
Allow callback functions for creating jobs
$wgJobClasses can now specify a factory function for creating a job,
instead of a class to be instantiated directly. This makes it possible
to inject services in a job constructor, and register a factory function
that calls the constructor with default services.
This follows Ieb85493a7765 and Ieb85493a7765, which introduced factory
functions for API modules and special pages.
Change-Id: I0461e59da2a8fa6681e3b1fcdfc38bfed7f3ac32
---
M RELEASE-NOTES-1.30
M includes/DefaultSettings.php
M includes/jobqueue/Job.php
M tests/phpunit/includes/jobqueue/JobTest.php
4 files changed, 60 insertions(+), 6 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/mediawiki/core
refs/changes/76/351876/1
diff --git a/RELEASE-NOTES-1.30 b/RELEASE-NOTES-1.30
index cdf8ba4..5370c6d 100644
--- a/RELEASE-NOTES-1.30
+++ b/RELEASE-NOTES-1.30
@@ -12,6 +12,11 @@
case.
* $wgShellLocale now affects LC_ALL rather than only LC_CTYPE. See
documentation of $wgShellLocale for details.
+* $wgJobClasses may now specify callback functions
+ as an alternative to plain class names.
+ This is intended for extensions that want control
+ over the instantiation of their jobs,
+ to allow for proper dependency injection.
=== New features in 1.30 ===
* …
diff --git a/includes/DefaultSettings.php b/includes/DefaultSettings.php
index 7c18fcc..8563fa1 100644
--- a/includes/DefaultSettings.php
+++ b/includes/DefaultSettings.php
@@ -7332,8 +7332,10 @@
];
/**
- * Maps jobs to their handling classes; extensions
- * can add to this to provide custom jobs
+ * Maps jobs to their handlers; extensions
+ * can add to this to provide custom jobs.
+ * A job handler should either be a class name to be instantiated,
+ * or a callback to use for creating the job object.
*/
$wgJobClasses = [
'refreshLinks' => 'RefreshLinksJob',
diff --git a/includes/jobqueue/Job.php b/includes/jobqueue/Job.php
index f814cee..79128be 100644
--- a/includes/jobqueue/Job.php
+++ b/includes/jobqueue/Job.php
@@ -69,12 +69,22 @@
global $wgJobClasses;
if ( isset( $wgJobClasses[$command] ) ) {
- $class = $wgJobClasses[$command];
+ $handler = $wgJobClasses[$command];
- $job = new $class( $title, $params );
- $job->command = $command;
+ if ( is_callable( $handler ) ) {
+ $job = call_user_func( $handler, $title,
$params );
+ } else if ( is_string( $handler ) ) {
+ $job = new $handler( $title, $params );
+ } else {
+ $job = null;
+ }
- return $job;
+ if ( $job instanceof Job ) {
+ $job->command = $command;
+ return $job;
+ } else {
+ throw new InvalidArgumentException( "Cannot
instantiate job '$command': bad spec!" );
+ }
}
throw new InvalidArgumentException( "Invalid job command
'{$command}'" );
diff --git a/tests/phpunit/includes/jobqueue/JobTest.php
b/tests/phpunit/includes/jobqueue/JobTest.php
index 1deb7aa..5b59fa9 100644
--- a/tests/phpunit/includes/jobqueue/JobTest.php
+++ b/tests/phpunit/includes/jobqueue/JobTest.php
@@ -91,4 +91,41 @@
return $mock;
}
+ /**
+ * @dataProvider provideTestJobFactory
+ *
+ * @param mixed $handler
+ *
+ * @covers Job::factory
+ */
+ public function testJobFactory( $handler ) {
+ $this->mergeMWGlobalArrayValue( 'wgJobClasses', [ 'testdummy'
=> $handler ] );
+
+ $job = Job::factory( 'testdummy', Title::newMainPage(), [] );
+ $this->assertInstanceOf( NullJob::class, $job );
+
+ $job2 = Job::factory( 'testdummy', Title::newMainPage(), [] );
+ $this->assertInstanceOf( NullJob::class, $job2 );
+ $this->assertNotSame( $job, $job2, 'should not reuse instance'
);
+ }
+
+ public function provideTestJobFactory() {
+ return [
+ 'class name' => [ 'NullJob' ],
+ 'closure' => [ function( Title $title, array $params ) {
+ return new NullJob( $title, $params );
+ } ],
+ 'function' => [ [ $this, 'newNullJob' ] ],
+ 'static function' => [ self::class . '::staticNullJob' ]
+ ];
+ }
+
+ public function newNullJob( Title $title, array $params ) {
+ return new NullJob( $title, $params );
+ }
+
+ public static function staticNullJob( Title $title, array $params ) {
+ return new NullJob( $title, $params );
+ }
+
}
--
To view, visit https://gerrit.wikimedia.org/r/351876
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I0461e59da2a8fa6681e3b1fcdfc38bfed7f3ac32
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/core
Gerrit-Branch: master
Gerrit-Owner: Lucas Werkmeister (WMDE) <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits