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

[WIP] - Rework how Stop works #61

Closed
wants to merge 3 commits into from
Closed

[WIP] - Rework how Stop works #61

wants to merge 3 commits into from

Conversation

karlseguin
Copy link
Owner

@karlseguin karlseguin commented Mar 19, 2021

Work on improving how safe Stop (and other parts of the code) are:
#59

Stop no longer relies on closing a channel. Rather, it uses the control
channel to send a stop message. Further, Stop is now delayed by a
configurable duration to minimize the chance that concurrent operations
are impacted by Stop.

Using the cache after Stop executes should no longer panic. However, it
can block indefinitely (because the worker is no longer reading from
various channels). This seems much worse to me. To compensate, the
control channel is now buffered (configurable) and control writes are
now guarded with a select/default->noop. The promote call was already
guarded by this. Further, all channels are now buffered.
@@ -161,39 +174,65 @@ func (c *Cache) Delete(key string) bool {
return false
}

// Clears the cache
// Clears the cache.
// This is a control command.
Copy link
Contributor

Choose a reason for hiding this comment

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

Might be good, in this and similar doc comments, to say something like "See Configuration.ControlBuffer" because that seems to be where "control command" is defined.

func (c *Cache) SetMaxSize(size int64) {
c.control <- setMaxSize{size}
done := make(chan struct{})
c.control <- setMaxSize{size: size, done: done}
Copy link
Contributor

Choose a reason for hiding this comment

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

Is it intentional that this one is still using a blocking send whereas the others have been changed to use a non-blocking send?

close(c.promotables)
<-c.control
go func() {
time.Sleep(c.stopDelay)
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not sure what's gained by this delay. Your comment on the other issue (which would probably be good to copy into the description of this PR) said it's "to let concurrent work finish", but what would happen if the work did not finish? That is, what is the bad consequence of still having some stuff in the other channels when the worker notices the stop message in the control channel and shuts down? It will drain those channels anyway, so this doesn't seem to be about reducing the chance of leaving some values sitting around in the channels.

As far as I can tell, the worst that would happen is that it wouldn't update the LRU status of some recently updated items. And since LRU status won't be getting updated from this point on anyway, I would think it'd be adequate to say that calling Stop() implies expiration/eviction behavior is now undefined.

Maybe in place of the deleted text in the comment above, it could say something like "After Stop is called, Get and Set operations will not cause panics, but the state of the cache data is no longer guaranteed to be consistent and should not be relied on, and control operations will have no effect.

@karlseguin karlseguin closed this Mar 20, 2021
@karlseguin karlseguin deleted the new_stop branch March 20, 2021 16:12
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.

2 participants