Concurrent requests

Hi all,

I was looking why sometimes on the Malawi production server users see duplicate LMIS form comments and I found out it is possible to send several requests (in the same) to change a requisition status and all of them will be executed properly.

In other words, in the database there will be several entries in the requisition.status_changes table and if there was draft of comment in the form then there will be several entries in the requisition.status_messages table.

I think the problem is more general because we don’t have any mechanism to control concurrent requests. Basically If a user sends several requests at the same time, with the same data, an endpoint will work normally and all our validations will be omitted because data in the database and in the requests are correct.

It was hard for me to find any useful information about how to handle this issue. One solution was about using 412 HTTP error code and If-Unmodified-Since header. But in our case it will be still possible to send several requests with the same If-Unmodified-Since header but it probably removes problem with double click on the UI. Other solution was to somehow lock a resource that is required by the request. In this situation only one of requests could make changes and another requests will have to wait or they will be rejected.

What do you think about that? Do you know any other good solution to avoid this problem?

Regards,

Lukasz


SolDevelo
Sp. z o.o. [LLC] / www.soldevelo.com
Al. Zwycięstwa 96/98, 81-451, Gdynia, Poland
Phone: +48 58 782 45 40 / Fax: +48 58 782 45 41

···

Łukasz Lewczyński
Software Developer
llewczynski@soldevelo.com

I don’t think OpenLMIS has established a pattern for this yet.

Browser-side options could involve putting in logic to prevent or handle the AngularJS app making multiple concurrent requests to the same API in certain cases like this. For example, when the app is saving/updating a Requisition, perhaps we need a loading spinner on screen so we prevent the user from clicking any button a second time and causing a concurrent request. That may be the easiest option. Similar approaches in the AngularJS service layer could use a locking mechanism or queue mechanism.

Server-side options are more robust/reliable, especially in situations where we have browsers with inconsistent internet connectivity. This could involve a token that the server checks as well as the If-Unmodified-Since header. Here is a good article about REST Best Practices for Managing Concurrent Updates:
https://blog.4psa.com/rest-best-practices-managing-concurrent-updates/
. It includes the solution Łukasz is describing.

-Brandon

···

From: openlmis-dev@googlegroups.com on behalf of Łukasz Lewczyński llewczynski@soldevelo.com

Date: Friday, September 15, 2017 at 3:28 AM

To: OpenLMIS Dev openlmis-dev@googlegroups.com

Subject: [openlmis-dev] Concurrent requests

Hi all,

I was looking why sometimes on the Malawi production server users see duplicate LMIS form comments and I found out it is possible to send several requests (in the same) to change a requisition status and all of them will be executed properly.

In other words, in the database there will be several entries in the requisition.status_changes table and if there was draft of comment in the form then there will be several entries in the requisition.status_messages table.

I think the problem is more general because we don’t have any mechanism to control concurrent requests. Basically If a user sends several requests at the same time, with the same data, an endpoint will work normally and all our validations will be omitted because data in the database and in the requests are correct.

It was hard for me to find any useful information about how to handle this issue. One solution was about using 412 HTTP error code and If-Unmodified-Since header. But in our case it will be still possible to send several requests with the same If-Unmodified-Since
header but it probably removes problem with double click on the UI. Other solution was to somehow lock a resource that is required by the request. In this situation only one of requests could make changes and another requests will have to wait or they will be rejected.

What do you think about that? Do you know any other good solution to avoid this problem?

Regards,

Lukasz

Łukasz Lewczyński

Software Developer

llewczynski@soldevelo.com

**

SolDevelo** Sp. z o.o. [LLC] /
www.soldevelo.com

Al. Zwycięstwa 96/98, 81-451, Gdynia, Poland

Phone: +48 58 782 45 40 / Fax: +48 58 782 45 41

You received this message because you are subscribed to the Google Groups “OpenLMIS Dev” group.

To unsubscribe from this group and stop receiving emails from it, send an email to openlmis-dev+unsubscribe@googlegroups.com.

To post to this group, send email to
openlmis-dev@googlegroups.com.

To view this discussion on the web visit
https://groups.google.com/d/msgid/openlmis-dev/CAAdp53yBV3Jn%2Bcvv%3DUSd54cR6Fv%3D3qJUOc9M1HmNtvU%3DmMLqMg%40mail.gmail.com
.

For more options, visit https://groups.google.com/d/optout.

Putting this responsibility on the UI side is kind of doomed to fail in my opinion. We already have a spinner when saving/updating Requisitions and the user can always just press F5 and start again. I agree that the server-side options are more reliable and using one of them should be the road we take.

···

On Friday, September 15, 2017 at 12:29:15 PM UTC+2, Łukasz Lewczyński wrote:

Hi all,

I was looking why sometimes on the Malawi production server users see duplicate LMIS form comments and I found out it is possible to send several requests (in the same) to change a requisition status and all of them will be executed properly.

In other words, in the database there will be several entries in the requisition.status_changes table and if there was draft of comment in the form then there will be several entries in the requisition.status_messages table.

I think the problem is more general because we don’t have any mechanism to control concurrent requests. Basically If a user sends several requests at the same time, with the same data, an endpoint will work normally and all our validations will be omitted because data in the database and in the requests are correct.

It was hard for me to find any useful information about how to handle this issue. One solution was about using 412 HTTP error code and If-Unmodified-Since header. But in our case it will be still possible to send several requests with the same If-Unmodified-Since header but it probably removes problem with double click on the UI. Other solution was to somehow lock a resource that is required by the request. In this situation only one of requests could make changes and another requests will have to wait or they will be rejected.

What do you think about that? Do you know any other good solution to avoid this problem?

Regards,

Lukasz

Łukasz Lewczyński
Software Developer
llewc...@soldevelo.com


SolDevelo
Sp. z o.o. [LLC] / www.soldevelo.com
Al. Zwycięstwa 96/98, 81-451, Gdynia, Poland
Phone: +48 58 782 45 40 / Fax: +48 58 782 45 41

I think the solution to this problem should be on the server side. When I checked how the server will handle concurrent requests I used bash terminal instead of UI. Also we get from time to time informations that during save/submit a requisition on UI adjustments are duplicated and because of that it is impossible to authorize the requisition without changing the form - by removing those duplicates. We captured a requisition that have duplicated adjustments and I noticed that this requisition has duplicates in the status_changes table so I think this issue is related with concurrent requests.


SolDevelo
Sp. z o.o. [LLC] / www.soldevelo.com
Al. Zwycięstwa 96/98, 81-451, Gdynia, Poland
Phone: +48 58 782 45 40 / Fax: +48 58 782 45 41

···

On Mon, Sep 18, 2017 at 8:13 AM, Nikodem Graczewski ngraczewski@soldevelo.com wrote:

Putting this responsibility on the UI side is kind of doomed to fail in my opinion. We already have a spinner when saving/updating Requisitions and the user can always just press F5 and start again. I agree that the server-side options are more reliable and using one of them should be the road we take.

On Friday, September 15, 2017 at 12:29:15 PM UTC+2, Łukasz Lewczyński wrote:

Hi all,

I was looking why sometimes on the Malawi production server users see duplicate LMIS form comments and I found out it is possible to send several requests (in the same) to change a requisition status and all of them will be executed properly.

In other words, in the database there will be several entries in the requisition.status_changes table and if there was draft of comment in the form then there will be several entries in the requisition.status_messages table.

I think the problem is more general because we don’t have any mechanism to control concurrent requests. Basically If a user sends several requests at the same time, with the same data, an endpoint will work normally and all our validations will be omitted because data in the database and in the requests are correct.

It was hard for me to find any useful information about how to handle this issue. One solution was about using 412 HTTP error code and If-Unmodified-Since header. But in our case it will be still possible to send several requests with the same If-Unmodified-Since header but it probably removes problem with double click on the UI. Other solution was to somehow lock a resource that is required by the request. In this situation only one of requests could make changes and another requests will have to wait or they will be rejected.

What do you think about that? Do you know any other good solution to avoid this problem?

Regards,

Lukasz

Łukasz Lewczyński
Software Developer
llewc...@soldevelo.com

**
SolDevelo** Sp. z o.o. [LLC] / www.soldevelo.com
Al. Zwycięstwa 96/98, 81-451, Gdynia, Poland
Phone: +48 58 782 45 40 / Fax: +48 58 782 45 41

**
SolDevelo** Sp. z o.o. [LLC] / www.soldevelo.com
Al. Zwycięstwa 96/98, 81-451, Gdynia, Poland
Phone: +48 58 782 45 40 / Fax: +48 58 782 45 41

You received this message because you are subscribed to the Google Groups “OpenLMIS Dev” group.

To unsubscribe from this group and stop receiving emails from it, send an email to openlmis-dev+unsubscribe@googlegroups.com.

To post to this group, send email to openlmis-dev@googlegroups.com.

To view this discussion on the web visit https://groups.google.com/d/msgid/openlmis-dev/a1defb65-73b5-4581-a07b-1401e977bc87%40googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

Łukasz Lewczyński
Software Developer
llewczynski@soldevelo.com

Hi again,

I created a ticket in the core space: https://openlmis.atlassian.net/browse/OLMIS-3235

Regards,

Lukasz


SolDevelo
Sp. z o.o. [LLC] / www.soldevelo.com
Al. Zwycięstwa 96/98, 81-451, Gdynia, Poland
Phone: +48 58 782 45 40 / Fax: +48 58 782 45 41

···

On Mon, Sep 18, 2017 at 12:49 PM, Łukasz Lewczyński llewczynski@soldevelo.com wrote:

