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

  • Could you wait to assign the task until they complete the previous one? That way, you wouldn't have any collisions because the task would be assigned directly to the user once they finish the previous task. Here's what I'm envisioning:

    The user is finished with their current task and they click submit. Once they submit their task, it starts a sub process which checks the next task in the list and assigns it directly to them. Then, this task is chained to a new task that has a link only to the new task. That way, there would never be a collision because the task isn't assigned UNTIL they complete the previous task.

    The only downside to this is that they would have to click the submit, then click a link to the task. However, it should solve the accidental collisions issue.

  • Certified Lead Developer

    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.

  • 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

  • I hadn't considered this approach, but I'll explore it a bit today and we'll see what comes up.. 

    Thanks for the help!

  • I've just been having that discussion with a colleague as well.  The problem our product owners perceive is that users may collide on picking up a task.  My experience has been, that even in high volume environments, it's just not that big a deal, but I don't want to dismiss the concern either.  

    One way of answering the question seems to be to abstract the view of available tasks through a database table that uses a lock approach to ensure users don't tread on each other's toes - so to speak.

    We've done this in the past to achieve "Taskless" work assignment where everything was managed outside of process tasks, and the process models merely updated database tables which in turn were viewed/updated through a continuously looping SAIL interface.

    I think that model is unsustainable and really loses out on Appian's task management tools.  

    So I think we're going to try first to settle our user's concerns and try to stay as OOB as possible, but if we must answer collision avoidance we'll use a lockable-database-row-per-task approach.

    Thanks for all of the input, this is a great discussion.

  • 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.