mirror of
https://github.com/afollestad/nock-nock.git
synced 2025-04-20 03:25:14 +00:00
Retry policy functionality works, resolves #30
This commit is contained in:
parent
31c9e94e15
commit
69d9eb094e
6 changed files with 87 additions and 31 deletions
|
@ -50,7 +50,7 @@ class AddSiteActivity : DarkModeSwitchActivity() {
|
|||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_addsite)
|
||||
setupUi(savedInstanceState)
|
||||
setupUi()
|
||||
|
||||
lifecycle.addObserver(viewModel)
|
||||
|
||||
|
@ -114,18 +114,9 @@ class AddSiteActivity : DarkModeSwitchActivity() {
|
|||
timesData = viewModel.retryPolicyTimes,
|
||||
minutesData = viewModel.retryPolicyMinutes
|
||||
)
|
||||
|
||||
// Done button
|
||||
doneBtn.setOnClickListener {
|
||||
viewModel.commit {
|
||||
setResult(RESULT_OK)
|
||||
finish()
|
||||
overridePendingTransition(R.anim.fade_out, R.anim.fade_out)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupUi(savedInstanceState: Bundle?) {
|
||||
private fun setupUi() {
|
||||
toolbarTitle.setText(R.string.add_site)
|
||||
toolbar.run {
|
||||
setNavigationIcon(R.drawable.ic_action_close)
|
||||
|
@ -139,5 +130,14 @@ class AddSiteActivity : DarkModeSwitchActivity() {
|
|||
)
|
||||
validationOptionsAdapter.setDropDownViewResource(R.layout.list_item_spinner_dropdown)
|
||||
responseValidationMode.adapter = validationOptionsAdapter
|
||||
|
||||
// Done button
|
||||
doneBtn.setOnClickListener {
|
||||
viewModel.commit {
|
||||
setResult(RESULT_OK)
|
||||
finish()
|
||||
overridePendingTransition(R.anim.fade_out, R.anim.fade_out)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -149,18 +149,6 @@ class ViewSiteActivity : DarkModeSwitchActivity() {
|
|||
.toViewText(this, textLastCheckResult)
|
||||
viewModel.onNextCheckText()
|
||||
.toViewText(this, textNextCheck)
|
||||
|
||||
// Disabled button
|
||||
viewModel.onDisableChecksVisibility()
|
||||
.toViewVisibility(this, disableChecksButton)
|
||||
disableChecksButton.setOnClickListener { maybeDisableChecks() }
|
||||
|
||||
// Done button
|
||||
viewModel.onDoneButtonText()
|
||||
.toViewText(this, doneBtn)
|
||||
doneBtn.setOnClickListener {
|
||||
viewModel.commit { finish() }
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupUi() {
|
||||
|
@ -195,6 +183,18 @@ class ViewSiteActivity : DarkModeSwitchActivity() {
|
|||
)
|
||||
validationOptionsAdapter.setDropDownViewResource(R.layout.list_item_spinner_dropdown)
|
||||
responseValidationMode.adapter = validationOptionsAdapter
|
||||
|
||||
// Disabled button
|
||||
viewModel.onDisableChecksVisibility()
|
||||
.toViewVisibility(this, disableChecksButton)
|
||||
disableChecksButton.setOnClickListener { maybeDisableChecks() }
|
||||
|
||||
// Done button
|
||||
viewModel.onDoneButtonText()
|
||||
.toViewText(this, doneBtn)
|
||||
doneBtn.setOnClickListener {
|
||||
viewModel.commit { finish() }
|
||||
}
|
||||
}
|
||||
|
||||
override fun onNewIntent(intent: Intent?) {
|
||||
|
|
|
@ -39,7 +39,11 @@ data class RetryPolicy(
|
|||
* In what amount of time (in minutes) we want
|
||||
* to perform those retries.
|
||||
*/
|
||||
var minutes: Int = 0
|
||||
var minutes: Int = 0,
|
||||
/** The timestamp in milliseconds of the last attempt. */
|
||||
var lastTryTimestamp: Long = 0,
|
||||
/** How many retries we have left before considering the site to have problem. */
|
||||
var triesLeft: Int = -1
|
||||
) : Serializable {
|
||||
|
||||
constructor() : this(0, 0, 0)
|
||||
|
@ -49,6 +53,9 @@ data class RetryPolicy(
|
|||
// 30 seconds = 30 * 1000 or 30,000 milliseconds.
|
||||
// 60,000 / 2 = 30,000.
|
||||
fun interval(): Long {
|
||||
if (count == 0 || minutes == 0) {
|
||||
return -1
|
||||
}
|
||||
val timesPerMinute = count.toFloat() / minutes.toFloat()
|
||||
return MINUTE / timesPerMinute.toInt()
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ import android.app.job.JobParameters
|
|||
import android.app.job.JobService
|
||||
import android.content.Intent
|
||||
import com.afollestad.nocknock.data.AppDatabase
|
||||
import com.afollestad.nocknock.data.RetryPolicy
|
||||
import com.afollestad.nocknock.data.getSite
|
||||
import com.afollestad.nocknock.data.model.Site
|
||||
import com.afollestad.nocknock.data.model.Status
|
||||
|
@ -139,6 +140,33 @@ class ValidationJob : JobService() {
|
|||
if (jobResult.lastResult!!.status == OK) {
|
||||
notificationManager.cancelStatusNotification(jobResult)
|
||||
} else {
|
||||
val retryPolicy = site.retryPolicy
|
||||
if (retryPolicy != null) {
|
||||
log("Check for site ${site.id} was unsuccessful. BUT we have a retryPolicy.")
|
||||
|
||||
if (retryPolicy.triesLeft == -1 || retryPolicy.triesLeft > 0) {
|
||||
if (retryPolicy.triesLeft == -1) {
|
||||
retryPolicy.triesLeft = retryPolicy.count
|
||||
} else {
|
||||
retryPolicy.triesLeft -= 1
|
||||
}
|
||||
updateTriesLeft(retryPolicy, retryPolicy.triesLeft)
|
||||
|
||||
val interval = retryPolicy.interval()
|
||||
validationManager.scheduleCheck(
|
||||
site = jobResult,
|
||||
fromFinishingJob = true,
|
||||
overrideDelay = interval
|
||||
)
|
||||
log("Scheduling retry in $interval milliseconds.")
|
||||
|
||||
return@launch
|
||||
} else {
|
||||
updateTriesLeft(retryPolicy, -1)
|
||||
log("No tries left, continuing to error notification.")
|
||||
}
|
||||
}
|
||||
|
||||
notificationManager.postStatusNotification(jobResult)
|
||||
}
|
||||
|
||||
|
@ -170,6 +198,13 @@ class ValidationJob : JobService() {
|
|||
if (status == OK) null
|
||||
else site.lastResult?.reason ?: "Unknown"
|
||||
|
||||
if (site.retryPolicy != null && status == OK) {
|
||||
site.retryPolicy = site.retryPolicy!!.copy(
|
||||
triesLeft = -1,
|
||||
lastTryTimestamp = 0
|
||||
)
|
||||
}
|
||||
|
||||
val updatedModel = site.withStatus(
|
||||
status = status,
|
||||
timestamp = lastCheckTime,
|
||||
|
@ -184,4 +219,16 @@ class ValidationJob : JobService() {
|
|||
}
|
||||
return updatedModel
|
||||
}
|
||||
|
||||
private suspend fun updateTriesLeft(
|
||||
retryPolicy: RetryPolicy,
|
||||
triesLeft: Int
|
||||
) {
|
||||
retryPolicy.triesLeft = triesLeft
|
||||
withContext(IO) {
|
||||
database.retryPolicyDao()
|
||||
.update(retryPolicy)
|
||||
}
|
||||
log("Tries left for site ${retryPolicy.siteId}: $triesLeft")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,7 +51,8 @@ interface ValidationManager {
|
|||
site: Site,
|
||||
rightNow: Boolean = false,
|
||||
cancelPrevious: Boolean = rightNow,
|
||||
fromFinishingJob: Boolean = false
|
||||
fromFinishingJob: Boolean = false,
|
||||
overrideDelay: Long = -1
|
||||
)
|
||||
|
||||
fun cancelCheck(site: Site)
|
||||
|
@ -96,7 +97,8 @@ class RealValidationManager(
|
|||
site: Site,
|
||||
rightNow: Boolean,
|
||||
cancelPrevious: Boolean,
|
||||
fromFinishingJob: Boolean
|
||||
fromFinishingJob: Boolean,
|
||||
overrideDelay: Long
|
||||
) {
|
||||
check(site.id != 0L) { "Cannot schedule checks for jobs with no ID." }
|
||||
val siteSettings = site.settings
|
||||
|
@ -118,10 +120,10 @@ class RealValidationManager(
|
|||
val jobInfo = jobInfoProvider.createCheckJob(
|
||||
id = site.id.toInt(),
|
||||
onlyUnmeteredNetwork = false,
|
||||
delayMs = if (rightNow) {
|
||||
1
|
||||
} else {
|
||||
siteSettings.validationIntervalMs
|
||||
delayMs = when {
|
||||
rightNow -> 1
|
||||
overrideDelay > -1 -> overrideDelay
|
||||
else -> siteSettings.validationIntervalMs
|
||||
},
|
||||
extras = extras,
|
||||
target = ValidationJob::class.java
|
||||
|
|
|
@ -10,6 +10,6 @@
|
|||
<string name="retry_policy">Retry Policy</string>
|
||||
<string name="retry_policy_retry">Retry</string>
|
||||
<string name="retry_policy_times_in">times in</string>
|
||||
<string name="retry_policy_minutes">Minutes</string>
|
||||
<string name="retry_policy_minutes">Minute(s)</string>
|
||||
|
||||
</resources>
|
||||
|
|
Loading…
Add table
Reference in a new issue