-
-
Notifications
You must be signed in to change notification settings - Fork 209
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
Enables running transitions synchronously #5476
Conversation
); | ||
return callback(); | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I moved the call to canRun
from the applyTransitions
map function.
The reason was to test canRun
over the document after it has been updated by previous transitions.
As an example, it enables the possibility of running registration
over a fresh doc: currently registration
requires either the form to be public or doc.contact
to exist, while update_clinics
is responsible for creating doc.contact
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a good idea.
We should also formalise transition run order to make this less fragile.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We already formalize that, since 2.15
https://github.com/medic/medic/blame/d7ec779eac1806a26cd6f546970b9319648a3cc7/shared-libs/transitions/src/transitions/index.js#L13
}); | ||
}); | ||
async.series(operations, (err, results) => { | ||
return err ? reject(err) : resolve(results); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just thought about this.. do you guys think I should delete the just-created info-docs for docs that are just echo-ed back?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is fine for now - deleting a doc is probably worse for performance than just leaving it there forever...
I think eventually we want the transitions function to return an array of docs to save, so all the docs are saved once all transitions have executed, but that would need careful consideration...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would very much agree with the transaction-like approach.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess I don't understand this part of the codebase anymore: why would you want to delete them? Even if the transitions don't touch the document we still want an infodoc for replication dates and stuff right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the transition returns "not changed" or has an error, I return the untouched version of the document that I received, which will not even have an _id
property.
The reason is that some transitions add errors on the docs, but still return as "not changed".
The doc will receive another _id
upon save, so the info-doc we just created is useless.
I guess I could only copy the _id
property over in this case, so it wouldn't be useless?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might as well right? The upside I presume being that when these docs are written Sentinel won't re-run those transactions over them. And the main downside is that we don't generate "smart" UUIDs that CouchDB likes, but honestly we don't do that for 90% of our data right now anyway (cause of PouchDB), and if we really wanted to we could replace the uuid generation used here with a cache that sources UUIDs from CouchDB if we considered it an issue.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sentinel would run all transitions over that doc either way.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a shame. Maybe not in the future though (like I feel like we should be able to take advantage of this even if we aren't now)!
Also, it's probably better for Impact to not have orphaned info docs. I may not matter depending on their impl, but it's a bug waiting to happen in any case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This thread is outdated because docs are saved in series within the library immediately after running transitions, same as old sentinel.
I guess this is it.. new and improved along with as much git history. Could you please have a look, @garethbowen & @SCdF . Thank you! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wow. Awesome!
A few questions and comments about minor details but the general approach is great.
}); | ||
}); | ||
async.series(operations, (err, results) => { | ||
return err ? reject(err) : resolve(results); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is fine for now - deleting a doc is probably worse for performance than just leaving it there forever...
I think eventually we want the transitions function to return an array of docs to save, so all the docs are saved once all transitions have executed, but that would need careful consideration...
@@ -262,11 +262,11 @@ describe('registration transition', () => { | |||
const checkAutoResponse = () => { | |||
const taskElement = element(by.css('#reports-content .details > ul')); | |||
expect(taskElement.element(by.css('.task-list > li:nth-child(1) > ul > li')).getText()).toBe('Thank you '+ CAROL.name +' for registering Siobhan'); | |||
expect(taskElement.element(by.css('.task-list > li:nth-child(1) .task-state .state.pending')).isDisplayed()).toBeTruthy(); | |||
expect(taskElement.element(by.css('.task-list > li:nth-child(1) .task-state .state.forwarded-to-gateway')).isDisplayed()).toBeTruthy(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
WOOHOO!
@@ -2,7 +2,7 @@ const utils = require('../../../utils'), | |||
sentinelUtils = require('../utils'), | |||
uuid = require('uuid'); | |||
|
|||
describe('death_reporting', () => { | |||
describe('generate_patient_id_on_people', () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hah
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mammoth!
Various comments, but the general gist is looking awesome! I'm excited for this distinction to open up opportunities to improve Sentinel's performance as well as our SMS response times
sentinel/src/transitions.js
Outdated
} | ||
|
||
if (!changed) { | ||
return updateMetadata(change, callback); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not your code I imagine, but it's weird that we call declare a call to updateMetadata twice even though we do it regardless (either we do it and return, or we do something else then do it).
return; | ||
} | ||
let changes; | ||
const clonedDocs = JSON.parse(JSON.stringify(docs)), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I haven't kept up and I'm cool if it is, but is this the state of the art for JSON cloning these days, perf-wise?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah every time I check this is what it comes back to. Last time I checked was a couple of months ago.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess it depends on what you're cloning.
As a result of Stefan's comment, I tried a couple of reliable alternatives : http://jsben.ch/SJghM
Do you guys think lodash.cloneDeep would be worth including? It can be required as a standalone.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mine's consistently slower. Strange. Different browser versions maybe?
I wonder how angular copy is doing it?
I don't think it's worth switching to lodash but it may be worth ripping out the angular version and using that throughout in a separate PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was planning on looking at the Angular version tomorrow, it got me curious.
The lodash seems to be the complete solution to deep copy and tries to treat all possible cases, while angular's solution is clearly stated to be riddled with caveats, albeit faster.
} | ||
let changes; | ||
const clonedDocs = JSON.parse(JSON.stringify(docs)), | ||
idsByIdx = []; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might as well
idsByIdx = []; | |
idsByIdx = new Array(clonedDocs.length); |
// - hydrate the docs and generate info docs | ||
// - run loaded transitions over all docs | ||
// - returns docs, either updated or their original version | ||
const processDocs = docs => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can processDocs
wrap and so re-use processChange
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess we could, but then everything would be done one doc at a time:
- fetching lineage
- creating the infodoc
Perf wise, it would be much worse than bulking them.
}); | ||
}); | ||
async.series(operations, (err, results) => { | ||
return err ? reject(err) : resolve(results); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess I don't understand this part of the codebase anymore: why would you want to delete them? Even if the transitions don't touch the document we still want an infodoc for replication dates and stuff right?
); | ||
return callback(); | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a good idea.
We should also formalise transition run order to make this less fragile.
@@ -1,7 +1,6 @@ | |||
// TODO: this doesn't need to exist. We can just work this out dynamically when | |||
// gateway queries, it's not slow or complicated. | |||
const async = require('async'), | |||
_ = require('underscore'), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the reasoning behind moving the schedule code into the transitions shared lib? AFAICT it's only used by sentinel.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's funny you should ask!
It's because someone wrote this two years ago:
https://github.com/medic/medic/blame/8c25c15e6fec268b272d5fb9b361bd119864a4e6/sentinel/src/schedule/due_tasks.js#L1
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@dianabarsan Could you please raise an issue so this actually gets fixed? I'm happy to do it but you're the sentinel expert now!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sure!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome.
I haven't gone through each line again but reviewed the new commits and it looks good to me. If you think it's ready for AT go for it!
Rolls back due_tasks fix Changes how logger and db are inited Changes "sync"/"async" transition definitions to be hardcoded Three transitions are only async: muting, update_notifications and mutli_report_alerts
+ adds some more unit tests.
This reverts commit ffe2c19
+ adds some more unit tests.
839e9ce
to
95e9099
Compare
I've rebased to resolve a conflict. Also published the shared-lib under the correct name and updated the dependencies in the apps. Had to do some minor updates to get a couple of unit tests passing. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM.
Pulls sentinel transitions out into a shared library Enables usage of new shared library @medic/transitions in Sentinel and API. API sms and records endpoints now run transitions over docs before saving. #4857
Pulls sentinel transitions out into a shared library Enables usage of new shared library @medic/transitions in Sentinel and API. API sms and records endpoints now run transitions over docs before saving. #4857
Description
Pulls sentinel transitions out into a shared library
Enables usage of new shared library @medic/transitions in Sentinel and API.
API
sms
andrecords
endpoints now run transitions over docs before saving.#4857
Review checklist
License
The software is provided under AGPL-3.0. Contributions to this project are accepted under the same license.