Skip to content

Commit 5ecaf5a

Browse files
Fixjobqueue (#7)
* fixed processing via JobQueue which is recommended and default now to avoid issues with deferredUpdates on pages
1 parent e8a483d commit 5ecaf5a

File tree

5 files changed

+123
-77
lines changed

5 files changed

+123
-77
lines changed

Diff for: extension.json

+6-5
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "SemanticDependencyUpdater",
3-
"version": "2.1.0",
3+
"version": "3.0.0-beta",
44
"author": [
55
"Simon Heimler (gesinn.it GmbH & Co. KG)",
66
"Alexander Gesinn (gesinn.it GmbH & Co. KG)",
@@ -12,9 +12,9 @@
1212
"license-name": "MIT",
1313
"type": "semantic",
1414
"requires": {
15-
"MediaWiki": ">= 1.31",
15+
"MediaWiki": ">= 1.35",
1616
"extensions": {
17-
"SemanticMediaWiki": ">= 3.1.0"
17+
"SemanticMediaWiki": ">= 4.0.0"
1818
}
1919
},
2020
"AutoloadNamespaces": {
@@ -26,12 +26,13 @@
2626
]
2727
},
2828
"JobClasses": {
29-
"DummyEditJob": "SDU\\DummyEditJob"
29+
"RebuildDataJob": "SDU\\RebuildDataJob",
30+
"PageUpdaterJob": "SDU\\PageUpdaterJob"
3031
},
3132
"callback": "SDU\\Hooks::setup",
3233
"config": {
3334
"SDUProperty": "Semantic Dependency",
34-
"SDUUseJobQueue": false
35+
"SDUUseJobQueue": true
3536
},
3637
"manifest_version": 1
3738
}

Diff for: src/DummyEditJob.php

-39
This file was deleted.

Diff for: src/Hooks.php

+45-33
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,14 @@
22

33
namespace SDU;
44

5-
use ContentHandler;
6-
use MediaWiki\Revision\RevisionRecord;
5+
use DeferredUpdates;
6+
use JobQueueGroup;
7+
use SMW\Options;
8+
use SMW\Services\ServicesFactory as ApplicationFactory;
79
use SMWDIBlob;
810
use SMWQueryProcessor;
911
use SMWSemanticData;
1012
use SMWStore;
11-
use Title;
1213
use WikiPage;
1314

1415
class Hooks {
@@ -23,8 +24,10 @@ public static function setup() {
2324
}
2425
}
2526

