From f39b718cea29bee4af4a9e95d3b8cc7bb57e7135 Mon Sep 17 00:00:00 2001 From: intracer Date: Thu, 26 Oct 2017 04:20:12 +0300 Subject: [PATCH] implement edit backoff #47 --- build.sbt | 6 ++++-- .../scalawiki/query/PageQueryImplDsl.scala | 17 +++++++++++----- .../test/scala/org/scalawiki/EditSpec.scala | 20 +++++++++++++++++-- 3 files changed, 34 insertions(+), 9 deletions(-) diff --git a/build.sbt b/build.sbt index 4ea38a55..b24fa6b6 100644 --- a/build.sbt +++ b/build.sbt @@ -22,7 +22,8 @@ lazy val commonSettings = Seq( "Typesafe Repo" at "http://repo.typesafe.com/typesafe/releases/", "Scalaz Bintray Repo" at "http://dl.bintray.com/scalaz/releases", Resolver.jcenterRepo, - Resolver.bintrayRepo("rick-beton", "maven") + Resolver.bintrayRepo("rick-beton", "maven"), + Resolver.bintrayRepo("softprops", "maven") ), scalacOptions ++= Seq("-Ybackend:GenBCode"), @@ -61,7 +62,8 @@ lazy val `scalawiki-core` = "ch.qos.logback" % "logback-classic" % "1.1.3", "org.sweble.wikitext" % "swc-engine" % "2.0.0" exclude("org.jsoup", "jsoup"), "commons-codec" % "commons-codec" % "1.10", - "org.jsoup" % "jsoup" % "1.8.3" + "org.jsoup" % "jsoup" % "1.8.3", + "me.lessis" %% "retry" % "0.2.0" ) }).dependsOn(`http-extensions`) diff --git a/scalawiki-core/src/main/scala/org/scalawiki/query/PageQueryImplDsl.scala b/scalawiki-core/src/main/scala/org/scalawiki/query/PageQueryImplDsl.scala index bd91445d..8a2f938b 100644 --- a/scalawiki-core/src/main/scala/org/scalawiki/query/PageQueryImplDsl.scala +++ b/scalawiki-core/src/main/scala/org/scalawiki/query/PageQueryImplDsl.scala @@ -3,14 +3,15 @@ package org.scalawiki.query import java.nio.file.{Files, Paths} import org.scalawiki.MwBot -import org.scalawiki.dto.{Namespace, Page} import org.scalawiki.dto.cmd._ import org.scalawiki.dto.cmd.edit._ import org.scalawiki.dto.cmd.query._ import org.scalawiki.dto.cmd.query.list._ import org.scalawiki.dto.cmd.query.prop._ import org.scalawiki.dto.cmd.query.prop.rvprop.RvProp +import org.scalawiki.dto.{Namespace, Page} import org.scalawiki.json.MwReads._ +import retry.Success import scala.concurrent.Future @@ -124,10 +125,16 @@ class PageQueryImplDsl(query: Either[Set[Long], Set[String]], bot.log.info(s"${bot.host} edit page: $page, summary: $summary") - if (multi) - bot.postMultiPart(editResponseReads, params) - else - bot.post(editResponseReads, params) + def performEdit(): Future[String] = { + if (multi) + bot.postMultiPart(editResponseReads, params) + else + bot.post(editResponseReads, params) + } + + import scala.concurrent.ExecutionContext.Implicits.global + implicit def stringSuccess: Success[String] = Success(_ == "Success") + retry.Backoff()(odelay.Timer.default)(() => performEdit()) } override def upload(filename: String, diff --git a/scalawiki-core/src/test/scala/org/scalawiki/EditSpec.scala b/scalawiki-core/src/test/scala/org/scalawiki/EditSpec.scala index f8fd6c20..ad6cf934 100644 --- a/scalawiki-core/src/test/scala/org/scalawiki/EditSpec.scala +++ b/scalawiki-core/src/test/scala/org/scalawiki/EditSpec.scala @@ -8,6 +8,7 @@ class EditSpec extends Specification with MockBotSpec { val tokenResponse = """{"batchcomplete":"","query":{"tokens":{"csrftoken":"cafebabe+\\"}}}""" val successResponse = """{"edit":{"result":"Success","pageid":1776370,"title":"pageTitle","contentmodel":"wikitext"}}""" + val errorResponse = """{"edit":{"result":"Error","pageid":1776370,"title":"pageTitle","contentmodel":"wikitext"}}""" "bot" should { "edit successfully" in { @@ -15,8 +16,23 @@ class EditSpec extends Specification with MockBotSpec { val bot: MwBot = getBot( HttpStub(Map("action" -> "query", "meta" -> "siteinfo", "format" -> "json"), siteInfo), HttpStub(Map("action" -> "query", "meta" -> "tokens", "format" -> "json"), tokenResponse), - HttpStub(Map("assert" -> "bot", "format" -> "json", "text" -> "pageText", "token"-> "cafebabe+\\", "bot" -> "x", - "title" -> "pageTitle", "action" -> "edit", "summary" -> "editsummary"), successResponse) + HttpStub(Map("assert" -> "bot", "format" -> "json", "text" -> "pageText", "token" -> "cafebabe+\\", "bot" -> "x", + "title" -> "pageTitle", "action" -> "edit", "summary" -> "editsummary"), successResponse) + ) + + val result = bot.page("pageTitle").edit("pageText", Some("editsummary")).await + result === "Success" + } + + "edit retry error once" in { + val siteInfo = TestUtils.resourceAsString("/org/scalawiki/ukwiki_siteinfo.json") + val bot: MwBot = getBot( + HttpStub(Map("action" -> "query", "meta" -> "siteinfo", "format" -> "json"), siteInfo), + HttpStub(Map("action" -> "query", "meta" -> "tokens", "format" -> "json"), tokenResponse), + HttpStub(Map("assert" -> "bot", "format" -> "json", "text" -> "pageText", "token"-> "cafebabe+\\", "bot" -> "x", + "title" -> "pageTitle", "action" -> "edit", "summary" -> "editsummary"), errorResponse), + HttpStub(Map("assert" -> "bot", "format" -> "json", "text" -> "pageText", "token"-> "cafebabe+\\", "bot" -> "x", + "title" -> "pageTitle", "action" -> "edit", "summary" -> "editsummary"), successResponse) ) val result = bot.page("pageTitle").edit("pageText", Some("editsummary")).await