Refactor user tasks to support collective and user scopes

Before, there were periodic tasks run per collective and not user by
making sure that submitter + group are the same value. This is now
encoded in `UserTaskScope` so it is now obvious and errors can be
reduced when using this.
This commit is contained in:
eikek
2021-08-14 21:10:09 +02:00
parent 548dfb9a57
commit 31d885ed79
14 changed files with 177 additions and 114 deletions

View File

@ -18,8 +18,7 @@ import docspell.store.UpdateResult
import docspell.store.queries.QCollective
import docspell.store.queue.JobQueue
import docspell.store.records._
import docspell.store.usertask.UserTask
import docspell.store.usertask.UserTaskStore
import docspell.store.usertask.{UserTask, UserTaskScope, UserTaskStore}
import docspell.store.{AddResult, Store}
import com.github.eikek.calev._
@ -169,7 +168,7 @@ object OCollective {
None,
LearnClassifierArgs(coll)
)
_ <- uts.updateOneTask(AccountId(coll, LearnClassifierArgs.taskName), ut)
_ <- uts.updateOneTask(UserTaskScope(coll), ut)
_ <- joex.notifyAllNodes
} yield ()
@ -185,7 +184,7 @@ object OCollective {
None,
EmptyTrashArgs(coll)
)
_ <- uts.updateOneTask(AccountId(coll, coll), ut)
_ <- uts.updateOneTask(UserTaskScope(coll), ut)
_ <- joex.notifyAllNodes
} yield ()
@ -199,7 +198,7 @@ object OCollective {
CalEvent(WeekdayComponent.All, DateEvent.All, TimeEvent.All),
None,
LearnClassifierArgs(collective)
).encode.toPeriodicTask(AccountId(collective, LearnClassifierArgs.taskName))
).encode.toPeriodicTask(UserTaskScope(collective))
job <- ut.toJob
_ <- queue.insert(job)
_ <- joex.notifyAllNodes
@ -215,7 +214,7 @@ object OCollective {
CalEvent(WeekdayComponent.All, DateEvent.All, TimeEvent.All),
None,
EmptyTrashArgs(collective)
).encode.toPeriodicTask(AccountId(collective, collective))
).encode.toPeriodicTask(UserTaskScope(collective))
job <- ut.toJob
_ <- queue.insert(job)
_ <- joex.notifyAllNodes

View File

@ -21,47 +21,47 @@ trait OUserTask[F[_]] {
/** Return the settings for all scan-mailbox tasks of the current user.
*/
def getScanMailbox(account: AccountId): Stream[F, UserTask[ScanMailboxArgs]]
def getScanMailbox(scope: UserTaskScope): Stream[F, UserTask[ScanMailboxArgs]]
/** Find a scan-mailbox task by the given id. */
def findScanMailbox(
id: Ident,
account: AccountId
scope: UserTaskScope
): OptionT[F, UserTask[ScanMailboxArgs]]
/** Updates the scan-mailbox tasks and notifies the joex nodes.
*/
def submitScanMailbox(
account: AccountId,
scope: UserTaskScope,
task: UserTask[ScanMailboxArgs]
): F[Unit]
/** Return the settings for all the notify-due-items task of the
* current user.
*/
def getNotifyDueItems(account: AccountId): Stream[F, UserTask[NotifyDueItemsArgs]]
def getNotifyDueItems(scope: UserTaskScope): Stream[F, UserTask[NotifyDueItemsArgs]]
/** Find a notify-due-items task by the given id. */
def findNotifyDueItems(
id: Ident,
account: AccountId
scope: UserTaskScope
): OptionT[F, UserTask[NotifyDueItemsArgs]]
/** Updates the notify-due-items tasks and notifies the joex nodes.
*/
def submitNotifyDueItems(
account: AccountId,
scope: UserTaskScope,
task: UserTask[NotifyDueItemsArgs]
): F[Unit]
/** Removes a user task with the given id. */
def deleteTask(account: AccountId, id: Ident): F[Unit]
def deleteTask(scope: UserTaskScope, id: Ident): F[Unit]
/** Discards the schedule and immediately submits the task to the job
* executor's queue. It will not update the corresponding periodic
* task.
*/
def executeNow[A](account: AccountId, task: UserTask[A])(implicit
def executeNow[A](scope: UserTaskScope, task: UserTask[A])(implicit
E: Encoder[A]
): F[Unit]
}
@ -75,57 +75,59 @@ object OUserTask {
): Resource[F, OUserTask[F]] =
Resource.pure[F, OUserTask[F]](new OUserTask[F] {
def executeNow[A](account: AccountId, task: UserTask[A])(implicit
def executeNow[A](scope: UserTaskScope, task: UserTask[A])(implicit
E: Encoder[A]
): F[Unit] =
for {
ptask <- task.encode.toPeriodicTask(account)
ptask <- task.encode.toPeriodicTask(scope)
job <- ptask.toJob
_ <- queue.insert(job)
_ <- joex.notifyAllNodes
} yield ()
def getScanMailbox(account: AccountId): Stream[F, UserTask[ScanMailboxArgs]] =
def getScanMailbox(scope: UserTaskScope): Stream[F, UserTask[ScanMailboxArgs]] =
store
.getByName[ScanMailboxArgs](account, ScanMailboxArgs.taskName)
.getByName[ScanMailboxArgs](scope, ScanMailboxArgs.taskName)
def findScanMailbox(
id: Ident,
account: AccountId
scope: UserTaskScope
): OptionT[F, UserTask[ScanMailboxArgs]] =
OptionT(getScanMailbox(account).find(_.id == id).compile.last)
OptionT(getScanMailbox(scope).find(_.id == id).compile.last)
def deleteTask(account: AccountId, id: Ident): F[Unit] =
def deleteTask(scope: UserTaskScope, id: Ident): F[Unit] =
(for {
_ <- store.getByIdRaw(account, id)
_ <- OptionT.liftF(store.deleteTask(account, id))
_ <- store.getByIdRaw(scope, id)
_ <- OptionT.liftF(store.deleteTask(scope, id))
} yield ()).getOrElse(())
def submitScanMailbox(
account: AccountId,
scope: UserTaskScope,
task: UserTask[ScanMailboxArgs]
): F[Unit] =
for {
_ <- store.updateTask[ScanMailboxArgs](account, task)
_ <- store.updateTask[ScanMailboxArgs](scope, task)
_ <- joex.notifyAllNodes
} yield ()
def getNotifyDueItems(account: AccountId): Stream[F, UserTask[NotifyDueItemsArgs]] =
def getNotifyDueItems(
scope: UserTaskScope
): Stream[F, UserTask[NotifyDueItemsArgs]] =
store
.getByName[NotifyDueItemsArgs](account, NotifyDueItemsArgs.taskName)
.getByName[NotifyDueItemsArgs](scope, NotifyDueItemsArgs.taskName)
def findNotifyDueItems(
id: Ident,
account: AccountId
scope: UserTaskScope
): OptionT[F, UserTask[NotifyDueItemsArgs]] =
OptionT(getNotifyDueItems(account).find(_.id == id).compile.last)
OptionT(getNotifyDueItems(scope).find(_.id == id).compile.last)
def submitNotifyDueItems(
account: AccountId,
scope: UserTaskScope,
task: UserTask[NotifyDueItemsArgs]
): F[Unit] =
for {
_ <- store.updateTask[NotifyDueItemsArgs](account, task)
_ <- store.updateTask[NotifyDueItemsArgs](scope, task)
_ <- joex.notifyAllNodes
} yield ()
})