diff --git a/modules/common/src/main/scala/docspell/common/EmptyTrashArgs.scala b/modules/common/src/main/scala/docspell/common/EmptyTrashArgs.scala index 8061f531..4267a971 100644 --- a/modules/common/src/main/scala/docspell/common/EmptyTrashArgs.scala +++ b/modules/common/src/main/scala/docspell/common/EmptyTrashArgs.scala @@ -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] = diff --git a/modules/joex/src/main/scala/docspell/joex/JoexAppImpl.scala b/modules/joex/src/main/scala/docspell/joex/JoexAppImpl.scala index e03a05aa..9bde54ec 100644 --- a/modules/joex/src/main/scala/docspell/joex/JoexAppImpl.scala +++ b/modules/joex/src/main/scala/docspell/joex/JoexAppImpl.scala @@ -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 diff --git a/modules/joex/src/main/scala/docspell/joex/emptytrash/EmptyTrashTask.scala b/modules/joex/src/main/scala/docspell/joex/emptytrash/EmptyTrashTask.scala index 8cd4d8a1..01cfaca9 100644 --- a/modules/joex/src/main/scala/docspell/joex/emptytrash/EmptyTrashTask.scala +++ b/modules/joex/src/main/scala/docspell/joex/emptytrash/EmptyTrashTask.scala @@ -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], diff --git a/modules/store/src/main/resources/db/migration/h2/V1.25.3__delete_corrupt_trash_task.sql b/modules/store/src/main/resources/db/migration/h2/V1.25.3__delete_corrupt_trash_task.sql new file mode 100644 index 00000000..176ceefb --- /dev/null +++ b/modules/store/src/main/resources/db/migration/h2/V1.25.3__delete_corrupt_trash_task.sql @@ -0,0 +1,3 @@ +-- note this is only for users of nightly releases +DELETE FROM "periodic_task" +WHERE "task" = 'empty-trash'; diff --git a/modules/store/src/main/resources/db/migration/mariadb/V1.25.3__delete_corrupt_trash_task.sql b/modules/store/src/main/resources/db/migration/mariadb/V1.25.3__delete_corrupt_trash_task.sql new file mode 100644 index 00000000..3016b0a9 --- /dev/null +++ b/modules/store/src/main/resources/db/migration/mariadb/V1.25.3__delete_corrupt_trash_task.sql @@ -0,0 +1,3 @@ +-- note this is only for users of nightly releases +DELETE FROM `periodic_task` +WHERE `task` = 'empty-trash'; diff --git a/modules/store/src/main/resources/db/migration/postgresql/V1.25.3__delete_corrupt_trash_task.sql b/modules/store/src/main/resources/db/migration/postgresql/V1.25.3__delete_corrupt_trash_task.sql new file mode 100644 index 00000000..176ceefb --- /dev/null +++ b/modules/store/src/main/resources/db/migration/postgresql/V1.25.3__delete_corrupt_trash_task.sql @@ -0,0 +1,3 @@ +-- note this is only for users of nightly releases +DELETE FROM "periodic_task" +WHERE "task" = 'empty-trash'; diff --git a/modules/store/src/main/scala/docspell/store/usertask/UserTaskStore.scala b/modules/store/src/main/scala/docspell/store/usertask/UserTaskStore.scala index 7e9e7d01..3dddcb7a 100644 --- a/modules/store/src/main/scala/docspell/store/usertask/UserTaskStore.scala +++ b/modules/store/src/main/scala/docspell/store/usertask/UserTaskStore.scala @@ -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!