mirror of
https://github.com/TheAnachronism/docspell.git
synced 2025-06-23 19:08:26 +00:00
Fix next-job query to do round-robin through job groups
This commit is contained in:
@ -60,8 +60,11 @@ object QJob {
|
||||
store.transact(for {
|
||||
n <- RJob.setScheduled(job.id, worker)
|
||||
_ <-
|
||||
if (n == 1) RJobGroupUse.setGroup(RJobGroupUse(worker, job.group))
|
||||
if (n == 1) RJobGroupUse.setGroup(RJobGroupUse(job.group, worker))
|
||||
else 0.pure[ConnectionIO]
|
||||
_ <- logger.fdebug[ConnectionIO](
|
||||
s"Scheduled job ${job.info} to worker ${worker.id}"
|
||||
)
|
||||
} yield if (n == 1) Right(job) else Left(()))
|
||||
|
||||
for {
|
||||
@ -98,22 +101,42 @@ object QJob {
|
||||
val stateCond =
|
||||
JC.state === JobState.waiting || (JC.state === JobState.stuck && stuckTrigger < now.toMillis)
|
||||
|
||||
object AllGroups extends TableDef {
|
||||
val tableName = "allgroups"
|
||||
val alias = Some("ag")
|
||||
|
||||
val group: Column[Ident] = JC.group.copy(table = this)
|
||||
|
||||
val selectAll = Select(JC.group.s, from(JC), stateCond).distinct
|
||||
}
|
||||
|
||||
val sql1 =
|
||||
Select(
|
||||
max(JC.group).as("g"),
|
||||
from(JC).innerJoin(G, JC.group === G.group),
|
||||
G.worker === worker && stateCond
|
||||
select(min(AllGroups.group).as("g"), lit("0 as n")),
|
||||
from(AllGroups),
|
||||
AllGroups.group > Select(G.group.s, from(G), G.worker === worker)
|
||||
)
|
||||
|
||||
val sql2 =
|
||||
Select(min(JC.group).as("g"), from(JC), stateCond)
|
||||
Select(
|
||||
select(min(AllGroups.group).as("g"), lit("1 as n")),
|
||||
from(AllGroups)
|
||||
)
|
||||
|
||||
val gcol = Column[String]("g", TableDef(""))
|
||||
val gnum = Column[Int]("n", TableDef(""))
|
||||
val groups =
|
||||
Select(select(gcol), from(union(sql1, sql2), "t0"), gcol.isNull.negate)
|
||||
withCte(AllGroups -> AllGroups.selectAll)
|
||||
.select(Select(gcol.s, from(union(sql1, sql2), "t0"), gcol.isNull.negate))
|
||||
.orderBy(gnum.asc)
|
||||
.limit(1)
|
||||
|
||||
// either 0, one or two results, but may be empty if RJob table is empty
|
||||
groups.build.query[Ident].to[List].map(_.headOption)
|
||||
val frag = groups.build
|
||||
logger.trace(
|
||||
s"nextGroupQuery: $frag (now=${now.toMillis}, pause=${initialPause.millis})"
|
||||
)
|
||||
|
||||
frag.query[Ident].option
|
||||
}
|
||||
|
||||
private def stuckTriggerValue(t: RJob.Table, initialPause: Duration, now: Timestamp) =
|
||||
|
@ -36,4 +36,7 @@ object RJobGroupUse {
|
||||
|
||||
def findGroup(workerId: Ident): ConnectionIO[Option[Ident]] =
|
||||
run(select(T.group), from(T), T.worker === workerId).query[Ident].option
|
||||
|
||||
def deleteAll: ConnectionIO[Int] =
|
||||
DML.delete(T, T.group.isNotNull)
|
||||
}
|
||||
|
Reference in New Issue
Block a user