I think the solution to this problem should be on the server side. When I checked how the server will handle concurrent requests I used bash terminal instead of UI. Also we get from time to time informations that during save/submit a requisition on UI adjustments are duplicated and because of that it is impossible to authorize the requisition without changing the form - by removing those duplicates. We captured a requisition that have duplicated adjustments and I noticed that this requisition has duplicates in the status_changes table so I think this issue is related with concurrent requests.

Łukasz Lewczyński
Software Developer
llewczynski@soldevelo.com

Łukasz Lewczyński
Software Developer
llewczynski@soldevelo.com

On Mon, Sep 18, 2017 at 8:13 AM, Nikodem Graczewski ngraczewski@soldevelo.com wrote:

Putting this responsibility on the UI side is kind of doomed to fail in my opinion. We already have a spinner when saving/updating Requisitions and the user can always just press F5 and start again. I agree that the server-side options are more reliable and using one of them should be the road we take.

On Friday, September 15, 2017 at 12:29:15 PM UTC+2, Łukasz Lewczyński wrote:

Hi all,

I was looking why sometimes on the Malawi production server users see duplicate LMIS form comments and I found out it is possible to send several requests (in the same) to change a requisition status and all of them will be executed properly.

In other words, in the database there will be several entries in the requisition.status_changes table and if there was draft of comment in the form then there will be several entries in the requisition.status_messages table.

I think the problem is more general because we don’t have any mechanism to control concurrent requests. Basically If a user sends several requests at the same time, with the same data, an endpoint will work normally and all our validations will be omitted because data in the database and in the requests are correct.

It was hard for me to find any useful information about how to handle this issue. One solution was about using 412 HTTP error code and If-Unmodified-Since header. But in our case it will be still possible to send several requests with the same If-Unmodified-Since header but it probably removes problem with double click on the UI. Other solution was to somehow lock a resource that is required by the request. In this situation only one of requests could make changes and another requests will have to wait or they will be rejected.

What do you think about that? Do you know any other good solution to avoid this problem?

Regards,

Lukasz

Łukasz Lewczyński
Software Developer
llewc...@soldevelo.com

**
SolDevelo** Sp. z o.o. [LLC] / www.soldevelo.com
Al. Zwycięstwa 96/98, 81-451, Gdynia, Poland
Phone: +48 58 782 45 40 / Fax: +48 58 782 45 41

**
SolDevelo** Sp. z o.o. [LLC] / www.soldevelo.com
Al. Zwycięstwa 96/98, 81-451, Gdynia, Poland
Phone: +48 58 782 45 40 / Fax: +48 58 782 45 41

You received this message because you are subscribed to the Google Groups “OpenLMIS Dev” group.

To unsubscribe from this group and stop receiving emails from it, send an email to openlmis-dev+unsubscribe@googlegroups.com.

To post to this group, send email to openlmis-dev@googlegroups.com.

To view this discussion on the web visit https://groups.google.com/d/msgid/openlmis-dev/a1defb65-73b5-4581-a07b-1401e977bc87%40googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

I agree that this should be fixed on the server side. No matter what we do on the UI, it will always be possible to send multiple requests (even because users can have rights to the exact same requisition and they may decide to submit at the same time).

  What Brandon's article is describing is a little different than the problem we are having in Malawi. Moreover, we already have a similar fix implemented manually for the save operation (returning 409 Conflict in case the update dates do not match, which prevents overwriting someone's changes). The problem is when the submit, authorize or other requests are sent at the very same time. Since submit and authorize can be lengthy (several seconds), it is possible to have the validation pass for both of the concurrent requests, before the changes are saved into the database. Simplified workflow would look like:

  (validation including conflict check) -> (other logic / several seconds of processing) -> (save to the database)

  It is therefore possible to have two or more requests pass the validation, then be "stuck" for a few seconds on processing the request and then flush everything to the database (where each request that passed validation would do so and therefore potentially create duplicate entries like comments or status changes). The problem is therefore with those couple of seconds between validation and the flush to the database.

