witash opened a new pull request, #6138:
URL: https://github.com/apache/couchdb/pull/6138

   <!-- Thank you for your contribution!
   
        Please file this form by replacing the Markdown comments
        with your text. If a section needs no action - remove it.
   
        Also remember, that CouchDB uses the Review-Then-Commit (RTC) model
        of code collaboration. Positive feedback is represented +1 from 
committers
        and negative is a -1. The -1 also means veto, and needs to be addressed
        to proceed. Once there are no objections, the PR can be merged by a
        CouchDB committer.
   
        See: http://couchdb.apache.org/bylaws.html#decisions for more info.
   
        Artificial Intelligence and Large Language Models Contributions Policy
   
        It is expressly forbidden to contribute material generated by
        AI, LLMs, and similar technologies, to the CouchDB project. 
        This includes, but is not limited to, source code, documentation,
        commit messages, or any other areas of the project.
   
   -->
   
   ## Overview
   
   When updating nouveau indexes, `nouveau_index_updater:update/1` runs two 
phases: first the purge phase (`purge_index`), which walks the purge infos 
since the index's `purge_seq`, then the changes phase, which walks the changes 
feed since the index's `update_seq`.
   
   If the document for a purge info still exists in the database, the current 
behavior is to re-index the document's current winning revision during the 
purge phase. This is sent to nouveau as a normal index update, using the 
document's current update seq, so it moves the index's `update_seq` to that 
seq, and the changes phase then starts from the moved `update_seq`.
   
   Purge infos are processed in purge order, but the current seqs of the 
documents that still exist don't follow that order, and can even be lower than 
the index's `update_seq`. So these updates can go backwards, and nouveau 
rejects them with "Index updates applied in the wrong order". When the update 
does go forward, `update_seq` can skip past changes that haven't been indexed 
yet, and the changes phase never indexes them, with no error.
   
   This branch stops re-indexing documents that still exist during the purge 
phase, so the purge phase never changes `update_seq`. If the document for a 
purge info still exists, the purge phase compares the document's current update 
seq with the index's `update_seq` from the start of the update:
   
   - If the document's seq is greater, the document was changed after the index 
last saw it (a purge that removes revisions gives the document a new seq). It's 
removed from the index with a purge delete, which only moves `purge_seq`, and 
the changes phase then indexes its current winning revision.
   - If the document's seq is less than or equal, the purge didn't change the 
document and the index already has its current winning revision, so nothing is 
sent.
   
   The exclude list, which let the changes phase skip documents already 
re-indexed in the purge phase, is removed, since nothing is re-indexed there 
any more. And the purge phase no longer needs a JS process, since it doesn't 
run the index function.
   
   This keeps the index consistent with the rules stated in the documentation 
(`src/docs/src/api/database/misc.rst`, "Updating Indexes"):
   
   - If the winner of the revision tree is not specified in the purge request, 
there is no change to the index record of this document.
   - If the winner of the revision tree is specified in the purge request, and 
there is still a revision left after purging, the index record of the document 
will be built according to the new winner of the revision tree.
   - If all revisions of the document are specified in the purge request, the 
index record of the document will be deleted. The document will no longer be 
found in searches.
   
   But there is a small change in behavior; between the purge phase and the 
changes phase, documents that were purged and then updated are not in the 
index. This is basically consistent with applying purges and then updates in 
order; first apply the purge (the old document is no longer indexed), then 
apply the update (the new document is indexed). But it's different from the 
current behavior, where the new document is indexed as soon as the purge is 
applied.
   
   I didn't see any way around this, other than a larger change to nouveau so 
that it can apply updates without changing `update_seq`.
   
   ## Testing recommendations
   
   `make nouveau-test`. The new elixir test `purge with out of order edits` (in 
`test/elixir/test/nouveau_test.exs`) creates a single-shard database, indexes 4 
documents, purges two of them (A, then B, in separate requests), creates a new 
document C, re-creates B and then A, and checks that the search returns all 5 
documents and that the index's `update_seq` and `purge_seq` match the database. 
Without this change, the final search fails with "Index updates applied in the 
wrong order (current seq: 10, match seq: 10, attempted seq: 9)".
   
   The existing `purge with conflicts` test covers documents where the purge 
removes the winning revision and a revision is left, which now goes through the 
purge delete and the changes phase.
   
   ## Related Issues or Pull Requests
   
   Fixes #6118. #6096 fixed the `{invalid_start_purge_seq, 0, N}` error from 
the same issue; this fixes the "Index updates applied in the wrong order" error 
that still happens after it, when documents that were purged still exist.
   
   ## Checklist
   
   - [ ] This is my own work, I did not use AI, LLM's or similar technology
   - [ ] Code is written and works correctly
   - [ ] Changes are covered by tests
   - [ ] Any new configurable parameters are documented in 
`rel/overlay/etc/default.ini`
   - [ ] Documentation changes were made in the `src/docs` folder
   - [ ] Documentation changes were backported (separated PR) to affected 
branches
   
   ## AI Disclosure
   
   I used Claude code to review changes that I authored, and to help with 
Erlang syntax, but all of the code in this PR was written by me directly, not 
Claude.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to