Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: out bound push fails while writing to info doc #9855

Open
wants to merge 17 commits into
base: master
Choose a base branch
from

Conversation

jonathanbataire
Copy link
Contributor

@jonathanbataire jonathanbataire commented Mar 24, 2025

Description

When two out bound pushes running against the same document (same doc id) there is an uncaught error as shown below while writing to the sentinel info doc that leads to duplication in the push.

while looping thru the outbound keys eg push-1 and push-2,
push-1 will successfully write the info doc for the report
when it get to push-2 it attempts to put the info doc but runs into a conflict error
This will lead to creation of an unnecessary task:outbound which leads to push-2 being pushed again.

Fixes #9854

{
  error: 'conflict',
  reason: 'Document update conflict.',
  status: 409,
  name: 'conflict',
  message: 'Document update conflict.',
  stack: 'Error\n' +
    '    at Object.generateErrorFromResponse (/home/jonathan/Downloads/cht-core-4.9.0/sentinel/node_modules/pouchdb-errors/lib/index.js:104:18)\n' +
    '    at /home/jonathan/Downloads/cht-core-4.9.0/sentinel/node_modules/pouchdb-adapter-http/lib/index.js:254:33\n' +
    '    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)',
  docId: 'c4628ff1-e3ac-4a2c-a499-f2f5fe8d81b6-info'
}

Code review checklist

  • UI/UX backwards compatible: Test it works for the new design (enabled by default). And test it works in the old design, enable can_view_old_navigation permission to see the old design. Test it has appropriate design for RTL languages.
  • Readable: Concise, well named, follows the style guide, documented if necessary.
  • Documented: Configuration and user documentation on cht-docs
  • Tested: Unit and/or e2e where appropriate
  • Internationalised: All user facing text
  • Backwards compatible: Works with existing data and configuration or includes a migration. Any breaking changes documented in the release notes.

License

The software is provided under AGPL-3.0. Contributions to this project are accepted under the same license.

@jonathanbataire jonathanbataire changed the title Out bound push fails while writing to info doc fix: Out bound push fails while writing to info doc Mar 25, 2025
@jonathanbataire jonathanbataire changed the title fix: Out bound push fails while writing to info doc fix: out bound push fails while writing to info doc Mar 25, 2025
@dianabarsan
Copy link
Member

@jonathanbataire I'm happy to review this when it's ready! Please let me know :)

@jonathanbataire
Copy link
Contributor Author

ready for review @dianabarsan

@dianabarsan dianabarsan self-requested a review March 26, 2025 15:59
Copy link
Member

@dianabarsan dianabarsan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Really appreciate you resolving on this! I left one suggestion inline.

@@ -48,8 +48,17 @@ const markForOutbound = (change) => {
.then(sent => {
if (sent) {
// Successfully sent, outbound.send wrote to the infodoc

return db.sentinel.put(change.info);
return db.sentinel.get(change.info._id)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this conflict resolution is a bit verbose to be here, and it doesn't treat an eventual conflict directly - in your error, the status that the PUT request got was 409, and here you're only resolving for 404s (not found).

I think the best solution here is to use the infodoc shared lib, which already has infodoc conflct resolution built in and already has a saveCompletedTasks function (https://github.com/medic/cht-core/blob/master/shared-libs/infodoc/src/infodoc.js#L285). This function doesn't receive parameters now, but that can be changed.

Please let me know what you think!

@@ -133,6 +133,78 @@ describe('mark_for_outbound', () => {
});
});

it('correctly creates and sends multiple outbound requests for the same report immediately', () => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Love this test!

@@ -156,7 +156,7 @@ const saveTransitions = change => {
};

const saveCompletedTasks = (id, infodoc) => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you need to add a parameter here, to save correct completed_tasks, instead of just completing all tasks.

@@ -155,8 +155,8 @@ const saveTransitions = change => {
return saveProperty(change.id, change.info, 'transitions', {});
};

const saveCompletedTasks = (id, infodoc) => {
return saveProperty(id, infodoc, 'completed_tasks', {});
const saveCompletedTasks = (id, infodoc, completedTasks = []) => {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

like this?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh... now that I check the implementation, I see that the property value was taken from the infodoc that was already passed, my bad!

Copy link
Member

@dianabarsan dianabarsan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome!

@@ -155,8 +155,8 @@ const saveTransitions = change => {
return saveProperty(change.id, change.info, 'transitions', {});
};

const saveCompletedTasks = (id, infodoc) => {
return saveProperty(id, infodoc, 'completed_tasks', {});
const saveCompletedTasks = (id, infodoc, completedTasks = []) => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh... now that I check the implementation, I see that the property value was taken from the infodoc that was already passed, my bad!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Bug: Duplication in outbound push
2 participants