Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wire up rest of update backfill form #388

Merged
merged 2 commits into from
May 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package app.cash.backfila.dashboard

import app.cash.backfila.service.BackfillRunListener
import app.cash.backfila.service.SlackHelper
import app.cash.backfila.service.persistence.BackfilaDb
import app.cash.backfila.service.persistence.BackfillState
import app.cash.backfila.service.persistence.BackfillState.PAUSED
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ class UpdateBackfillAction @Inject constructor(

request.backoff_schedule?.let { schedule ->
if (request.backoff_schedule.isEmpty()) {
changesLog += "backoff_schedule ${run.backoff_schedule}->"
changesLog += "backoff_schedule ${run.backoff_schedule}->null"
run.backoff_schedule = null
return@let
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package app.cash.backfila.service

import app.cash.backfila.service.persistence.DbBackfillRun
import misk.hibernate.Id
import misk.hibernate.load

interface BackfillRunListener {
fun runStarted(id: Id<DbBackfillRun>, user: String)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import app.cash.backfila.dashboard.StartBackfillAction
import app.cash.backfila.dashboard.StartBackfillRequest
import app.cash.backfila.dashboard.StopBackfillAction
import app.cash.backfila.dashboard.StopBackfillRequest
import app.cash.backfila.dashboard.UpdateBackfillAction
import app.cash.backfila.dashboard.UpdateBackfillRequest
import app.cash.backfila.service.persistence.BackfillState
import javax.inject.Inject
import javax.inject.Singleton
Expand All @@ -23,8 +25,7 @@ import okhttp3.Headers
class BackfillShowButtonHandlerAction @Inject constructor(
private val startBackfillAction: StartBackfillAction,
private val stopBackfillAction: StopBackfillAction,
// TODO add support for updating other fields, not just state
// private val updateBackfillAction: UpdateBackfillAction,
private val updateBackfillAction: UpdateBackfillAction,
) : WebAction {
@Get(PATH)
@ResponseContentType(MediaTypes.TEXT_HTML)
Expand All @@ -43,6 +44,33 @@ class BackfillShowButtonHandlerAction @Inject constructor(
startBackfillAction.start(id.toLong(), StartBackfillRequest())
}
}
"num_threads" -> {
val numThreads = field_value?.toIntOrNull()
if (numThreads != null) {
updateBackfillAction.update(id.toLong(), UpdateBackfillRequest(num_threads = numThreads))
}
}
"scan_size" -> {
val scanSize = field_value?.toLongOrNull()
if (scanSize != null) {
updateBackfillAction.update(id.toLong(), UpdateBackfillRequest(scan_size = scanSize))
}
}
"batch_size" -> {
val batchSize = field_value?.toLongOrNull()
if (batchSize != null) {
updateBackfillAction.update(id.toLong(), UpdateBackfillRequest(batch_size = batchSize))
}
}
"extra_sleep_ms" -> {
val extraSleepMs = field_value?.toLongOrNull()
if (extraSleepMs != null) {
updateBackfillAction.update(id.toLong(), UpdateBackfillRequest(extra_sleep_ms = extraSleepMs))
}
}
"backoff_schedule" -> {
updateBackfillAction.update(id.toLong(), UpdateBackfillRequest(backoff_schedule = field_value))
}

// TODO add support for updating other fields, not just state
}
Expand Down
129 changes: 102 additions & 27 deletions service/src/main/kotlin/app/cash/backfila/ui/pages/BackfillShowAction.kt
Original file line number Diff line number Diff line change
Expand Up @@ -86,37 +86,102 @@ class BackfillShowAction @Inject constructor(
dl("divide-y divide-gray-100") {
backfill.toRows(id).map {
div("px-4 py-6 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-0") {
attributes["data-controller"] = "toggle"

this@dl.dt("text-sm font-medium leading-6 text-gray-900") { +it.label }
this@dl.dd("mt-1 flex text-sm leading-6 text-gray-700 sm:col-span-2 sm:mt-0") {
span("flex-grow") { +it.description }
span("ml-4 flex-shrink-0") {
it.button?.let { button ->
form {
action = BackfillShowButtonHandlerAction.PATH.replace("{id}", id)
span("flex-grow") {
attributes["data-toggle-target"] = "toggleable"
attributes["data-css-class"] = "hidden"

// POST /backfills/1/start
// POST /backfills/1/stop
// POST /backfills/1/update { num_threads: 2 }
+it.description
}
it.button?.let { button ->
if (button.label == UPDATE_BUTTON_LABEL) {
// Initial Update Button to toggle showing form
span("ml-4 flex-shrink-0") {
attributes["data-toggle-target"] = "toggleable"
attributes["data-css-class"] = "hidden"

it.updateFieldId?.let {
button(
classes = "mt-1 rounded-md font-medium text-indigo-600 hover:text-indigo-500",
) {
attributes["data-action"] = "toggle#toggle"
type = ButtonType.button
+button.label
}
}

// Have initial click reveal the update form with editable input
form(classes = "flex-grow hidden") {
attributes["data-toggle-target"] = "toggleable"
attributes["data-css-class"] = "hidden"

action = BackfillShowButtonHandlerAction.PATH.replace("{id}", id)

it.updateFieldId?.let { updateFieldId ->
input {
type = InputType.hidden
name = "field_id"
value = it
value = updateFieldId
}

input {
type = InputType.hidden
name = "field_value"
value = button.href
div {
div("flex rounded-md shadow-sm") {
div("relative flex flex-grow items-stretch focus-within:z-10") {
input(classes = "block w-full rounded-none rounded-l-md border-0 py-1.5 text-gray-900 ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6") {
name = "field_value"
value = it.description
}
}
button(classes = "relative -ml-px inline-flex items-center gap-x-1.5 rounded-r-md px-3 py-2 text-sm font-semibold text-gray-900 ring-1 ring-inset ring-gray-300 hover:bg-gray-50") {
type = ButtonType.submit
+"""Update"""
}
}
}
}
}

// Cancel Button to hide form
span("hidden ml-4 flex-shrink-0") {
attributes["data-toggle-target"] = "toggleable"
attributes["data-css-class"] = "hidden"

button(
classes = "rounded-md bg-white font-medium text-indigo-600 hover:text-indigo-500",
classes = "mt-1 rounded-md font-medium text-indigo-600 hover:text-indigo-500",
) {
type = ButtonType.submit
+button.label
attributes["data-action"] = "toggle#toggle"
type = ButtonType.button
+"Cancel"
}
}
} else {
span("ml-4 flex-shrink-0") {
// Button when clicked updates without additional form
form {
action = BackfillShowButtonHandlerAction.PATH.replace("{id}", id)

it.updateFieldId?.let {
input {
type = InputType.hidden
name = "field_id"
value = it
}

input {
type = InputType.hidden
name = "field_value"
value = button.href
}
}

button(
classes = "rounded-md font-medium text-indigo-600 hover:text-indigo-500",
) {
type = ButtonType.submit
+button.label
}
}
}
}
Expand Down Expand Up @@ -176,11 +241,16 @@ class BackfillShowAction @Inject constructor(
div("truncate font-medium text-gray-900") { +partition.name }
}
td("hidden py-5 pl-8 pr-0 text-right align-top text-gray-700 sm:table-cell") { +partition.state.name }
td("hidden py-5 pl-8 pr-0 text-right align-top tabular-nums text-gray-700 sm:table-cell") { +(partition.pkey_cursor ?: "") }
td("hidden py-5 pl-8 pr-0 text-right align-top tabular-nums text-gray-700 sm:table-cell") {
+(partition.pkey_cursor ?: "")
}
td("hidden py-5 pl-8 pr-0 text-right align-top text-gray-700 sm:table-cell") { +"""${partition.pkey_start} to ${partition.pkey_end}""" }
td("hidden py-5 pl-8 pr-0 text-right align-top text-gray-700 sm:table-cell") { +"""${partition.backfilled_matching_record_count} / ${partition.computed_matching_record_count}""" }
td("hidden py-5 pl-8 pr-0 text-right align-top tabular-nums text-gray-700 sm:table-cell") {
ProgressBar(partition.backfilled_matching_record_count, partition.computed_matching_record_count)
ProgressBar(
partition.backfilled_matching_record_count,
partition.computed_matching_record_count,
)
}
td("hidden py-5 pl-8 pr-0 text-right align-top tabular-nums text-gray-700 sm:table-cell") { +"""${partition.matching_records_per_minute} #/m""" }
td("py-5 pl-8 pr-0 text-right align-top tabular-nums text-gray-700") { +"""ETA TODO""" }
Expand Down Expand Up @@ -219,9 +289,11 @@ class BackfillShowAction @Inject constructor(
tbody {
backfill.event_logs.map { log ->
tr("border-b border-gray-100") {
td("hidden py-5 pl-8 pr-0 align-top text-wrap text-gray-700 sm:table-cell") { +log.occurred_at.toString().replace("T", " ").dropLast(5) }
td("hidden py-5 pl-8 pr-0 align-top text-gray-700 sm:table-cell") { log.user ?.let { +it } }
td("hidden py-5 pl-8 pr-0 align-top text-gray-700 sm:table-cell") { log.partition_name ?.let { +it } }
td("hidden py-5 pl-8 pr-0 align-top text-wrap text-gray-700 sm:table-cell") {
+log.occurred_at.toString().replace("T", " ").dropLast(5)
}
td("hidden py-5 pl-8 pr-0 align-top text-gray-700 sm:table-cell") { log.user?.let { +it } }
td("hidden py-5 pl-8 pr-0 align-top text-gray-700 sm:table-cell") { log.partition_name?.let { +it } }
td("hidden py-5 pl-8 pr-0 align-top max-w-2 text-wrap text-gray-700 sm:table-cell") { +log.message }
td("hidden py-5 pl-8 pr-0 align-top max-w-2 text-wrap text-gray-700 sm:table-cell") { log.extra_data?.let { +it } }
}
Expand Down Expand Up @@ -253,6 +325,7 @@ class BackfillShowAction @Inject constructor(
label = "Start",
href = BackfillState.RUNNING.name,
)

BackfillState.COMPLETE -> null
else -> Link(
label = "Pause",
Expand All @@ -276,7 +349,7 @@ class BackfillShowAction @Inject constructor(
label = "Threads per partition",
description = num_threads.toString(),
button = Link(
label = "Update",
label = UPDATE_BUTTON_LABEL,
href = "#",
),
updateFieldId = "num_threads",
Expand All @@ -285,7 +358,7 @@ class BackfillShowAction @Inject constructor(
label = "Scan Size",
description = scan_size.toString(),
button = Link(
label = "Update",
label = UPDATE_BUTTON_LABEL,
href = "#",
),
updateFieldId = "scan_size",
Expand All @@ -294,7 +367,7 @@ class BackfillShowAction @Inject constructor(
label = "Batch Size",
description = batch_size.toString(),
button = Link(
label = "Update",
label = UPDATE_BUTTON_LABEL,
href = "#",
),
updateFieldId = "batch_size",
Expand All @@ -303,7 +376,7 @@ class BackfillShowAction @Inject constructor(
label = "Sleep betweeen batches (ms)",
description = extra_sleep_ms.toString(),
button = Link(
label = "Update",
label = UPDATE_BUTTON_LABEL,
href = "#",
),
updateFieldId = "extra_sleep_ms",
Expand All @@ -312,7 +385,7 @@ class BackfillShowAction @Inject constructor(
label = "Backoff Schedule",
description = backoff_schedule ?: "",
button = Link(
label = "Update",
label = UPDATE_BUTTON_LABEL,
href = "#",
),
updateFieldId = "backoff_schedule",
Expand All @@ -333,5 +406,7 @@ class BackfillShowAction @Inject constructor(

companion object {
const val PATH = "/backfills/{id}"

const val UPDATE_BUTTON_LABEL = "Update"
}
}
Loading