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
--
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
openlm...@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 openlm...@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.
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.
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 openlm...@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
sbrud...@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...@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
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
Best regards,
Sebastian.
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
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
From: openlm...@googlegroups.com <openlmis-dev@googlegroups.com> on behalf of Sebastian Brudziński <sbrud...@soldevelo.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
sbrud...@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 openlm...@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.
--
Sebastian Brudziński
Software Developer / Team Leader
sbrud...@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 openlm...@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.
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.
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
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.