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

Optimize and clean up couch_multidb_changes #4911

Merged
merged 1 commit into from
Dec 13, 2023
Merged

Conversation

nickva
Copy link
Contributor

@nickva nickva commented Dec 12, 2023

couch_multidb_changes is in charge of monitoring changes to multiple databases. It is what drives the couch_replicator application when users update replication docs. It starts off by scanning all the local db shards and launches changes feeds for each of them. After it processes each changes feed, it checkpoints where it stops. As the shards are updated, it starts change feeds for those updated shards and checkpoints again. The checkpoints are kept in an ets table and the main logic which decides when to start a changes feed for a particular shard is in the resume_scan/2 function.

This change makes a few small optimizations:

  • Use a map to track Pid -> DbName mappings. This avoids using a O(N) operation for looking up exiting change feed processes. So pids is switched to be a map of #{Pid => DbName} and the ets table has a 4th tuple member to keep track of dbname -> pid mappings.

  • Previously, when the plain "suffix" dbname (just <<"_replicator">>) was found, we tried to open and close it to see if it exists. Change to use couch_server:exists/1 instead.

The are also a few clean-ups:

  • Update tests to use ?TDEF_FE/?TDEF macros. This shortens them a bit and saves one indentation level.

  • Increase test coverage from 86% to 96%. To help create a few more test scenarios switched to using a public ets table instead of a private one.

Copy link
Contributor

@jaydoane jaydoane left a comment

Choose a reason for hiding this comment

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

Nice cleanup, and impressive coverage at 96%!

ok = couch_db:close(Db);
_Error ->
ok
case couch_server:exists(DbSuffix) of
Copy link
Contributor

Choose a reason for hiding this comment

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

Nice!

couch_multidb_changes is in charge of monitoring changes to multiple databases.
It is what drives the couch_replicator application when users update
replication docs. It starts off by scanning all the local db shards and
launches changes feeds for each of them. After it processes each changes feed,
it checkpoints where it stops. As the shards are updated, it starts change
feeds for those updated shards and checkpoints again. The checkpoints are kept
in an ets table and the main logic which decides when to start a changes feed
for a particular shard is in the resume_scan/2 function.

This change makes a few small optimizations:

 * Use a map to track Pid -> DbName mappings. This avoids using a O(N)
   operation for looking up exiting change feed processes. So `pids` is
   switched to be a map of `#{Pid => DbName}` and the ets table has a 4th tuple
   member to keep track of `dbname -> pid` mappings.

 * Previously, when the plain "suffix" dbname (just <<"_replicator">>) was
   found, we tried to open and close it to see if it exists. Change to use
   `couch_server:exists/1` instead.

The are also a few clean-ups:

 * Update tests to use ?TDEF_FE/?TDEF macros. This shortens them a bit and
   saves one indentation level.

 * Increase test coverage from 86% to 96%. To help create a few more test
   scenarios switched to using a public ets table instead of a private one.
@nickva
Copy link
Contributor Author

nickva commented Dec 13, 2023

I caught a case missed where when a change feed process exits but it doesn't have to rescan again I didn't clear its old Pid from the ets table. So I added a clause for it:

                [{DbName, _EndSeq, false, From}] ->
                    ets:update_element(NewState#state.tid, DbName, {4, undefined}),
                    {noreply, NewState};

Also running on my slow laptop a few times in a row I noticed a few couch_replicator_scheduler_docs_tests had a few flaky timeout so I bumped their timeouts from 10 to 15

@nickva nickva merged commit 641b393 into main Dec 13, 2023
14 checks passed
@nickva nickva deleted the clean-up-multidb-changes branch December 13, 2023 00:58
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.

None yet

2 participants