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

Common cycle manager #3025

Merged
merged 8 commits into from May 22, 2023
Merged

Common cycle manager #3025

merged 8 commits into from May 22, 2023

Conversation

aliszka
Copy link
Member

@aliszka aliszka commented May 15, 2023

What's being changed:

Addresses #2983
Instead creating multiple cycle managers, separate for each bucket, geo prop etc, common cycle managers are created for different usecases:

  • memtable flush (one per store)
  • compaction (one per store)
  • tombstone cleanup (one per vector index, if created)
  • commit log maintenance (one per vector index, if created)
  • tombstone cleanup for geo props (one per shard, if any geo prop is indexed)
  • commit log maintenance for geo props (one per shard, if any geo prop is indexed)

Review checklist

  • Documentation has been updated, if necessary. Link to changed documentation:
  • Chaos pipeline run or not necessary. Link to pipeline: [TEST] common cycle manager weaviate-chaos-engineering#75
  • All new code is covered by tests where it is reasonable.
  • Performance tests have been run or not necessary.

c.commitLogMaintenance = cyclemanager.NewMulti(commitlogMaintenanceTicker)
c.tombstoneCleanup = cyclemanager.NewMulti(tombstoneCleanupTicker)

c.commitLogMaintenance.Start()
Copy link
Contributor

Choose a reason for hiding this comment

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

c.commitLogMaintenance or c.tombstoneCleanup one of them could be nil
I think we need to check for nil pointer before calling start

Copy link
Member Author

Choose a reason for hiding this comment

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

cyclemanager.NewMulti() method always returns instance. so at that point both of cycle managers are inited and safe to use

tombstoneCleanupStop <- nil
}()

commitlogMaintenanceStopErr := <-commitlogMaintenanceStop
Copy link
Contributor

Choose a reason for hiding this comment

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

the main goroutine blocks anyway. I would rather use a wait group instead of using two channels

Copy link
Member Author

Choose a reason for hiding this comment

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

Right, refactored to use WaitGroup. Also extracted to separate method to be reused in Shutdown method

}
c.lock.Unlock()

c.commitLogMaintenance.Start()
Copy link
Contributor

Choose a reason for hiding this comment

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

Same as before we need to check for nit pointers

Copy link
Member Author

Choose a reason for hiding this comment

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

as explained above. method returns earlier if instance is not inited.

commitlogMaintenanceStop := make(chan error)
tombstoneCleanupStop := make(chan error)
go func() {
if err := c.commitLogMaintenance.StopAndWait(ctx); err != nil {
Copy link
Contributor

Choose a reason for hiding this comment

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

check nil for nil pointer

Copy link
Member Author

Choose a reason for hiding this comment

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

Check whether commitLogMaintenance and tombstoneCleanup are nils is done at the beginning of the method. If so, method returns earlier.

I've extracted the check to separate method, as it was used couple of times already, and changed condition to consider instance inited if both cycle managers are created, not just one.
(change of condition was purely cosmetic, cause both cycle managers are created at the same time. So either both or none will be created)

commitlogMaintenanceStop <- nil
}()
go func() {
if err := c.tombstoneCleanup.StopAndWait(ctx); err != nil {
Copy link
Contributor

Choose a reason for hiding this comment

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

here as well

Copy link
Member Author

Choose a reason for hiding this comment

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

as explained above. method returns earlier if instance is not inited.


eg := errgroup.Group{}
eg.Go(func() error {
if err := c.commitLogMaintenance.StopAndWait(ctx); err != nil {
Copy link
Contributor

Choose a reason for hiding this comment

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

check nil for nil pointer

Copy link
Member Author

Choose a reason for hiding this comment

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

as explained above. method returns earlier if instance is not inited.

counter: 0,
states: map[uint32]*callbackState{},
keys: []uint32{},
canceledCtx: canceledCtx,
Copy link
Contributor

Choose a reason for hiding this comment

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

It is not clear to me why are we returning cancelled context canceledCtx (see line 41)

Copy link
Member Author

Choose a reason for hiding this comment

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

I used contexts to track if callback is being currently executed. Active context means callback is running, expired context means callback finished execution or was not yet started.

This particular canceled (expired) context was meant to be used as const context, for all newly added callbacks to mark them as not running.

I've changed the implementation to use nil to mark not yet run callbacks instead of expired ctx.

continue
case <-ctx.Done():
// in case both context are ready, but incoming ctx was selected
// check again running ctx as priority one
Copy link
Contributor

Choose a reason for hiding this comment

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

I would consider using if runningCtx.Err() != nil instead of the select because it is more simple

Copy link
Member Author

Choose a reason for hiding this comment

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

Good point. Changed to error check.

"github.com/weaviate/weaviate/entities/storagestate"
)

func TestStoreBackup_PauseCompaction(t *testing.T) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe it would be also useful to include in all tests a scenario where we create n-buckets in store? now we create in each test only 1 bucket.

Copy link
Member Author

Choose a reason for hiding this comment

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

added tests for 1, 2 and 5 buckets

Copy link
Contributor

Choose a reason for hiding this comment

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

great! looks good

Comment on lines 170 to 171
// h.tombstoneCleanupCycle.Start()
// h.commitLogMaintenanceCycle.Start()
Copy link
Contributor

Choose a reason for hiding this comment

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

why is this commented?

Copy link
Member Author

Choose a reason for hiding this comment

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

good catch. removed

@antas-marcin antas-marcin merged commit fc67581 into stable/v1.19 May 22, 2023
12 checks passed
@antas-marcin antas-marcin deleted the common_cycle_manager branch May 22, 2023 10:23
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

3 participants