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

Enable look-up by secondary index in cache #4125

Merged
merged 3 commits into from
Feb 12, 2015

Conversation

derekwaynecarr
Copy link
Member

This is an enhancement to our cache to let you optionally create a store that can build a secondary index on its data. The main use case is I want to have a store that holds a bunch of resources across namespaces, and I want to be able to then interface with that store by asking to retrieve only the resources in namespace X.

If folks are good with this pattern, I will adopt it in the admission control handlers for resource quota and limit range.

@smarterclayton @ironcladlou @erictune

// it is intended to be called from a function that already has a lock on the cache
func (c *cache) updateIndex(obj interface{}) error {
if c.indexFunc == nil {
return nil
Copy link
Contributor

Choose a reason for hiding this comment

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

Since Cache claims to implements Index, I feel like a nil indexFunc would be an illegal state resulting in silently broken indexing behavior. Maybe this should return an error?

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 could see that. I guess I could have a default indexFunc that maps to the empty string.

@ironcladlou
Copy link
Contributor

Really cool idea. I made some comments inline.

@derekwaynecarr
Copy link
Member Author

@ironcladlou thanks for the feedback, will update per your comments.

after speaking with @markturansky , we thought it would be useful to support multiple index funcs. I am going to take another pass at this work with that concept in mind.

@markturansky
Copy link
Contributor

The single index function could also be a composite of index functions.

@derekwaynecarr derekwaynecarr force-pushed the store_by_namespace branch 2 times, most recently from 2e6f9c9 to 09cb617 Compare February 5, 2015 18:25
@derekwaynecarr
Copy link
Member Author

Added support for giving multiple index functions, and then ability to get an index by its name.

Addressed @ironcladlou feedback to make sure cache works fine as both an Indexer and a Store.

Please review and provide any further feedback.

@@ -76,6 +81,57 @@ func (c *cache) Add(obj interface{}) error {
c.lock.Lock()
defer c.lock.Unlock()
c.items[key] = obj
c.updateIndices(obj)
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you build the list of what you need to modify in the indexes separately from actually making the update? It would help limit contention on the lock. Same reason the key is calculated before lock acquisition.

Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think rebuilding the entire index is going to scale very long. Why not start with incremental? Get prev object, gen index entries for it, delete those, gen index entries for new object, insert those.

On Feb 6, 2015, at 11:08 AM, David Eads notifications@github.com wrote:

In pkg/client/cache/store.go:

@@ -76,6 +81,57 @@ func (c *cache) Add(obj interface{}) error {
c.lock.Lock()
defer c.lock.Unlock()
c.items[key] = obj

  • c.updateIndices(obj)
    Can you build the list of what you need to modify in the indexes separately from actually making the update? It would help limit contention on the lock. Same reason the key is calculated before lock acquisition.


Reply to this email directly or view it on GitHub.

Copy link
Member Author

Choose a reason for hiding this comment

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

@smarterclayton - its not rebuilding the entire index. your point on prev object is needed, will update.

Copy link
Member Author

Choose a reason for hiding this comment

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

basically, i need a diff call on add vs update.

Copy link
Member Author

Choose a reason for hiding this comment

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

so if on update, i get the previous object based on its key, and then remove that object from all indices, then for updated object treat like an add, it should be fine. will make an update this afternoon.

Copy link
Contributor

Choose a reason for hiding this comment

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

Right.

----- Original Message -----

@@ -76,6 +81,57 @@ func (c *cache) Add(obj interface{}) error {
c.lock.Lock()
defer c.lock.Unlock()
c.items[key] = obj

  • c.updateIndices(obj)

so if on update, i get the previous object based on its key, and then remove
that object from all indices, then for updated object treat like an add, it
should be fine. will make an update this afternoon.


Reply to this email directly or view it on GitHub:
https://github.com/GoogleCloudPlatform/kubernetes/pull/4125/files#r24257444

Copy link
Contributor

Choose a reason for hiding this comment

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

You might have to hold a lock while doing that (or the Add has to fail fast if there's a conflict and you have to try again)

----- Original Message -----

@@ -76,6 +81,57 @@ func (c *cache) Add(obj interface{}) error {
c.lock.Lock()
defer c.lock.Unlock()
c.items[key] = obj

  • c.updateIndices(obj)

so if on update, i get the previous object based on its key, and then remove
that object from all indices, then for updated object treat like an add, it
should be fine. will make an update this afternoon.


Reply to this email directly or view it on GitHub:
https://github.com/GoogleCloudPlatform/kubernetes/pull/4125/files#r24257444

@derekwaynecarr
Copy link
Member Author

Updated to ensure that when updating an object in the indices that it handles removal before addition. Current indexing is incremental. An obvious solution to limiting lock contention is not there for me right now because I need the oldObject in the context of a lock in order to do removal. I think this is a good first step and should not block the PR.

@derekwaynecarr
Copy link
Member Author

Any other comments or issues with this PR?

@smarterclayton
Copy link
Contributor

LGTM

@smarterclayton smarterclayton added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Feb 12, 2015
@erictune
Copy link
Member

LGTM

@erictune erictune assigned erictune and unassigned dchen1107 Feb 12, 2015
@erictune
Copy link
Member

will merge this tomorrow if the oncall doesn't get to it first.

smarterclayton added a commit that referenced this pull request Feb 12, 2015
Enable look-up by secondary index in cache
@smarterclayton smarterclayton merged commit 371349f into kubernetes:master Feb 12, 2015
@derekwaynecarr derekwaynecarr deleted the store_by_namespace branch April 17, 2015 17:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
lgtm "Looks good to me", indicates that a PR is ready to be merged.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants