mirror of
https://github.com/TheAnachronism/docspell.git
synced 2025-06-05 06:35:59 +00:00
Fix storing empty-trash task
It was wrongly stored using RPeriodicTask directly, but the higher level `UserTask` must be used instead, because this ensures a correctly scoped periodic task using the `updateOneTask` method. Since this is a system task, it can be given a fixed ID which makes it now safe even if stored using RPeriodicTask directly. The bug resulted in multiple empty-trash tasks to be inserted (on each restart). Refs: #347
This commit is contained in:
parent
e85bd1267c
commit
90421599ea
@ -25,6 +25,8 @@ case class EmptyTrashArgs(
|
||||
def makeSubject: String =
|
||||
s"Empty Trash: Remove older than ${minAge.toJava}"
|
||||
|
||||
def periodicTaskId: Ident =
|
||||
EmptyTrashArgs.periodicTaskId(collective)
|
||||
}
|
||||
|
||||
object EmptyTrashArgs {
|
||||
@ -33,6 +35,9 @@ object EmptyTrashArgs {
|
||||
|
||||
val defaultSchedule = CalEvent.unsafe("*-*-1/7 03:00:00")
|
||||
|
||||
def periodicTaskId(coll: Ident): Ident =
|
||||
Ident.unsafe(s"docspell") / taskName / coll
|
||||
|
||||
implicit val jsonEncoder: Encoder[EmptyTrashArgs] =
|
||||
deriveEncoder[EmptyTrashArgs]
|
||||
implicit val jsonDecoder: Decoder[EmptyTrashArgs] =
|
||||
|
@ -40,6 +40,8 @@ import docspell.store.records.{REmptyTrashSetting, RJobLog}
|
||||
import emil.javamail._
|
||||
import org.http4s.blaze.client.BlazeClientBuilder
|
||||
import org.http4s.client.Client
|
||||
import docspell.store.usertask.UserTaskStore
|
||||
import docspell.store.usertask.UserTaskScope
|
||||
|
||||
final class JoexAppImpl[F[_]: Async](
|
||||
cfg: Config,
|
||||
@ -91,9 +93,15 @@ final class JoexAppImpl[F[_]: Async](
|
||||
REmptyTrashSetting.findForAllCollectives(OCollective.EmptyTrash.default, 50)
|
||||
)
|
||||
.evalMap(es =>
|
||||
EmptyTrashTask.periodicTask(EmptyTrashArgs(es.cid, es.minAge), es.schedule)
|
||||
UserTaskStore(store).use { uts =>
|
||||
val args = EmptyTrashArgs(es.cid, es.minAge)
|
||||
uts.updateOneTask(
|
||||
UserTaskScope(args.collective),
|
||||
args.makeSubject.some,
|
||||
EmptyTrashTask.userTask(args, es.schedule)
|
||||
)
|
||||
}
|
||||
)
|
||||
.evalMap(pstore.insert)
|
||||
.compile
|
||||
.drain
|
||||
|
||||
|
@ -13,8 +13,8 @@ import fs2.Stream
|
||||
import docspell.backend.ops.{OItem, OItemSearch}
|
||||
import docspell.common._
|
||||
import docspell.joex.scheduler._
|
||||
import docspell.store.records.{RItem, RPeriodicTask}
|
||||
import docspell.store.usertask.{UserTask, UserTaskScope}
|
||||
import docspell.store.records.RItem
|
||||
import docspell.store.usertask.UserTask
|
||||
|
||||
import com.github.eikek.calev.CalEvent
|
||||
|
||||
@ -26,19 +26,15 @@ object EmptyTrashTask {
|
||||
|
||||
private val pageSize = 20
|
||||
|
||||
def periodicTask[F[_]: Sync](args: EmptyTrashArgs, ce: CalEvent): F[RPeriodicTask] =
|
||||
Ident
|
||||
.randomId[F]
|
||||
.flatMap(id =>
|
||||
UserTask(
|
||||
id,
|
||||
EmptyTrashArgs.taskName,
|
||||
true,
|
||||
ce,
|
||||
None,
|
||||
args
|
||||
).encode.toPeriodicTask(UserTaskScope(args.collective), args.makeSubject.some)
|
||||
)
|
||||
def userTask(args: EmptyTrashArgs, ce: CalEvent): UserTask[EmptyTrashArgs] =
|
||||
UserTask(
|
||||
args.periodicTaskId,
|
||||
EmptyTrashArgs.taskName,
|
||||
true,
|
||||
ce,
|
||||
None,
|
||||
args
|
||||
)
|
||||
|
||||
def apply[F[_]: Async](
|
||||
itemOps: OItem[F],
|
||||
|
@ -0,0 +1,3 @@
|
||||
-- note this is only for users of nightly releases
|
||||
DELETE FROM "periodic_task"
|
||||
WHERE "task" = 'empty-trash';
|
@ -0,0 +1,3 @@
|
||||
-- note this is only for users of nightly releases
|
||||
DELETE FROM `periodic_task`
|
||||
WHERE `task` = 'empty-trash';
|
@ -0,0 +1,3 @@
|
||||
-- note this is only for users of nightly releases
|
||||
DELETE FROM "periodic_task"
|
||||
WHERE "task" = 'empty-trash';
|
@ -81,7 +81,8 @@ trait UserTaskStore[F[_]] {
|
||||
*
|
||||
* Unlike `updateTask`, this ensures that there is at most one task of some name in the
|
||||
* db. Multiple same tasks (task with same name) may not be allowed to run, depending
|
||||
* on what they do. This is not ensured by the database, though.
|
||||
* on what they do. This is not ensured by the database, though. The task is identified
|
||||
* by task name, submitter and group.
|
||||
*
|
||||
* If there are currently multiple tasks with same name as `ut` for the user `account`,
|
||||
* they will all be removed and the given task inserted!
|
||||
|
Loading…
x
Reference in New Issue
Block a user