Concurrency in Forge

Hi,

I’m quite new to forge and still have problems understanding some basic concepts regarding concurrency. Sadly I did not find much documentation about this topic.

As far as I understood, it can happen that forge functions are executed concurrently, probably even in parallel, correct?
This means in particular that this can lead to race conditions, e.g. when working with shared data like issue properties/fields or multiple issues.

To be more specific, here an example:
Let’s say I subscribe to a product event. In the corresponding event handler I do some stuff and depending on the result I want to update multiple issues.
Since product events can be “emitted” by many people simultaneously, I assume that more than one of these event handlers could be executed concurrently. (correct?)
This means that it can happen that some of the issues get their final value from one event handler whereas other issues get it from another event handler, which leads to inconsistencies.

I assume this is a very general problem, which many developers will encounter.
Does anyone know how to solve this? Is there documentation somewhere which I missed? What’s the official approach Atlassian is suggesting here?

Thanks,
Sebastian

1 Like

Not sure about Forge, but if I remember correct, the webhook events that you receive in Connect have an HTTP header that lists the order of the webhook received. In theory, this allows you to reshuffle & queue the event and have them processed in order. However, I would strongly recommend making sure event handling is idempotent, as Atlassian event processing does not guarantee delivery nor order. This means that any processing done after receiving an event should not result in data loss.

Perhaps you can elaborate more on what you are trying to do?

1 Like

Hi remie,

first of all thanks for the answer :slightly_smiling_face:

Having a queue and process the events in order would be one way how I could solve my problem. However I did not find a way how I can do this with forge. I.e. how one can create a queue and put items on it from concurrent functions such that the items on the queue are handled after each other.

I’ll try to elaborate a bit more what I want to achieve (this is a reduced example which does not really make sense, but hopefully shows what I want to do):

Given: a list L of issues: [IssueA, IssueB, IssueC]
Whenever any issue gets updated I want to assign the issue name of the updated issue to custom fields on the issues of L.

The app would look like this:

  1. Subscribe to the event avi:jira:updated:issue (see https://developer.atlassian.com/platform/forge/events-reference/jira/#issue-events)
  2. In the event handler I will assign the issue name of the issue which triggered the event handler to a custom field for all issues contained in the list L.

So if an issue with name “Issue1” gets updated, the event handler will assign “Issue1” to a custom field in “IssueA”, “IssueB” and “IssueC”.

The problem now is if two issues (“Issue1” and “Issue2”) are modified and the corresponding event handlers (let’s call them issue_1_event_handler and issue_2_event_handler) are executed concurrently:

Time	| issue_1_event_handler					   		|  issue_2_event_handler
------------------------------------------------------------------------------------------------------------------------------------
  ↓		|  update custom field of IssueA to "Issue1"	|
  ↓		|  update custom field of IssueB to "Issue1"	|
  ↓		|												|  update custom field of IssueA to "Issue2"
  ↓		|												|  update custom field of IssueB to "Issue2"
  ↓		|												|  update custom field of IssueC to "Issue2"
  ↓		|  update custom field of IssueC to "Issue1"	|

Then, in this case (it’s non-deterministic), the custom fields of IssueA and IssueB would have the value “Issue2”, whereas the one of IssueC would have the value “Issue1”. I.e. the values would be inconsistent.

I hope this makes my problem a bit clearer.

1 Like