Skip to content

Commit cde4f66

Browse files
authored
Add method to fetch the current lag from the Wikibase instance (#470)
* Add method to fetch the current lag from the server. Closes #510. * Add missing test resource
1 parent 6cb761d commit cde4f66

File tree

6 files changed

+105
-4
lines changed

6 files changed

+105
-4
lines changed

wdtk-wikibaseapi/src/main/java/org/wikidata/wdtk/wikibaseapi/ApiConnection.java

+12-3
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727
import okhttp3.*;
2828
import org.slf4j.Logger;
2929
import org.slf4j.LoggerFactory;
30+
import org.wikidata.wdtk.util.WebResourceFetcherImpl;
31+
import org.wikidata.wdtk.wikibaseapi.apierrors.MaxlagErrorException;
3032
import org.wikidata.wdtk.wikibaseapi.apierrors.AssertUserFailedException;
3133
import org.wikidata.wdtk.wikibaseapi.apierrors.MediaWikiApiErrorException;
3234
import org.wikidata.wdtk.wikibaseapi.apierrors.MediaWikiApiErrorHandler;
@@ -414,9 +416,16 @@ private void buildClient() {
414416
protected void checkErrors(JsonNode root) throws MediaWikiApiErrorException {
415417
if (root.has("error")) {
416418
JsonNode errorNode = root.path("error");
417-
MediaWikiApiErrorHandler.throwMediaWikiApiErrorException(errorNode
418-
.path("code").asText("UNKNOWN"), errorNode.path("info")
419-
.asText("No details provided"));
419+
String code = errorNode.path("code").asText("UNKNOWN");
420+
String info = errorNode.path("info").asText("No details provided");
421+
// Special case for the maxlag error since we also want to return
422+
// the lag value in the exception thrown
423+
if (errorNode.has("lag") && MediaWikiApiErrorHandler.ERROR_MAXLAG.equals(code)) {
424+
double lag = errorNode.path("lag").asDouble();
425+
throw new MaxlagErrorException(info, lag);
426+
} else {
427+
MediaWikiApiErrorHandler.throwMediaWikiApiErrorException(code, info);
428+
}
420429
}
421430
}
422431

wdtk-wikibaseapi/src/main/java/org/wikidata/wdtk/wikibaseapi/WbEditingAction.java

+21
Original file line numberDiff line numberDiff line change
@@ -894,4 +894,25 @@ public void setMaxLagBackOffFactor(double value) {
894894
maxLagBackOffFactor = value;
895895
}
896896

897+
/**
898+
* Retrieves the current lag from the target site, by making an API call.
899+
*
900+
* @throws MediaWikiApiErrorException
901+
* when an unexpected MediaWiki API error happened (not the spurious
902+
* one normally returned by MediaWiki when retrieving lag).
903+
* @throws IOException
904+
* when communication with the server failed.
905+
*
906+
*/
907+
public double getCurrentLag() throws IOException, MediaWikiApiErrorException {
908+
Map<String,String> parameters = new HashMap<>();
909+
parameters.put("action", "query");
910+
parameters.put("maxlag", "-1");
911+
try {
912+
this.connection.sendJsonRequest("POST", parameters);
913+
} catch (MaxlagErrorException e) {
914+
return e.getLag();
915+
}
916+
throw new IllegalStateException("MediaWiki did not return any maxlag value");
917+
}
897918
}

wdtk-wikibaseapi/src/main/java/org/wikidata/wdtk/wikibaseapi/apierrors/MaxlagErrorException.java

+28-1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@
3232
public class MaxlagErrorException extends MediaWikiApiErrorException {
3333

3434
private static final long serialVersionUID = -4013361654647685959L;
35+
36+
protected double lag = 0;
3537

3638
/**
3739
* Creates a new exception.
@@ -43,5 +45,30 @@ public class MaxlagErrorException extends MediaWikiApiErrorException {
4345
public MaxlagErrorException(String errorMessage) {
4446
super(MediaWikiApiErrorHandler.ERROR_MAXLAG, errorMessage);
4547
}
46-
48+
49+
/**
50+
* Creates an exception which also stores the lag announced by the server.
51+
*
52+
* @param errorMessage
53+
* the error message reported by MediaWiki, or any other
54+
* meaningful message for the user
55+
* @param lag
56+
* the value of the reported lag, in seconds
57+
*/
58+
public MaxlagErrorException(String errorMessage, double lag) {
59+
super(MediaWikiApiErrorHandler.ERROR_MAXLAG, errorMessage);
60+
this.lag = lag;
61+
}
62+
63+
/**
64+
* Retrieves the amount of lag announced by the server when this
65+
* error was emitted. May return 0 if the lag was not extracted from
66+
* the server response.
67+
*
68+
* @return
69+
* the lag on the target server
70+
*/
71+
public double getLag() {
72+
return lag;
73+
}
4774
}

wdtk-wikibaseapi/src/test/java/org/wikidata/wdtk/wikibaseapi/BasicApiConnectionTest.java

+13
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
import org.junit.*;
3737
import org.wikidata.wdtk.testing.MockStringContentFactory;
3838
import org.wikidata.wdtk.wikibaseapi.apierrors.AssertUserFailedException;
39+
import org.wikidata.wdtk.wikibaseapi.apierrors.MaxlagErrorException;
3940
import org.wikidata.wdtk.wikibaseapi.apierrors.MediaWikiApiErrorException;
4041

4142
import com.fasterxml.jackson.databind.JsonNode;
@@ -232,6 +233,18 @@ public void testErrors() throws IOException,
232233
root = mapper.readTree(path.openStream());
233234
connection.checkErrors(root);
234235
}
236+
237+
@Test
238+
public void testMaxlagError() throws IOException, MediaWikiApiErrorException {
239+
JsonNode root;
240+
URL path = this.getClass().getResource("/error-maxlag-full.json");
241+
root = mapper.readTree(path.openStream());
242+
try {
243+
connection.checkErrors(root);
244+
} catch(MaxlagErrorException e) {
245+
assertEquals(3.45, e.getLag(), 0.001);
246+
}
247+
}
235248