26-
public static function onAfterDataUpdateComplete( SMWStore $store, SMWSemanticData $newData,
27-
$compositePropertyTableDiffIterator ) {
27+
public static function onAfterDataUpdateComplete(
28+
SMWStore $store, SMWSemanticData $newData,
29+
$compositePropertyTableDiffIterator
30+
) {
2831
global $wgSDUProperty;
2932
global $wgSDUTraversed;
3033

@@ -83,14 +86,16 @@ public static function onAfterDataUpdateComplete( SMWStore $store, SMWSemanticDa
8386
// SMWDataItem[] $dataItem
8487
$dataItem = $newData->getPropertyValues( $properties[$wgSDUProperty] );
8588

89+
$wikiPageValues = [];
8690
if ( $dataItem != null ) {
8791
foreach ( $dataItem as $valueItem ) {
8892
if ( $valueItem instanceof SMWDIBlob ) {
89-
self::updatePagesMatchingQuery( $valueItem->getSerialization() );
93+
$wikiPageValues = array_merge( $wikiPageValues, self::updatePagesMatchingQuery( $valueItem->getSerialization() ) );
9094
}
9195
}
9296
}
9397

98+
self::rebuildData( $wikiPageValues, $store );
9499
return true;
95100
}
96101

@@ -123,42 +128,49 @@ private static function updatePagesMatchingQuery( $queryString ) {
123128
$result = $store->getQueryResult( $query ); // SMWQueryResult
124129
$wikiPageValues = $result->getResults(); // array of SMWWikiPageValues
125130

126-
// TODO: This can be optimized by collecting a list of all pages first, make them unique
127-
// and do the dummy edit afterwards
128-
// TODO: A threshold when to switch to Queue Jobs might be smarter
129-
foreach ( $wikiPageValues as $page ) {
130-
self::dummyEdit( $page->getTitle() );
131-
}
131+
return $wikiPageValues;
132132
}
133133

134134
/**
135-
* Save a null revision in the page's history to propagate the update
135+
* Rebuilds data of the given wikipages to regenerate semantic attrubutes and re-run queries
136136
*
137-
* @param Title $title
137+
* @param SMWWikiPageValues[] $wikiPageValues
138+
* @param SMWStore $store
138139
*/
139-
public static function dummyEdit( $title ) {
140+
public static function rebuildData( $wikiPageValues, $store ) {
140141
global $wgSDUUseJobQueue;
141142

143+
$pageArray = [];
144+
foreach ( $wikiPageValues as $wikiPageValue ) {
145+
$page = WikiPage::newFromID( $wikiPageValue->getTitle()->getArticleId() );
146+
if ( $page ) {
147+
$pageArray[] = $page->getTitle()->prefixedText;
148+
}
149+
}
150+
$pageString = implode( $pageArray, "|" );
151+
152+
// TODO: A threshold when to switch to Queue Jobs might be smarter
142153
if ( $wgSDUUseJobQueue ) {
143-
wfDebugLog( 'SemanticDependencyUpdater', "[SDU] --------> [Edit Job] $title" );
144-
$job = new DummyEditJob( $title );
145-
$job->insert();
146-
} else {
147-
wfDebugLog( 'SemanticDependencyUpdater', "[SDU] --------> [Edit] $title" );
148-
$page = WikiPage::newFromID( $title->getArticleId() );
149-
if ( $page ) { // prevent NPE when page not found
150-
$content = $page->getContent( RevisionRecord::RAW );
151-
152-
if ( $content ) {
153-
$text = ContentHandler::getContentText( $content );
154-
$page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle() ),
155-
"[SemanticDependencyUpdater] Null edit." ); // since this is a null edit, the edit summary will be ignored.
156-
$page->doPurge(); // required since SMW 2.5.1
157-
158-
# Consider calling doSecondaryDataUpdates() for MW 1.32+
159-
# https://doc.wikimedia.org/mediawiki-core/master/php/classWikiPage.html#ac761e927ec2e7d95c9bb48aac60ff7c8
160-
}
154+
$jobs[] = new RebuildDataJob( [
155+
'pageString' => $pageString,
156+
] );
157+
foreach ( $wikiPageValues as $page ) {
158+
$jobs[] = new PageUpdaterJob( [
159+
'page' => $page
160+
] );
161161
}
162+
JobQueueGroup::singleton()->lazyPush( $jobs );
163+
} else {
164+
DeferredUpdates::addCallableUpdate( static function () use ( $store, $pageString ) {
165+
wfDebugLog( 'SemanticDependencyUpdater', "[SDU] --------> [rebuildData] $pageString" );
166+
$maintenanceFactory = ApplicationFactory::getInstance()->newMaintenanceFactory();
167+
168+
$dataRebuilder = $maintenanceFactory->newDataRebuilder( $store );
169+
$dataRebuilder->setOptions(
170+
new Options( [ 'page' => $pageString ] )
171+
);
172+
$dataRebuilder->rebuild();
173+
} );
162174
}
163175
}
164176

Diff for: src/PageUpdaterJob.php

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?php
2+
3+
namespace SDU;
4+
5+
use CommentStoreComment;
6+
use GenericParameterJob;
7+
use Job;
8+
use MediaWiki\Revision\RevisionRecord;
9+
use MediaWiki\Revision\SlotRecord;
10+
use RequestContext;
11+
use WikiPage;
12+
13+
class PageUpdaterJob extends Job implements GenericParameterJob {
14+
15+
public function __construct( array $params ) {
16+
parent::__construct( 'PageUpdaterJob', $params );
17+
}
18+
19+
/**
20+
* Run the job
21+
* @return bool success
22+
*/
23+
public function run() {
24+
$pageParam = $this->params['page'];
25+
$page = WikiPage::newFromID( $this->params['page']->getTitle()->getArticleId() );
26+
$content = $page->getContent( RevisionRecord::RAW );
27+
$title = $page->getTitle();
28+
29+
wfDebugLog( 'SemanticDependencyUpdater', "[SDU] --------> [rebuildData job] $title" );
30+
31+
$performer = RequestContext::getMain()->getUser();
32+
$updater = $page->newPageUpdater( $performer );
33+
34+
$updater->setContent( SlotRecord::MAIN, $content );
35+
$updater->saveRevision( CommentStoreComment::newUnsavedComment( __CLASS__ . ' [SemanticDependencyUpdater] Null edit. ' . $title ) );
36+
37+
return true;
38+
}
39+
}

Diff for: src/RebuildDataJob.php

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php
2+
3+
namespace SDU;
4+
5+
use GenericParameterJob;
6+
use Job;
7+
use SMW\Options;
8+
use SMW\Services\ServicesFactory as ApplicationFactory;
9+
10+
class RebuildDataJob extends Job implements GenericParameterJob {
11+
12+
public function __construct( array $params ) {
13+
parent::__construct( 'RebuildDataJob', $params );
14+
}
15+
16+
/**
17+
* Run the job
18+
* @return bool success
19+
*/
20+
public function run() {
21+
$store = smwfGetStore();
22+
$pageString = $this->params['pageString'];
23+
wfDebugLog( 'SemanticDependencyUpdater', "[SDU] --------> [rebuildData job] $pageString" );
24+
$maintenanceFactory = ApplicationFactory::getInstance()->newMaintenanceFactory();
25+
26+
$dataRebuilder = $maintenanceFactory->newDataRebuilder( $store );
27+
$dataRebuilder->setOptions(
28+
new Options( [ 'page' => $pageString ] )
29+
);
30+
$dataRebuilder->rebuild();
31+
return true;
32+
}
33+
}

0 commit comments

Comments
 (0)