I think there are two mistakes that we have made:

   - Not relying on built-in locking of the resources (would need to explore what Spring Data offers and how it handles that)

   - Not including those checks for operations other than save

  A potential solution would be to refactor those checks to locks on the database level. We would need to explore what Spring offers and how to best tackle it first. We would want to lock a specific resource only (eq. requisition with id xyz). That means I can still concurrently update 5 different requisitions, but if I try to do it with the same requisition, I wouldn't be able to do so. Another question that needs to be answered is whether we would want optimistic or pessimistic locking. Do we just allow everything and throw an exception if conflict is detected? Or do we not allow concurrent processing of the same resource (waiting for the lock)? The latter may be more problematic on the database level.

  Alternative approach would be to keep those checks manual but refactor them to be resource locks. Submitting requisition xyz would create a lock on xyz and no other resource update would be allowed to proceed for requisition xyz until the submit of xyz is done. This would involve keeping track of the locks (eg. by requisition id) and supporting timeouts (if resource wasn't unlocked after x minutes, the lock is released).

  It would be great to get more opinions/voices on this. Concurrent requests causing duplicate comments/status changes are quite a big issue for Malawi, so having a plan to tackle this is important for us. Why the UI allows users to send concurrent requests (we have vefrified that most cases of concurrent requests are not multiple users operating on the same resource, but a single user sending multiple requests) is another case and we are investigating that in a separate ticket. Nevertheless, the API should be capable of handling the concurrent requests on its own as well, for the reasons mentioned above.

Best regards,

  Sebastian.
···

On 22.09.2017 12:05, Łukasz Lewczyński wrote:

Hi again,

I created a ticket in the core space: https://openlmis.atlassian.net/browse/OLMIS-3235

Regards,

Lukasz

Łukasz Lewczyński

              Software Developer

              llewczynski@soldevelo.com
      On Mon, Sep 18, 2017 at 12:49 PM, Łukasz Lewczyński <llewczynski@soldevelo.com>
      wrote:
          I think the solution to this problem should be on the server side. When I checked how the server will handle concurrent requests I used bash terminal instead of UI. Also we get from time to time informations that during save/submit a requisition on UI adjustments are duplicated and because of that it is impossible to authorize the requisition without changing the form - by removing those duplicates. We captured a requisition that have duplicated adjustments and I noticed that this requisition has duplicates in the **status_changes**               table so I think this issue is related with concurrent requests.

Łukasz Lewczyński

                      Software Developer

                      llewczynski@soldevelo.com
                On Mon, Sep 18, 2017 at 8:13 AM, Nikodem Graczewski <ngraczewski@soldevelo.com>
                wrote:
                    Putting this responsibility on the UI side is kind of doomed to fail in my opinion. We already have a spinner when saving/updating Requisitions and the user can always just press F5 and start again. I agree that the server-side options are more reliable and using one of them should be the road we take.



                      On Friday, September 15, 2017 at 12:29:15 PM UTC+2, Łukasz Lewczyński wrote:

Hi all,

                            I was looking why sometimes on the Malawi production server users see duplicate LMIS form comments and I found out it is possible to send several requests (in the same) to change a requisition status and all of them will be executed properly.
                            In other words, in the database there will be several entries in the *requisition.status_changes*
                            table and if there was draft of comment in the form then there will be several entries in the *requisition.status_messages*
                            table.
                            I think the problem is more general because we don't have any mechanism to control concurrent requests. Basically If a user sends several requests at the same time, with the same data, an endpoint will work normally and all our validations will be omitted because data in the database and in the requests are correct.
                            It was hard for me to find any useful information about how to handle this issue. One solution was about using *[412](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/412)*
                            HTTP error code and *[If-Unmodified-Since](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/If-Unmodified-Since)*
                            header. But in our case it will be still possible to send several requests with the same *If-Unmodified-Since*                                 header but it probably removes problem with double click on the UI. Other solution was to somehow lock a resource that is required by the request. In this situation only one of requests could make changes and another requests will have to wait or they will be rejected.
                            What do you think about that? Do you know any other good solution to avoid this problem?

Regards,

Lukasz

** Łukasz Lewczyński**

                                    Software Developer

                                    llewc...@soldevelo.com
                        **

                            SolDevelo** Sp. z o.o. [LLC] / [www.soldevelo.com](http://www.soldevelo.com)

                          Al. Zwycięstwa 96/98, 81-451, Gdynia, Poland

                          Phone:                                 +48 58 782 45 40 / Fax: +48 58 782 45 41
                    **

                        SolDevelo** Sp. z o.o. [LLC] / [www.soldevelo.com](http://www.soldevelo.com)

                      Al. Zwycięstwa 96/98, 81-451, Gdynia, Poland

                      Phone:                             +48 58 782 45 40 / Fax:                             +48 58 782 45 41

                    --

                    You received this message because you are subscribed to the Google Groups "OpenLMIS Dev" group.

                    To unsubscribe from this group and stop receiving emails from it, send an email to openlmis-dev+unsubscribe@googlegroups.com.

                    To post to this group, send email to openlmis-dev@googlegroups.com.


                  To view this discussion on the web visit [https://groups.google.com/d/msgid/openlmis-dev/a1defb65-73b5-4581-a07b-1401e977bc87%40googlegroups.com](https://groups.google.com/d/msgid/openlmis-dev/a1defb65-73b5-4581-a07b-1401e977bc87%40googlegroups.com?utm_medium=email&utm_source=footer).


                      For more options, visit [https://groups.google.com/d/optout](https://groups.google.com/d/optout).
  **![](http://www.soldevelo.com/sites/default/files/Soldevelo_logo_EPS_CMYK.png)

      SolDevelo** Sp. z o.o. [LLC] / [www.soldevelo.com](http://www.soldevelo.com)

    Al. Zwycięstwa 96/98, 81-451, Gdynia, Poland

    Phone: +48 58 782 45 40 / Fax: +48 58 782 45 41

  --

  You received this message because you are subscribed to the Google Groups "OpenLMIS Dev" group.

  To unsubscribe from this group and stop receiving emails from it, send an email to openlmis-dev+unsubscribe@googlegroups.com.

  To post to this group, send email to openlmis-dev@googlegroups.com.

  To view this discussion on the web visit [https://groups.google.com/d/msgid/openlmis-dev/CAAdp53xsgqqom0e7uX8vA81-aLGotpjjSK8VJOQcWKJ0T59AVg%40mail.gmail.com](https://groups.google.com/d/msgid/openlmis-dev/CAAdp53xsgqqom0e7uX8vA81-aLGotpjjSK8VJOQcWKJ0T59AVg%40mail.gmail.com?utm_medium=email&utm_source=footer).

  For more options, visit [https://groups.google.com/d/optout](https://groups.google.com/d/optout).


Sebastian Brudziński

    Software Developer / Team Leader


SolDevelo
Sp. z o.o. [LLC] / www.soldevelo.com
Al. Zwycięstwa 96/98, 81-451, Gdynia, Poland
Phone: +48 58 782 45 40 / Fax: +48 58 782 45 41
sbrudzinski@soldevelo.com

Sebastian, thanks for keeping this thread going and getting more input

You mentioned we are getting errors from MW — has anyone started collecting and summarizing these errors? It would be great to have a concrete section to look at, improve, and document a “best practice” around.

I do agree that the ultimate solution is to fix the issue on the backend, because I know we want to support multiple clients (eventually) — that might be written with out any of our knowledge.

On the UI side, I think we could up our game a little. A goal we need to build metrics around (and then fix) is the number of HTTP requests the UI makes, as that directly relates to a good UX and operating cost for Malawi (and other places we work)

I have noticed code that doesn’t really follow an OO pattern, which would make “locking” objects easier to work with — and I could go “splunking” for specifics, but would much rather have analytics to guide where we do refactors.

– nick –

···

Nick Reid | nick.reid@villagereach.org

Software Developer, Information Systems Group

VillageReach** *** Starting at the Last Mile
*2900 Eastlake Ave. E, Suite 230, Seattle, WA 98102, USA

CELL: +1.510.410.0020

SKYPE: nickdotreid

www.villagereach.org


From: openlmis-dev@googlegroups.com openlmis-dev@googlegroups.com on behalf of Sebastian Brudziński sbrudzinski@soldevelo.com

Sent: Monday, September 25, 2017 5:43:40 AM

To: openlmis-dev@googlegroups.com

Subject: Re: [openlmis-dev] Re: Concurrent requests

I agree that this should be fixed on the server side. No matter what we do on the UI, it will always be possible to send multiple requests (even because users can have rights to the exact same requisition and they may decide to submit at the same time).

What Brandon’s article is describing is a little different than the problem we are having in Malawi. Moreover, we already have a similar fix implemented manually for the save operation (returning 409 Conflict in case the update dates do not match, which prevents overwriting someone’s changes). The problem is when the submit, authorize or other requests are sent at the very same time. Since submit and authorize can be lengthy (several seconds), it is possible to have the validation pass for both of the concurrent requests, before the changes are saved into the database. Simplified workflow would look like:

(validation including conflict check) -> (other logic / several seconds of processing) -> (save to the database)

It is therefore possible to have two or more requests pass the validation, then be “stuck” for a few seconds on processing the request and then flush everything to the database (where each request that passed validation would do so and therefore potentially create duplicate entries like comments or status changes). The problem is therefore with those couple of seconds between validation and the flush to the database.

I think there are two mistakes that we have made:

  • Not relying on built-in locking of the resources (would need to explore what Spring Data offers and how it handles that)

  • Not including those checks for operations other than save

A potential solution would be to refactor those checks to locks on the database level. We would need to explore what Spring offers and how to best tackle it first. We would want to lock a specific resource only (eq. requisition with id xyz). That means I can still concurrently update 5 different requisitions, but if I try to do it with the same requisition, I wouldn’t be able to do so. Another question that needs to be answered is whether we would want optimistic or pessimistic locking. Do we just allow everything and throw an exception if conflict is detected? Or do we not allow concurrent processing of the same resource (waiting for the lock)? The latter may be more problematic on the database level.

Alternative approach would be to keep those checks manual but refactor them to be resource locks. Submitting requisition xyz would create a lock on xyz and no other resource update would be allowed to proceed for requisition xyz until the submit of xyz is done. This would involve keeping track of the locks (eg. by requisition id) and supporting timeouts (if resource wasn’t unlocked after x minutes, the lock is released).

It would be great to get more opinions/voices on this. Concurrent requests causing duplicate comments/status changes are quite a big issue for Malawi, so having a plan to tackle this is important for us. Why the UI allows users to send concurrent requests (we have vefrified that most cases of concurrent requests are not multiple users operating on the same resource, but a single user sending multiple requests) is another case and we are investigating that in a separate ticket. Nevertheless, the API should be capable of handling the concurrent requests on its own as well, for the reasons mentioned above.

Best regards,

Sebastian.

On 22.09.2017 12:05, Łukasz Lewczyński wrote:

Hi again,

I created a ticket in the core space: https://openlmis.atlassian.net/browse/OLMIS-3235

Regards,

Lukasz

Łukasz Lewczyński

Software Developer

llewczynski@soldevelo.com

On Mon, Sep 18, 2017 at 12:49 PM, Łukasz Lewczyński
llewczynski@soldevelo.com wrote:

I think the solution to this problem should be on the server side. When I checked how the server will handle concurrent requests I used bash terminal instead of UI. Also we get from time to time informations that during save/submit a requisition on UI adjustments are duplicated and because of that it is impossible to authorize the requisition without changing the form - by removing those duplicates. We captured a requisition that have duplicated adjustments and I noticed that this requisition has duplicates in the status_changes table so I think this issue is related with concurrent requests.

Łukasz Lewczyński

Software Developer

llewczynski@soldevelo.com

On Mon, Sep 18, 2017 at 8:13 AM, Nikodem Graczewski
ngraczewski@soldevelo.com wrote:

Putting this responsibility on the UI side is kind of doomed to fail in my opinion. We already have a spinner when saving/updating Requisitions and the user can always just press F5 and start again. I agree that the server-side options are more reliable and using one of them should be the road we take.

On Friday, September 15, 2017 at 12:29:15 PM UTC+2, Łukasz Lewczyński wrote:

Hi all,

I was looking why sometimes on the Malawi production server users see duplicate LMIS form comments and I found out it is possible to send several requests (in the same) to change a requisition status and all of them will be executed properly.

In other words, in the database there will be several entries in the requisition.status_changes table and if there was draft of comment in the form then there will be several entries in the requisition.status_messages table.

I think the problem is more general because we don’t have any mechanism to control concurrent requests. Basically If a user sends several requests at the same time, with the same data, an endpoint will work normally and all our validations will be omitted because data in the database and in the requests are correct.

It was hard for me to find any useful information about how to handle this issue. One solution was about using 412 HTTP error code and If-Unmodified-Since
header. But in our case it will be still possible to send several requests with the same If-Unmodified-Since header but it probably removes problem with double click on the UI. Other solution was to somehow lock a resource that is required by the request. In this situation only one of requests could make changes and another requests will have to wait or they will be rejected.

What do you think about that? Do you know any other good solution to avoid this problem?

Regards,

Lukasz

Łukasz Lewczyński

Software Developer

llewc...@soldevelo.com

**

SolDevelo** Sp. z o.o. [LLC] /
www.soldevelo.com

Al. Zwycięstwa 96/98, 81-451, Gdynia, Poland

Phone: +48 58 782 45 40 / Fax:
+48 58 782 45 41

**

SolDevelo** Sp. z o.o. [LLC] /
www.soldevelo.com

Al. Zwycięstwa 96/98, 81-451, Gdynia, Poland

Phone: +48 58 782 45 40 / Fax:
+48 58 782 45 41

You received this message because you are subscribed to the Google Groups “OpenLMIS Dev” group.

To unsubscribe from this group and stop receiving emails from it, send an email to
openlmis-dev+unsubscribe@googlegroups.com.

To post to this group, send email to
openlmis-dev@googlegroups.com.

To view this discussion on the web visit
https://groups.google.com/d/msgid/openlmis-dev/a1defb65-73b5-4581-a07b-1401e977bc87%40googlegroups.com
.

For more options, visit
https://groups.google.com/d/optout
.

**

SolDevelo** Sp. z o.o. [LLC] /
www.soldevelo.com

Al. Zwycięstwa 96/98, 81-451, Gdynia, Poland

Phone: +48 58 782 45 40 / Fax:
+48 58 782 45 41

You received this message because you are subscribed to the Google Groups “OpenLMIS Dev” group.

To unsubscribe from this group and stop receiving emails from it, send an email to
openlmis-dev+unsubscribe@googlegroups.com.

To post to this group, send email to
openlmis-dev@googlegroups.com.

To view this discussion on the web visit
https://groups.google.com/d/msgid/openlmis-dev/CAAdp53xsgqqom0e7uX8vA81-aLGotpjjSK8VJOQcWKJ0T59AVg%40mail.gmail.com
.

For more options, visit
https://groups.google.com/d/optout
.


Sebastian Brudziński

Software Developer / Team Leader

sbrudzinski@soldevelo.com

**

SolDevelo** Sp. z o.o. [LLC] /
www.soldevelo.com

Al. Zwycięstwa 96/98, 81-451, Gdynia, Poland

Phone: +48 58 782 45 40 / Fax: +48 58 782 45 41

You received this message because you are subscribed to the Google Groups “OpenLMIS Dev” group.

To unsubscribe from this group and stop receiving emails from it, send an email to openlmis-dev+unsubscribe@googlegroups.com.

To post to this group, send email to
openlmis-dev@googlegroups.com.

To view this discussion on the web visit
https://groups.google.com/d/msgid/openlmis-dev/7b9dd105-e1c1-b570-6b10-9e739f20c2a6%40soldevelo.com
.

For more options, visit https://groups.google.com/d/optout.

Thanks for your input, Nick. I’ve started a simple Confluence page on the Malawi space that sums up the current issues caused by concurrent requests and possible causes of concurrent requests coming from the same user:

Best regards,

  Sebastian.
···

https://openlmis.atlassian.net/wiki/spaces/MW/pages/116031617/Concurrency+issues
On 25.09.2017 17:50, Nick Reid wrote:

      Sebastian, thanks for keeping this thread going and getting more input
        You mentioned we are getting errors from MW — **              has anyone started collecting and summarizing these errors?** It would be great to have a             concrete section to look at, improve, and document a "best practice" around.
        I do agree that the ultimate solution is to fix the issue on the backend, because I know we want to support multiple clients (eventually) — that might be written with out any of our knowledge.
          On the UI side, I think we could up our game a little. A goal we need to build metrics around (and then fix) is the number of HTTP requests the UI makes, as that directly relates to a good UX and operating cost for Malawi (and other places we work)
          I have noticed code that doesn't really follow an OO pattern, which would make "locking" objects easier to work with — and I could go "splunking" for specifics, but would much rather have analytics to guide where we do refactors.

– nick –

Nick Reid | nick.reid@villagereach.org

              *                      Software Developer, Information Systems Group*

VillageReach** *** Starting at the Last Mile

             *                   2900 Eastlake Ave. E, Suite 230, Seattle, WA 98102, USA

                              CELL: +1.510.410.0020

                                SKYPE: nickdotreid

              [www.villagereach.org](http://www.villagereach.org/)

From:

       on behalf of Sebastian Brudziński Monday, September 25, 2017 5:43:40 AM Re: [openlmis-dev] Re: Concurrent requests
      I agree that this should be fixed on the server side. No matter what we do on the UI, it will always be possible to send multiple requests (even because users can have rights to the exact same requisition and they may decide to submit at the same time).
      What Brandon's article is describing is a little different than the problem we are having in Malawi. Moreover, we already have a similar fix implemented manually for the save operation (returning 409 Conflict in case the update dates do not match, which prevents overwriting someone's changes). The problem is when the submit, authorize or other requests are sent at the very same time. Since submit and authorize can be lengthy (several seconds), it is possible to have the validation pass for both of the concurrent requests, before the changes are saved into the database. Simplified workflow would look like:

      (validation including conflict check) -> (other logic / several seconds of processing) -> (save to the database)

      It is therefore possible to have two or more requests pass the validation, then be "stuck" for a few seconds on processing the request and then flush everything to the database (where each request that passed validation would do so and therefore potentially create duplicate entries like comments or status changes). The problem is therefore with those couple of seconds between validation and the flush to the database.

I think there are two mistakes that we have made:

       - Not relying on built-in locking of the resources (would need to explore what Spring Data offers and how it handles that)

       - Not including those checks for operations other than save
      A potential solution would be to refactor those checks to locks on the database level. We would need to explore what Spring offers and how to best tackle it first. We would want to lock a specific resource only (eq. requisition with id xyz). That means I can still concurrently update 5 different requisitions, but if I try to do it with the same requisition, I wouldn't be able to do so. Another question that needs to be answered is whether we would want optimistic or pessimistic locking. Do we just allow everything and throw an exception if conflict is detected? Or do we not allow concurrent processing of the same resource (waiting for the lock)? The latter may be more problematic on the database level.
      Alternative approach would be to keep those checks manual but refactor them to be resource locks. Submitting requisition xyz would create a lock on xyz and no other resource update would be allowed to proceed for requisition xyz until the submit of xyz is done. This would involve keeping track of the locks (eg. by requisition id) and supporting timeouts (if resource wasn't unlocked after x minutes, the lock is released).
      It would be great to get more opinions/voices on this. Concurrent requests causing duplicate comments/status changes are quite a big issue for Malawi, so having a plan to tackle this is important for us. Why the UI allows users to send concurrent requests (we have vefrified that most cases of concurrent requests are not multiple users operating on the same resource, but a single user sending multiple requests) is another case and we are investigating that in a separate ticket. Nevertheless, the API should be capable of handling the concurrent requests on its own as well, for the reasons mentioned above.

Best regards,

      Sebastian.
    -- You received this message because you are subscribed to the Google Groups "OpenLMIS Dev" group. To unsubscribe from this group and stop receiving emails from it, send an email to . To post to this group, send email to . To view this discussion on the web visit . For more options, visit .


Sebastian Brudziński

    Software Developer / Team Leader


SolDevelo
Sp. z o.o. [LLC] / www.soldevelo.com
Al. Zwycięstwa 96/98, 81-451, Gdynia, Poland
Phone: +48 58 782 45 40 / Fax: +48 58 782 45 41
openlmis-dev@googlegroups.comopenlmis-dev@googlegroups.comsbrudzinski@soldevelo.com
Sent:
**To:**openlmis-dev@googlegroups.com
Subject:
On 22.09.2017 12:05, Łukasz Lewczyński wrote:

Hi again,

I created a ticket in the core space: https://openlmis.atlassian.net/browse/OLMIS-3235

Regards,

Lukasz

Łukasz Lewczyński

                  Software Developer

                  llewczynski@soldevelo.com
          On Mon, Sep 18, 2017 at 12:49 PM, Łukasz Lewczyński
            <llewczynski@soldevelo.com>
          wrote:
              I think the solution to this problem should be on the server side. When I checked how the server will handle concurrent requests I used bash terminal instead of UI. Also we get from time to time informations that during save/submit a requisition on UI adjustments are duplicated and because of that it is impossible to authorize the requisition without changing the form - by removing those duplicates. We captured a requisition that have duplicated adjustments and I noticed that this requisition has duplicates in the **status_changes**                   table so I think this issue is related with concurrent requests.

Łukasz Lewczyński

                          Software Developer

                          llewczynski@soldevelo.com
                    On Mon, Sep 18, 2017 at 8:13 AM, Nikodem Graczewski
                      <ngraczewski@soldevelo.com>
                    wrote:
                        Putting this responsibility on the UI side is kind of doomed to fail in my opinion. We already have a spinner when saving/updating Requisitions and the user can always just press F5 and start again. I agree that the server-side options are more reliable and using one of them should be the road we take.



                          On Friday, September 15, 2017 at 12:29:15 PM UTC+2, Łukasz Lewczyński wrote:

Hi all,

                                I was looking why sometimes on the Malawi production server users see duplicate LMIS form comments and I found out it is possible to send several requests (in the same) to change a requisition status and all of them will be executed properly.
                                In other words, in the database there will be several entries in the *requisition.status_changes*
                                table and if there was draft of comment in the form then there will be several entries in the *requisition.status_messages*
                                table.
                                I think the problem is more general because we don't have any mechanism to control concurrent requests. Basically If a user sends several requests at the same time, with the same data, an endpoint will work normally and all our validations will be omitted because data in the database and in the requests are correct.
                                It was hard for me to find any useful information about how to handle this issue. One solution was about using *[412](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/412)*
                                HTTP error code and *[If-Unmodified-Since](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/If-Unmodified-Since)*
                                header. But in our case it will be still possible to send several requests with the same *                                    If-Unmodified-Since*                                     header but it probably removes problem with double click on the UI. Other solution was to somehow lock a resource that is required by the request. In this situation only one of requests could make changes and another requests will have to wait or they will be rejected.
                                What do you think about that? Do you know any other good solution to avoid this problem?

Regards,

Lukasz

** Łukasz Lewczyński**

                                        Software Developer

                                        llewc...@soldevelo.com
                            **

                                SolDevelo** Sp. z o.o. [LLC] / [
                                www.soldevelo.com](http://www.soldevelo.com)

                              Al. Zwycięstwa 96/98, 81-451, Gdynia, Poland

                              Phone:                                     +48 58 782 45 40 / Fax:
                                +48 58 782 45 41
                        **

                            SolDevelo** Sp. z o.o. [LLC] / [
                            www.soldevelo.com](http://www.soldevelo.com)

                          Al. Zwycięstwa 96/98, 81-451, Gdynia, Poland

                          Phone:                                 +48 58 782 45 40 / Fax:
                            +48 58 782 45 41

                        --

                        You received this message because you are subscribed to the Google Groups "OpenLMIS Dev" group.

                        To unsubscribe from this group and stop receiving emails from it, send an email to
                          openlmis-dev+unsubscribe@googlegroups.com.

                        To post to this group, send email to
                          openlmis-dev@googlegroups.com.

                                                To view this discussion on the web visit [
                        https://groups.google.com/d/msgid/openlmis-dev/a1defb65-73b5-4581-a07b-1401e977bc87%40googlegroups.com](https://groups.google.com/d/msgid/openlmis-dev/a1defb65-73b5-4581-a07b-1401e977bc87%40googlegroups.com?utm_medium=email&utm_source=footer).


                          For more options, visit [
                            https://groups.google.com/d/optout](https://groups.google.com/d/optout).
      **![](http://www.soldevelo.com/sites/default/files/Soldevelo_logo_EPS_CMYK.png)

          SolDevelo** Sp. z o.o. [LLC] / [
          www.soldevelo.com](http://www.soldevelo.com)

        Al. Zwycięstwa 96/98, 81-451, Gdynia, Poland

        Phone: +48 58 782 45 40 / Fax:
          +48 58 782 45 41

      --

      You received this message because you are subscribed to the Google Groups "OpenLMIS Dev" group.

      To unsubscribe from this group and stop receiving emails from it, send an email to
        openlmis-dev+unsubscribe@googlegroups.com.

      To post to this group, send email to
        openlmis-dev@googlegroups.com.

      To view this discussion on the web visit [https://groups.google.com/d/msgid/openlmis-dev/CAAdp53xsgqqom0e7uX8vA81-aLGotpjjSK8VJOQcWKJ0T59AVg%40mail.gmail.com](https://groups.google.com/d/msgid/openlmis-dev/CAAdp53xsgqqom0e7uX8vA81-aLGotpjjSK8VJOQcWKJ0T59AVg%40mail.gmail.com?utm_medium=email&utm_source=footer).

      For more options, visit [
        https://groups.google.com/d/optout](https://groups.google.com/d/optout).


Sebastian Brudziński

                      Software Developer / Team Leader

sbrudzinski@soldevelo.com
**

        SolDevelo** Sp. z o.o. [LLC] / [
        www.soldevelo.com](http://www.soldevelo.com)

      Al. Zwycięstwa 96/98, 81-451, Gdynia, Poland

      Phone: +48 58 782 45 40 / Fax: +48 58 782 45 41

openlmis-dev+unsubscribe@googlegroups.com

      openlmis-dev@googlegroups.com

https://groups.google.com/d/msgid/openlmis-dev/7b9dd105-e1c1-b570-6b10-9e739f20c2a6%40soldevelo.com
https://groups.google.com/d/optout
sbrudzinski@soldevelo.com

Ideally the database should force the data integrity. Locking solutions in services will be hard to scale.

Perhaps we are missing some form of a constraint on our audit entries/comments?

If it’s a bit more complex than that, there are also ways to prevent this on the database level (triggers, check constraints, procedures) that we can consider.

Regards,

Paweł


SolDevelo
Sp. z o.o. [LLC] / www.soldevelo.com
Al. Zwycięstwa 96/98, 81-451, Gdynia, Poland
Phone: +48 58 782 45 40 / Fax: +48 58 782 45 41

···

On Tue, Sep 26, 2017 at 10:58 AM, Sebastian Brudziński sbrudzinski@soldevelo.com wrote:

  Thanks for your input, Nick. I've started a simple Confluence page on the Malawi space that sums up the current issues caused by concurrent requests and possible causes of concurrent requests coming from the same user: [https://openlmis.atlassian.net/wiki/spaces/MW/pages/116031617/Concurrency+issues](https://openlmis.atlassian.net/wiki/spaces/MW/pages/116031617/Concurrency+issues)

Best regards,

  Sebastian.

On 25.09.2017 17:50, Nick Reid wrote:

      Sebastian, thanks for keeping this thread going and getting more input
        You mentioned we are getting errors from MW — **              has anyone started collecting and summarizing these errors?** It would be great to have a             concrete section to look at, improve, and document a "best practice" around.
        I do agree that the ultimate solution is to fix the issue on the backend, because I know we want to support multiple clients (eventually) — that might be written with out any of our knowledge.
          On the UI side, I think we could up our game a little. A goal we need to build metrics around (and then fix) is the number of HTTP requests the UI makes, as that directly relates to a good UX and operating cost for Malawi (and other places we work)
          I have noticed code that doesn't really follow an OO pattern, which would make "locking" objects easier to work with — and I could go "splunking" for specifics, but would much rather have analytics to guide where we do refactors.

– nick –

Nick Reid | nick.reid@villagereach.org

              *                      Software Developer, Information Systems Group*

VillageReach** *** Starting at the Last Mile

             *                   2900 Eastlake Ave. E, Suite 230, Seattle, WA 98102, USA

                              CELL: +1.510.410.0020

                                SKYPE: nickdotreid

              [www.villagereach.org](http://www.villagereach.org/)

From:
openlmis-dev@googlegroups.com
openlmis-dev@googlegroups.com on behalf of Sebastian Brudziński sbrudzinski@soldevelo.com

      **Sent:** Monday, September 25, 2017 5:43:40 AM

      **To:** openlmis-dev@googlegroups.com

      **Subject:** Re: [openlmis-dev] Re: Concurrent requests
      I agree that this should be fixed on the server side. No matter what we do on the UI, it will always be possible to send multiple requests (even because users can have rights to the exact same requisition and they may decide to submit at the same time).
      What Brandon's article is describing is a little different than the problem we are having in Malawi. Moreover, we already have a similar fix implemented manually for the save operation (returning 409 Conflict in case the update dates do not match, which prevents overwriting someone's changes). The problem is when the submit, authorize or other requests are sent at the very same time. Since submit and authorize can be lengthy (several seconds), it is possible to have the validation pass for both of the concurrent requests, before the changes are saved into the database. Simplified workflow would look like:

      (validation including conflict check) -> (other logic / several seconds of processing) -> (save to the database)

      It is therefore possible to have two or more requests pass the validation, then be "stuck" for a few seconds on processing the request and then flush everything to the database (where each request that passed validation would do so and therefore potentially create duplicate entries like comments or status changes). The problem is therefore with those couple of seconds between validation and the flush to the database.

I think there are two mistakes that we have made:

       - Not relying on built-in locking of the resources (would need to explore what Spring Data offers and how it handles that)

       - Not including those checks for operations other than save
      A potential solution would be to refactor those checks to locks on the database level. We would need to explore what Spring offers and how to best tackle it first. We would want to lock a specific resource only (eq. requisition with id xyz). That means I can still concurrently update 5 different requisitions, but if I try to do it with the same requisition, I wouldn't be able to do so. Another question that needs to be answered is whether we would want optimistic or pessimistic locking. Do we just allow everything and throw an exception if conflict is detected? Or do we not allow concurrent processing of the same resource (waiting for the lock)? The latter may be more problematic on the database level.
      Alternative approach would be to keep those checks manual but refactor them to be resource locks. Submitting requisition xyz would create a lock on xyz and no other resource update would be allowed to proceed for requisition xyz until the submit of xyz is done. This would involve keeping track of the locks (eg. by requisition id) and supporting timeouts (if resource wasn't unlocked after x minutes, the lock is released).
      It would be great to get more opinions/voices on this. Concurrent requests causing duplicate comments/status changes are quite a big issue for Malawi, so having a plan to tackle this is important for us. Why the UI allows users to send concurrent requests (we have vefrified that most cases of concurrent requests are not multiple users operating on the same resource, but a single user sending multiple requests) is another case and we are investigating that in a separate ticket. Nevertheless, the API should be capable of handling the concurrent requests on its own as well, for the reasons mentioned above.

Best regards,

      Sebastian.
      On 22.09.2017 12:05, Łukasz Lewczyński wrote:

Hi again,

I created a ticket in the core space: https://openlmis.atlassian.net/browse/OLMIS-3235

Regards,

Lukasz

      **![](http://www.soldevelo.com/sites/default/files/Soldevelo_logo_EPS_CMYK.png)

          SolDevelo** Sp. z o.o. [LLC] / [
          www.soldevelo.com](http://www.soldevelo.com)

        [Al. Zwycięstwa 96](https://maps.google.com/?q=Al.+Zwyci%C4%99stwa+96&entry=gmail&source=g)/98, 81-451, Gdynia, Poland

        Phone: +48 58 782 45 40 / Fax:
          +48 58 782 45 41

      --

      You received this message because you are subscribed to the Google Groups "OpenLMIS Dev" group.

      To unsubscribe from this group and stop receiving emails from it, send an email to
        openlmis-dev+unsubscribe@googlegroups.com.

      To post to this group, send email to
        openlmis-dev@googlegroups.com.

      To view this discussion on the web visit [https://groups.google.com/d/msgid/openlmis-dev/CAAdp53xsgqqom0e7uX8vA81-aLGotpjjSK8VJOQcWKJ0T59AVg%40mail.gmail.com](https://groups.google.com/d/msgid/openlmis-dev/CAAdp53xsgqqom0e7uX8vA81-aLGotpjjSK8VJOQcWKJ0T59AVg%40mail.gmail.com?utm_medium=email&utm_source=footer).

      For more options, visit [
        https://groups.google.com/d/optout](https://groups.google.com/d/optout).


Sebastian Brudziński

                      Software Developer / Team Leader


        sbrudzinski@soldevelo.com
    **![](http://www.soldevelo.com/sites/default/files/Soldevelo_logo_EPS_CMYK.png)

        SolDevelo** Sp. z o.o. [LLC] / [
        www.soldevelo.com](http://www.soldevelo.com)

      [Al. Zwycięstwa 96](https://maps.google.com/?q=Al.+Zwyci%C4%99stwa+96&entry=gmail&source=g)/98, 81-451, Gdynia, Poland

      Phone: +48 58 782 45 40 / Fax: +48 58 782 45 41

    --

    You received this message because you are subscribed to the Google Groups "OpenLMIS Dev" group.

    To unsubscribe from this group and stop receiving emails from it, send an email to openlmis-dev+unsubscribe@googlegroups.com.

    To post to this group, send email to
      openlmis-dev@googlegroups.com.

    To view this discussion on the web visit [https://groups.google.com/d/msgid/openlmis-dev/7b9dd105-e1c1-b570-6b10-9e739f20c2a6%40soldevelo.com](https://groups.google.com/d/msgid/openlmis-dev/7b9dd105-e1c1-b570-6b10-9e739f20c2a6%40soldevelo.com?utm_medium=email&utm_source=footer).

    For more options, visit [https://groups.google.com/d/optout](https://groups.google.com/d/optout).


Sebastian Brudziński

    Software Developer / Team Leader


     sbrudzinski@soldevelo.com


SolDevelo
Sp. z o.o. [LLC] / www.soldevelo.com
Al. Zwycięstwa 96/98, 81-451, Gdynia, Poland
Phone: +48 58 782 45 40 / Fax: +48 58 782 45 41

You received this message because you are subscribed to the Google Groups “OpenLMIS Dev” group.

To unsubscribe from this group and stop receiving emails from it, send an email to openlmis-dev+unsubscribe@googlegroups.com.

To post to this group, send email to openlmis-dev@googlegroups.com.

To view this discussion on the web visit https://groups.google.com/d/msgid/openlmis-dev/72175aea-c7c6-2cf0-3d04-81733faa91e6%40soldevelo.com.

For more options, visit https://groups.google.com/d/optout.

Łukasz Lewczyński

                  Software Developer

                  llewczynski@soldevelo.com

          On Mon, Sep 18, 2017 at 12:49 PM, Łukasz Lewczyński
            <llewczynski@soldevelo.com>
          wrote:
              I think the solution to this problem should be on the server side. When I checked how the server will handle concurrent requests I used bash terminal instead of UI. Also we get from time to time informations that during save/submit a requisition on UI adjustments are duplicated and because of that it is impossible to authorize the requisition without changing the form - by removing those duplicates. We captured a requisition that have duplicated adjustments and I noticed that this requisition has duplicates in the **status_changes**                   table so I think this issue is related with concurrent requests.

Łukasz Lewczyński

                          Software Developer

                          llewczynski@soldevelo.com

                    On Mon, Sep 18, 2017 at 8:13 AM, Nikodem Graczewski
                      <ngraczewski@soldevelo.com>
                    wrote:
                        Putting this responsibility on the UI side is kind of doomed to fail in my opinion. We already have a spinner when saving/updating Requisitions and the user can always just press F5 and start again. I agree that the server-side options are more reliable and using one of them should be the road we take.



                          On Friday, September 15, 2017 at 12:29:15 PM UTC+2, Łukasz Lewczyński wrote:

Hi all,

                                I was looking why sometimes on the Malawi production server users see duplicate LMIS form comments and I found out it is possible to send several requests (in the same) to change a requisition status and all of them will be executed properly.
                                In other words, in the database there will be several entries in the *requisition.status_changes*
                                table and if there was draft of comment in the form then there will be several entries in the *requisition.status_messages*
                                table.
                                I think the problem is more general because we don't have any mechanism to control concurrent requests. Basically If a user sends several requests at the same time, with the same data, an endpoint will work normally and all our validations will be omitted because data in the database and in the requests are correct.
                                It was hard for me to find any useful information about how to handle this issue. One solution was about using *[412](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/412)*
                                HTTP error code and *[If-Unmodified-Since](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/If-Unmodified-Since)*
                                header. But in our case it will be still possible to send several requests with the same *                                    If-Unmodified-Since*                                     header but it probably removes problem with double click on the UI. Other solution was to somehow lock a resource that is required by the request. In this situation only one of requests could make changes and another requests will have to wait or they will be rejected.
                                What do you think about that? Do you know any other good solution to avoid this problem?

Regards,

Lukasz

** Łukasz Lewczyński**

                                        Software Developer

                                        llewc...@soldevelo.com
                            **

                                SolDevelo** Sp. z o.o. [LLC] / [
                                www.soldevelo.com](http://www.soldevelo.com)

                              [Al. Zwycięstwa 96](https://maps.google.com/?q=Al.+Zwyci%C4%99stwa+96&entry=gmail&source=g)                                  /98, 81-451, Gdynia, Poland

                              Phone:                                     +48 58 782 45 40 / Fax:
                                +48 58 782 45 41
                        **

                            SolDevelo** Sp. z o.o. [LLC] / [
                            www.soldevelo.com](http://www.soldevelo.com)

                          [Al. Zwycięstwa 96](https://maps.google.com/?q=Al.+Zwyci%C4%99stwa+96&entry=gmail&source=g)                              /98, 81-451, Gdynia, Poland

                          Phone:                                 +48 58 782 45 40 / Fax:
                            +48 58 782 45 41

                        --

                        You received this message because you are subscribed to the Google Groups "OpenLMIS Dev" group.

                        To unsubscribe from this group and stop receiving emails from it, send an email to
                          openlmis-dev+unsubscribe@googlegroups.com.

                        To post to this group, send email to
                          openlmis-dev@googlegroups.com.

                                                To view this discussion on the web visit [
                        https://groups.google.com/d/msgid/openlmis-dev/a1defb65-73b5-4581-a07b-1401e977bc87%40googlegroups.com](https://groups.google.com/d/msgid/openlmis-dev/a1defb65-73b5-4581-a07b-1401e977bc87%40googlegroups.com?utm_medium=email&utm_source=footer).


                          For more options, visit [
                            https://groups.google.com/d/optout](https://groups.google.com/d/optout).

Paweł Gesek

    Technical Project Manager

     pgesek@soldevelo.com / +48 690 020 875

Finding a unique constraint for comments / audit entries may be difficult as we should allow identical comments and requisitions reaching the same status (eg. after being rejected). The timestamps usually won’t be the same either.

  While we need the database to force its integrity, I don't believe this is an ultimate solution to the concurrency issues. Saving a requisition may serve as an example. It doesn't produce a new resource and so simply enforcing it's unique doesn't give us much here.

  What kind of triggers or procedures to prevent concurrency do you have in mind exactly?

Regards,

  Sebastian.
···

On 26.09.2017 11:51, Paweł Gesek wrote:

          Ideally the database should force the data integrity. Locking solutions in services will be hard to scale.
          Perhaps we are missing some form of a constraint on our audit entries/comments?
        If it's a bit more complex than that, there are also ways to prevent this on the database level (triggers, check constraints, procedures) that we can consider.

Regards,

Paweł

      On Tue, Sep 26, 2017 at 10:58 AM, Sebastian Brudziński <sbrudzinski@soldevelo.com>
      wrote:
            Thanks for your input, Nick. I've started a simple Confluence page on the Malawi space that sums up the current issues caused by concurrent requests and possible causes of concurrent requests coming from the same user: [https://openlmis.atlassian.net/wiki/spaces/MW/pages/116031617/Concurrency+issues](https://openlmis.atlassian.net/wiki/spaces/MW/pages/116031617/Concurrency+issues)

Best regards,

            Sebastian.
                On 25.09.2017 17:50, Nick Reid wrote:
                    Sebastian, thanks for keeping this thread going and getting more input
                      You mentioned we are getting errors from MW —  **                            has anyone started collecting and summarizing these errors?** It would be great to have a                           concrete section to look at, improve, and document a "best practice                          " around.
                      I do agree that the ultimate solution is to fix the issue on the backend, because I know we want to support multiple clients (eventually) — that might be written with out any of our knowledge.
                        On the UI side, I think we could up our game a little. A goal we need to build metrics around (and then fix) is the number of HTTP requests the UI makes, as that directly relates to a good UX and operating cost for Malawi (and other places we work)
                        I have noticed code that doesn't really follow an OO pattern, which would make "locking" objects easier to work with — and I could go "splunking" for specifics, but would much rather have analytics to guide where we do refactors.

– nick –

** Nick Reid** | nick.reid@villagereach.org

                            *                                    Software Developer, Information Systems Group*

VillageReach** *** Starting at the Last Mile

                           *                                 2900 Eastlake Ave. E, Suite 230, Seattle, WA 98102, USA

                          CELL: +1.510.410.0020

                                                            SKYPE: nickdotreid

                            [www.villagereach.org](http://www.villagereach.org/)

From:
openlmis-dev@googlegroups.com
openlmis-dev@googlegroups.com
on behalf of Sebastian Brudziński sbrudzinski@soldevelo.com

                    **Sent:** Monday, September 25, 2017 5:43:40 AM

                    **To:** openlmis-dev@googlegroups.com

                    **Subject:** Re: [openlmis-dev] Re: Concurrent requests
                    I agree that this should be fixed on the server side. No matter what we do on the UI, it will always be possible to send multiple requests (even because users can have rights to the exact same requisition and they may decide to submit at the same time).
                    What Brandon's article is describing is a little different than the problem we are having in Malawi. Moreover, we already have a similar fix implemented manually for the save operation (returning 409 Conflict in case the update dates do not match, which prevents overwriting someone's changes). The problem is when the submit, authorize or other requests are sent at the very same time. Since submit and authorize can be lengthy (several seconds), it is possible to have the validation pass for both of the concurrent requests, before the changes are saved into the database. Simplified workflow would look like:

                    (validation including conflict check) -> (other logic / several seconds of processing) -> (save to the database)

                    It is therefore possible to have two or more requests pass the validation, then be "stuck" for a few seconds on processing the request and then flush everything to the database (where each request that passed validation would do so and therefore potentially create duplicate entries like comments or status changes). The problem is therefore with those couple of seconds between validation and the flush to the database.
                    I think there are two mistakes that we have made:

                     - Not relying on built-in locking of the resources (would need to explore what Spring Data offers and how it handles that)

                     - Not including those checks for operations other than save
                    A potential solution would be to refactor those checks to locks on the database level. We would need to explore what Spring offers and how to best tackle it first. We would want to lock a specific resource only (eq. requisition with id xyz). That means I can still concurrently update 5 different requisitions, but if I try to do it with the same requisition, I wouldn't be able to do so. Another question that needs to be answered is whether we would want optimistic or pessimistic locking. Do we just allow everything and throw an exception if conflict is detected? Or do we not allow concurrent processing of the same resource (waiting for the lock)? The latter may be more problematic on the database level.
                    Alternative approach would be to keep those checks manual but refactor them to be resource locks. Submitting requisition xyz would create a lock on xyz and no other resource update would be allowed to proceed for requisition xyz until the submit of xyz is done. This would involve keeping track of the locks (eg. by requisition id) and supporting timeouts (if resource wasn't unlocked after x minutes, the lock is released).
                    It would be great to get more opinions/voices on this. Concurrent requests causing duplicate comments/status changes are quite a big issue for Malawi, so having a plan to tackle this is important for us. Why the UI allows users to send concurrent requests (we have vefrified that most cases of concurrent requests are not multiple users operating on the same resource, but a single user sending multiple requests) is another case and we are investigating that in a separate ticket. Nevertheless, the API should be capable of handling the concurrent requests on its own as well, for the reasons mentioned above.

Best regards,

                    Sebastian.
                    On 22.09.2017 12:05, Łukasz Lewczyński wrote:

Hi again,

I created a ticket in the core space: https://openlmis.atlassian.net/browse/OLMIS-3235

Regards,

Lukasz

Łukasz Lewczyński

                                Software Developer

                                llewczynski@soldevelo.com
                        On Mon, Sep 18, 2017 at 12:49 PM, Łukasz Lewczyński  <llewczynski@soldevelo.com>
                        wrote:
                            I think the solution to this problem should be on the server side. When I checked how the server will handle concurrent requests I used bash terminal instead of UI. Also we get from time to time informations that during save/submit a requisition on UI adjustments are duplicated and because of that it is impossible to authorize the requisition without changing the form - by removing those duplicates. We captured a requisition that have duplicated adjustments and I noticed that this requisition has duplicates in the **status_changes**                                 table so I think this issue is related with concurrent requests.

** Łukasz Lewczyński**

                                        Software Developer

                                        llewczynski@soldevelo.com
                                  On Mon, Sep 18, 2017 at 8:13 AM, Nikodem Graczewski  <ngraczewski@soldevelo.com>
                                  wrote:
                                      Putting this responsibility on the UI side is kind of doomed to fail in my opinion. We already have a spinner when saving/updating Requisitions and the user can always just press F5 and start again. I agree that the server-side options are more reliable and using one of them should be the road we take.



                                        On Friday, September 15, 2017 at 12:29:15 PM UTC+2, Łukasz Lewczyński wrote:

Hi all,

                                              I was looking why sometimes on the Malawi production server users see duplicate LMIS form comments and I found out it is possible to send several requests (in the same) to change a requisition status and all of them will be executed properly.
                                              In other words, in the database there will be several entries in the *requisition.status_changes*
                                              table and if there was draft of comment in the form then there will be several entries in the *requisition.status_messages*
                                              table.
                                              I think the problem is more general because we don't have any mechanism to control concurrent requests. Basically If a user sends several requests at the same time, with the same data, an endpoint will work normally and all our validations will be omitted because data in the database and in the requests are correct.
                                              It was hard for me to find any useful information about how to handle this issue. One solution was about using *[412](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/412)*
                                              HTTP error code and *[If-Unmodified-Since](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/If-Unmodified-Since)*
                                              header. But in our case it will be still possible to send several requests with the same *                                                  If-Unmodified-Since*                                                   header but it probably removes problem with double click on the UI. Other solution was to somehow lock a resource that is required by the request. In this situation only one of requests could make changes and another requests will have to wait or they will be rejected.
                                              What do you think about that? Do you know any other good solution to avoid this problem?

Regards,

Lukasz

** Łukasz Lewczyński**

                                                      Software Developer

                                                      llewc...@soldevelo.com
                                          **

                                              SolDevelo** Sp. z o.o. [LLC] / [
                                              www.soldevelo.com](http://www.soldevelo.com)

                                            [                                                  Al. Zwycięstwa 96](https://maps.google.com/?q=Al.+Zwyci%C4%99stwa+96&entry=gmail&source=g)                                                /98, 81-451, Gdynia, Poland

                                            Phone:                                                   +48 58 782 45 40 / Fax:
                                              +48 58 782 45 41
                                      **

                                          SolDevelo** Sp. z o.o. [LLC] / [
                                          www.soldevelo.com](http://www.soldevelo.com)

                                        [                                              Al. Zwycięstwa 96](https://maps.google.com/?q=Al.+Zwyci%C4%99stwa+96&entry=gmail&source=g)                                            /98, 81-451, Gdynia, Poland

                                        Phone:                                               +48 58 782 45 40 / Fax:
                                          +48 58 782 45 41

                                      --

                                      You received this message because you are subscribed to the Google Groups "OpenLMIS Dev" group.

                                      To unsubscribe from this group and stop receiving emails from it, send an email to
                                        openlmis-dev+unsubscribe@googlegroups.com.

                                      To post to this group, send email to
                                        openlmis-dev@googlegroups.com.

                                                                            To view this discussion on the web visit [
                                      https://groups.google.com/d/msgid/openlmis-dev/a1defb65-73b5-4581-a07b-1401e977bc87%40googlegroups.com](https://groups.google.com/d/msgid/openlmis-dev/a1defb65-73b5-4581-a07b-1401e977bc87%40googlegroups.com?utm_medium=email&utm_source=footer).


                                        For more options, visit [
                                          https://groups.google.com/d/optout](https://groups.google.com/d/optout).
                    **![](http://www.soldevelo.com/sites/default/files/Soldevelo_logo_EPS_CMYK.png)

                        SolDevelo** Sp. z o.o. [LLC] / [ www.soldevelo.com](http://www.soldevelo.com)

                      [                            Al. Zwycięstwa 96](https://maps.google.com/?q=Al.+Zwyci%C4%99stwa+96&entry=gmail&source=g)/98, 81-451, Gdynia, Poland

                      Phone:                             +48 58 782 45 40 / Fax:
                        +48 58 782 45 41

                    --

                    You received this message because you are subscribed to the Google Groups "OpenLMIS Dev" group.

                    To unsubscribe from this group and stop receiving emails from it, send an email to  openlmis-dev+unsubscribe@googlegroups.com.

                    To post to this group, send email to  openlmis-dev@googlegroups.com.

                    To view this discussion on the web visit [https://groups.google.com/d/msgid/openlmis-dev/CAAdp53xsgqqom0e7uX8vA81-aLGotpjjSK8VJOQcWKJ0T59AVg%40mail.gmail.com](https://groups.google.com/d/msgid/openlmis-dev/CAAdp53xsgqqom0e7uX8vA81-aLGotpjjSK8VJOQcWKJ0T59AVg%40mail.gmail.com?utm_medium=email&utm_source=footer).

                    For more options, visit [ https://groups.google.com/d/optout](https://groups.google.com/d/optout).
                    --
                        Sebastian Brudziński

                                                  Software Developer / Team Leader

                      sbrudzinski@soldevelo.com
                  **![](http://www.soldevelo.com/sites/default/files/Soldevelo_logo_EPS_CMYK.png)

                      SolDevelo** Sp. z o.o. [LLC] / [ www.soldevelo.com](http://www.soldevelo.com)

                    [                          Al. Zwycięstwa 96](https://maps.google.com/?q=Al.+Zwyci%C4%99stwa+96&entry=gmail&source=g)/98, 81-451, Gdynia, Poland

                    Phone:                           +48 58 782 45 40 / Fax:                           +48 58 782 45 41

                  --

                  You received this message because you are subscribed to the Google Groups "OpenLMIS Dev" group.

                  To unsubscribe from this group and stop receiving emails from it, send an email to openlmis-dev+unsubscribe@googlegroups.com.

                  To post to this group, send email to  openlmis-dev@googlegroups.com.

                  To view this discussion on the web visit [https://groups.google.com/d/msgid/openlmis-dev/7b9dd105-e1c1-b570-6b10-9e739f20c2a6%40soldevelo.com](https://groups.google.com/d/msgid/openlmis-dev/7b9dd105-e1c1-b570-6b10-9e739f20c2a6%40soldevelo.com?utm_medium=email&utm_source=footer).

                  For more options, visit [https://groups.google.com/d/optout](https://groups.google.com/d/optout).


Sebastian Brudziński

                                          Software Developer / Team Leader

                   sbrudzinski@soldevelo.com
            **![](http://www.soldevelo.com/sites/default/files/Soldevelo_logo_EPS_CMYK.png)

                SolDevelo** Sp. z o.o. [LLC] / [www.soldevelo.com](http://www.soldevelo.com)

              [                    Al. Zwycięstwa 96](https://maps.google.com/?q=Al.+Zwyci%C4%99stwa+96&entry=gmail&source=g)/98, 81-451, Gdynia, Poland

              Phone: +48 58 782 45 40
              / Fax: +48 58 782 45 41

            --

            You received this message because you are subscribed to the Google Groups "OpenLMIS Dev" group.

            To unsubscribe from this group and stop receiving emails from it, send an email to openlmis-dev+unsubscribe@googlegroups.com.

            To post to this group, send email to openlmis-dev@googlegroups.com.

To view this discussion on the web visit https://groups.google.com/d/msgid/openlmis-dev/72175aea-c7c6-2cf0-3d04-81733faa91e6%40soldevelo.com.

            For more options, visit [https://groups.google.com/d/optout](https://groups.google.com/d/optout).
    --
                          Paweł Gesek

                                                     Technical Project Manager

                         pgesek@soldevelo.com
                          /                               +48 690 020 875
  **![](http://www.soldevelo.com/sites/default/files/Soldevelo_logo_EPS_CMYK.png)

      SolDevelo** Sp. z o.o. [LLC] / [www.soldevelo.com](http://www.soldevelo.com)

    Al. Zwycięstwa 96/98, 81-451, Gdynia, Poland

    Phone: +48 58 782 45 40 / Fax: +48 58 782 45 41


Sebastian Brudziński

    Software Developer / Team Leader


SolDevelo
Sp. z o.o. [LLC] / www.soldevelo.com
Al. Zwycięstwa 96/98, 81-451, Gdynia, Poland
Phone: +48 58 782 45 40 / Fax: +48 58 782 45 41
sbrudzinski@soldevelo.com

Speaking to the browser side, I think incorporating a separation between the object being saved, and the resource/service doing the saving would be quick to prevent this from happening going forward

Here is a
code sample with what we would want to adopt
– you will notice that the user object knows if it has a request in progress, and instead of making a new request – it passes back the promise for the original request.

I was going to implement this into a couple of referencedata services today – but we will need to figure out how to prioritize this work, since it makes no sense to go backwards and update everything right now

– nick –

···

Nick Reid | nick.reid@villagereach.org

Software Developer, Information Systems Group

VillageReach** *** Starting at the Last Mile
*2900 Eastlake Ave. E, Suite 230, Seattle, WA 98102, USA

CELL: +1.510.410.0020

SKYPE: nickdotreid

www.villagereach.org


From: openlmis-dev@googlegroups.com openlmis-dev@googlegroups.com on behalf of Brandon Bowersox-Johnson brandon.bowersox-johnson@villagereach.org

Sent: Friday, September 15, 2017 12:41:24 PM

To: Łukasz Lewczyński; OpenLMIS Dev

Subject: Re: [openlmis-dev] Concurrent requests

I don’t think OpenLMIS has established a pattern for this yet.

Browser-side options could involve putting in logic to prevent or handle the AngularJS app making multiple concurrent requests to the same API in certain cases like this. For example, when the app is saving/updating a Requisition, perhaps we need a loading spinner on screen so we prevent the user from clicking any button a second time and causing a concurrent request. That may be the easiest option. Similar approaches in the AngularJS service layer could use a locking mechanism or queue mechanism.

Server-side options are more robust/reliable, especially in situations where we have browsers with inconsistent internet connectivity. This could involve a token that the server checks as well as the If-Unmodified-Since header. Here is a good article about REST Best Practices for Managing Concurrent Updates:
https://blog.4psa.com/rest-best-practices-managing-concurrent-updates/
. It includes the solution Łukasz is describing.

-Brandon

From: openlmis-dev@googlegroups.com on behalf of Łukasz Lewczyński llewczynski@soldevelo.com

Date: Friday, September 15, 2017 at 3:28 AM

To: OpenLMIS Dev openlmis-dev@googlegroups.com

Subject: [openlmis-dev] Concurrent requests

Hi all,

I was looking why sometimes on the Malawi production server users see duplicate LMIS form comments and I found out it is possible to send several requests (in the same) to change a requisition status and all of them will be executed properly.

In other words, in the database there will be several entries in the requisition.status_changes table and if there was draft of comment in the form then there will be several entries in the requisition.status_messages table.

I think the problem is more general because we don’t have any mechanism to control concurrent requests. Basically If a user sends several requests at the same time, with the same data, an endpoint will work normally and all our validations will be omitted because data in the database and in the requests are correct.

It was hard for me to find any useful information about how to handle this issue. One solution was about using 412 HTTP error code and If-Unmodified-Since header. But in our case it will be still possible to send several requests with the same If-Unmodified-Since
header but it probably removes problem with double click on the UI. Other solution was to somehow lock a resource that is required by the request. In this situation only one of requests could make changes and another requests will have to wait or they will be rejected.

What do you think about that? Do you know any other good solution to avoid this problem?

Regards,

Lukasz

Łukasz Lewczyński

Software Developer

llewczynski@soldevelo.com

**

SolDevelo** Sp. z o.o. [LLC] /
www.soldevelo.com

Al. Zwycięstwa 96/98, 81-451, Gdynia, Poland

Phone: +48 58 782 45 40 / Fax: +48 58 782 45 41

You received this message because you are subscribed to the Google Groups “OpenLMIS Dev” group.

To unsubscribe from this group and stop receiving emails from it, send an email to openlmis-dev+unsubscribe@googlegroups.com.

To post to this group, send email to
openlmis-dev@googlegroups.com.

To view this discussion on the web visit
https://groups.google.com/d/msgid/openlmis-dev/CAAdp53yBV3Jn%2Bcvv%3DUSd54cR6Fv%3D3qJUOc9M1HmNtvU%3DmMLqMg%40mail.gmail.com
.

For more options, visit https://groups.google.com/d/optout.

You received this message because you are subscribed to the Google Groups “OpenLMIS Dev” group.

To unsubscribe from this group and stop receiving emails from it, send an email to openlmis-dev+unsubscribe@googlegroups.com.

To post to this group, send email to
openlmis-dev@googlegroups.com.

To view this discussion on the web visit
https://groups.google.com/d/msgid/openlmis-dev/04D68890-E73B-4244-B450-CE72D13BF1E0%40villagereach.org
.

For more options, visit https://groups.google.com/d/optout.

Hi,

I think the solution proposed by Nick could work, but I still have a little concern (and I think we should solve this issue on the back-end side) - what would happen if we just refresh the page and click the button again? If will send the second request in this case.

Best regards,
Nikodem

···

On Monday, October 2, 2017 at 8:50:45 PM UTC+2, Nick Reid wrote:

Speaking to the browser side, I think incorporating a separation between the object being saved, and the resource/service doing the saving would be quick to prevent this from happening going forward

Here is a
code sample with what we would want to adopt
– you will notice that the user object knows if it has a request in progress, and instead of making a new request – it passes back the promise for the original request.

I was going to implement this into a couple of referencedata services today – but we will need to figure out how to prioritize this work, since it makes no sense to go backwards and update everything right now

– nick –

Nick Reid | nick...@villagereach.org

Software Developer, Information Systems Group

VillageReach** *** Starting at the Last Mile
*2900 Eastlake Ave. E, Suite 230, Seattle, WA 98102, USA

CELL: +1.510.410.0020

SKYPE: nickdotreid

www.villagereach.org


From: openlm...@googlegroups.com openlm...@googlegroups.com on behalf of Brandon Bowersox-Johnson brandon.bowe...@villagereach.org

Sent: Friday, September 15, 2017 12:41:24 PM

To: Łukasz Lewczyński; OpenLMIS Dev

Subject: Re: [openlmis-dev] Concurrent requests

I don’t think OpenLMIS has established a pattern for this yet.

Browser-side options could involve putting in logic to prevent or handle the AngularJS app making multiple concurrent requests to the same API in certain cases like this. For example, when the app is saving/updating a Requisition, perhaps we need a loading spinner on screen so we prevent the user from clicking any button a second time and causing a concurrent request. That may be the easiest option. Similar approaches in the AngularJS service layer could use a locking mechanism or queue mechanism.

Server-side options are more robust/reliable, especially in situations where we have browsers with inconsistent internet connectivity. This could involve a token that the server checks as well as the If-Unmodified-Since header. Here is a good article about REST Best Practices for Managing Concurrent Updates:
https://blog.4psa.com/rest-best-practices-managing-concurrent-updates/
. It includes the solution Łukasz is describing.

-Brandon

From: openlm...@googlegroups.com on behalf of Łukasz Lewczyński llewc...@soldevelo.com

Date: Friday, September 15, 2017 at 3:28 AM

To: OpenLMIS Dev openlm...@googlegroups.com

Subject: [openlmis-dev] Concurrent requests

Hi all,

I was looking why sometimes on the Malawi production server users see duplicate LMIS form comments and I found out it is possible to send several requests (in the same) to change a requisition status and all of them will be executed properly.

In other words, in the database there will be several entries in the requisition.status_changes table and if there was draft of comment in the form then there will be several entries in the requisition.status_messages table.

I think the problem is more general because we don’t have any mechanism to control concurrent requests. Basically If a user sends several requests at the same time, with the same data, an endpoint will work normally and all our validations will be omitted because data in the database and in the requests are correct.

It was hard for me to find any useful information about how to handle this issue. One solution was about using 412 HTTP error code and If-Unmodified-Since header. But in our case it will be still possible to send several requests with the same If-Unmodified-Since
header but it probably removes problem with double click on the UI. Other solution was to somehow lock a resource that is required by the request. In this situation only one of requests could make changes and another requests will have to wait or they will be rejected.

What do you think about that? Do you know any other good solution to avoid this problem?

Regards,

Lukasz

Łukasz Lewczyński

Software Developer

llewc...@soldevelo.com

**

SolDevelo** Sp. z o.o. [LLC] /
www.soldevelo.com

Al. Zwycięstwa 96/98, 81-451, Gdynia, Poland

Phone: +48 58 782 45 40 / Fax: +48 58 782 45 41

You received this message because you are subscribed to the Google Groups “OpenLMIS Dev” group.

To unsubscribe from this group and stop receiving emails from it, send an email to openlmis-dev...@googlegroups.com.

To post to this group, send email to
openl...@googlegroups.com.

To view this discussion on the web visit
https://groups.google.com/d/msgid/openlmis-dev/CAAdp53yBV3Jn%2Bcvv%3DUSd54cR6Fv%3D3qJUOc9M1HmNtvU%3DmMLqMg%40mail.gmail.com
.

For more options, visit https://groups.google.com/d/optout.

You received this message because you are subscribed to the Google Groups “OpenLMIS Dev” group.

To unsubscribe from this group and stop receiving emails from it, send an email to openlmis-dev...@googlegroups.com.

To post to this group, send email to
openl...@googlegroups.com.

To view this discussion on the web visit
https://groups.google.com/d/msgid/openlmis-dev/04D68890-E73B-4244-B450-CE72D13BF1E0%40villagereach.org
.

For more options, visit https://groups.google.com/d/optout.