236249
@Test
237250
public void testClearCookies() throws LoginFailedException, IOException, MediaWikiApiErrorException {

wdtk-wikibaseapi/src/test/java/org/wikidata/wdtk/wikibaseapi/WbEditingActionTest.java

+19
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package org.wikidata.wdtk.wikibaseapi;
22

3+
import static org.junit.Assert.assertEquals;
4+
35
/*
46
* #%L
57
* Wikidata Toolkit Wikibase API
@@ -191,5 +193,22 @@ public void testNoTask() throws IOException, MediaWikiApiErrorException {
191193
new MockBasicApiConnection(), Datamodel.SITE_WIKIDATA);
192194
weea.wbEditEntity(null, null, null, null, "{}", false, false, 0, null, null);
193195
}
196+
197+
@Test
198+
public void testGetLag() throws IOException, MediaWikiApiErrorException {
199+
MockBasicApiConnection con = new MockBasicApiConnection();
200+
Map<String, String> params = new HashMap<>();
201+
params.put("action", "query");
202+
params.put("maxlag", "-1");
203+
params.put("format", "json");
204+
con.setWebResourceFromPath(params, this.getClass(),
205+
"/error-maxlag-full.json",
206+
CompressionType.NONE);
207+
208+
WbEditingAction weea = new WbEditingAction(
209+
con, Datamodel.SITE_WIKIDATA);
210+
double lag = weea.getCurrentLag();
211+
assertEquals(3.45, lag, 0.001);
212+
}
194213

195214
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"error": {
3+
"code": "maxlag",
4+
"info": "Waiting for all: 3.45 seconds lagged.",
5+
"host": "all",
6+
"lag": 3.45,
7+
"type": "wikibase-queryservice",
8+
"queryserviceLag": 626,
9+
"*": "See https://www.wikidata.org/w/api.php for API usage. Subscribe to the mediawiki-api-announce mailing list at &lt;https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce&gt; for notice of API deprecations and breaking changes."
10+
},
11+
"servedby": "mw1280"
12+
}

0 commit comments

Comments
 (0)