-
Notifications
You must be signed in to change notification settings - Fork 0
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
Alternative approach: Let the model sort out the logic #49
Alternative approach: Let the model sort out the logic #49
Conversation
…nother for SO docs that can't be processed, adapts control flow through the model of how to handle the new return type, splits bulk indexing of transformed documents out from next, resumes searching for outdated docs after the bulk index is done
…uptSavedObject error in OUTDATED_DOCUMENTS_SEARCH if we have failed docs and no new outdated documents. Current issue: The model now claims to not have a final return and that undefined is not on the State type
// documents and can proceed to the next step | ||
if (stateP.failedDocumentIds && stateP.failedDocumentIds?.length > 0) { | ||
// we exit out here and throw an error with the ids of documents that we'ren't transformed | ||
throw new CorruptSavedObjectError(stateP.failedDocumentIds?.toString()); |
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.
nit: I've been trying to avoid using exceptions for control flow. So basically we only throw an exception if something unexpected happens that we have no idea how to handle. If there's a known failure condition we go to the FATAL
state. E.g. when there's a newer Kibana we want to fail, but this is a condition we fully expect to happen so we handle it explicitly https://github.com/elastic/kibana/blob/master/src/core/server/saved_objects/migrationsv2/model.ts#L715-L716
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.
Ok, that makes sense, especially because we're handling the failed docs as a right
. Should we then rather handle this as a failure condition? We want migrations to stop after we've built up the full list of failed docs. Should we rather try the approach of creating a TaskEither
from the async transform method?
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.
Instead of throwing we would just go to the FATAL
state with a reason
string. The code changed after I posted, so the link is no longer showing the correct lines.
But I meant something like:
return {
...stateP,
controlState: 'FATAL',
reason: '... migrations failed because of the following corrupt saved object documents: [...]',
};
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 thought about that too but then realized we're specifically targeting CorruptSavedObjectError
within the catch
block of migrationStateActionMachine
, where we throw a new Error
with a custom message. I guess we won't need to target CorruptSavedObjectError
anymore if we're going to the FATAL
state with a detailed reason
.
@@ -191,12 +191,25 @@ export type UpdateTargetMappingsWaitForTaskState = PostInitState & { | |||
export type OutdatedDocumentsSearch = PostInitState & { | |||
/** Search for outdated documents in the target index */ | |||
readonly controlState: 'OUTDATED_DOCUMENTS_SEARCH'; | |||
readonly failedDocumentIds?: string[]; |
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 be simpler to not make this property optional otherwise we have three states:
- undefined
- empty array (no failures)
- non-empty array (some failures)
But we don't need or use (1), so we can rather initialize an empty array and then we don't need to use failedDocumentIds!
in other places.
abandoned approach in favor of elastic#96986 |
Summary
This explores an alternative approach to handling saved objects that can't be transformed.
The approach assumes we have PIT search and won't attempt to transform documents that have already failed transformation.
This approach does the following:
migrate_run_docs
uses a new method,migrateRawDocsNonThrowing
that returns both the processed docs and the ids of those that couldn't be processed as arrays.failedDocsIds
contains the ids of those documents that we previously threw aCorruptSavedObjectError
for.try-catch
, to catch any serious errors such as a migration script throwing an error.OUTDATED_DOCUMENTS_SEARCH
handls control flow toOUTDATED_DOCUMENTS_TRANSFORM
:TRANSFORMED_DOCUMENTS_BULK_INDEX
.TRANSFORMED_DOCUMENTS_BULK_INDEX
bulk indexes the transformed documents and passes control flow back toOUTDATED_DOCUMENTS_SEARCH
to carry on searching.failedDocumentIds: string[]
and pass the control flow back toOUTDATED_DOCUMENTS_SEARCH
. Note: We explicitly don't carry on indexing the transformed documents because we already know the migration will ultimately fail.OUTDATED_DOCUMENTS_SEARCH
will throw aCorruptSavedObject
Error (that triggers dumping the logs) when it sees there aren't any more outdated documents to search and we have failed documents on state. If there aren't any failed documents on state and we've searched through all the outdated docs, we continue along the happy migration path.All types were updated (I think) but no tests have been refactored yet. There's also an issue now that the model complains to not have a final return statement and that
undefined
is not declared onState
.PROBLEM: I'm not sure where the issue with the model not having a final return statement is coming from. Is it because we're not dealing with a
Task
?