Appian Tasks race condition

We are redesigning a non-Appian applicaiton for a new build in Appian. In this tool, users are typically presented with the next work item immediately after completing one.

This seems akin to activity chaining tasks in Appian, a practice that we understand, and know it isn't a good fit. We have presented a proof-of-concept application that uses a sail interface without Appian tasks to mimic this push-mode, but we would either have to abandon or re-create functionality that comes standard with Appian tasks - Escalations, Exceptions, Group Assignment, performance metrics, Task Reports......

The concern among our stakeholders is centered around users colliding on task acceptance by following links from task reports.

E.g. two users click the same task link, and one accepts before the other. This would leave the second user reading a message that the task had been accepted by the first user and they would have to return to the task list and make a second attempt at finding/accepting a task.

Our stakeholders feel this is unacceptable, even in a low-volume environment.

Is there a best practice around task presentation and task acceptance that would avoid that possibility while still allowing us to leverage standard OOB Appian Tasks?

  Discussion posts and replies are publicly visible

Parents
  • Last year I designed a small new application that used Reports instead of a Task List, and I got around the issue of task acceptance collisions by using a hybrid approach basically.  That is, the first "task" (the one that's eligible for acceptance by anyone in a group), is not actually a task but instead a database row.  A Task Report shows a grid of such available "tasks" and each one takes the form of a Start Process Link.  Immediately after a user clicks into it, in the process side, a database lock is written (after being quickly re-queried and double-checked), which causes that task to show up as "locked" and un-clickable to other users (and if a user had already loaded the task report and not refreshed it before clicking one that someone else just took, they're redirected in-process to a friendly error screen explaining that someone else has already accepted that one).

    In your case i'm somewhat unclear whether there would just be a certain set selection of tasks that would be picked up by anyone in a group, or if *every* task in a process flow would at some point be group-assigned.  My approach above is likely too cumbersome to do for a large collection of tasks, but if your jump-in points are reasonably few, it might be worth considering.

Reply
  • Last year I designed a small new application that used Reports instead of a Task List, and I got around the issue of task acceptance collisions by using a hybrid approach basically.  That is, the first "task" (the one that's eligible for acceptance by anyone in a group), is not actually a task but instead a database row.  A Task Report shows a grid of such available "tasks" and each one takes the form of a Start Process Link.  Immediately after a user clicks into it, in the process side, a database lock is written (after being quickly re-queried and double-checked), which causes that task to show up as "locked" and un-clickable to other users (and if a user had already loaded the task report and not refreshed it before clicking one that someone else just took, they're redirected in-process to a friendly error screen explaining that someone else has already accepted that one).

    In your case i'm somewhat unclear whether there would just be a certain set selection of tasks that would be picked up by anyone in a group, or if *every* task in a process flow would at some point be group-assigned.  My approach above is likely too cumbersome to do for a large collection of tasks, but if your jump-in points are reasonably few, it might be worth considering.

Children
  • That's close to what I was thinking as well.  I think your approach is more mature than my initial thoughts were.  What I was thinking of doing was having a process that ran the task report and kept a db table current with outstanding tasks that were assigned to a group, the process would assign individual tasks that were currently unaccepted to any users who didn't have any tasks currently assigned and present a filtered report to each logged in user.

    I like the idea of using database locks as part of the collision avoidance strategy too.  This is a relatively small task set in an (again) relatively short process, so this would probably work well.

    Thanks for your input

  • Certified Lead Developer
    in reply to Mike Schmitt

    A colleague of mine built something very similar on another project we were doing.  Just an absolutely enormous number of our requirements across modules called for "Assigning a Task" and we determined that these tasks would kill the system with idle processes waiting to be picked up.

    The best advantage we saw for database-driven tasks was the fact that processes didn't start until the user clicked on the start process link.  We also used pessimistic locking to ensure only one person did the task at a time.