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

fix rampant memory leak in providers records storage #1315

Merged
merged 1 commit into from
Jun 2, 2015
Merged

Conversation

whyrusleeping
Copy link
Member

This was broken, its better now. provider records still arent signed, but now our gateways wont inadvertently run themselves out of memory.

@whyrusleeping whyrusleeping added the status/in-progress In progress label Jun 1, 2015
pi.Value = np.val
arr := pm.providers[np.k]
pm.providers[np.k] = append(arr, pi)
provs, ok := pm.providers[np.k]
Copy link
Contributor

Choose a reason for hiding this comment

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

pm.run is the only func that access this map, right? might want to document that in the struct

@whyrusleeping
Copy link
Member Author

in the future, i do want to move back to using arrays here, maps use a lot of memory, and iterating maps into an array for every request is moderately expensive. But doing so would require a limit on the number of providers stored for any given key to avoid the problem i'm fixing here again (checking for existence in a large array is unpleasant, but doable) Maybe I should just implement that now?

delete(provs, p)
} else {
parr = append(parr, p)
}
Copy link
Member

Choose a reason for hiding this comment

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

this is making a huge array every time, isn't it? nevermind

@jbenet
Copy link
Member

jbenet commented Jun 1, 2015

@whyrusleeping what i do for this sort of thing is keep both. something like:

var ProviderLifetime = time.Hour * 24

// record key : providers
var providers = map[u.Key]*ProviderSet

type ProviderSet struct {
  records []Record // to be copied right into a message
  set map[u.Key]time.Time // set for fast checking.
}

func (ps *ProviderSet) add(r Record) {
  if   _, found := ps.set[r.key]; !found {
    ps.records = append(ps.records, r)
  }
  ps.set[r.key] = time.Now()
}

func (ps *ProviderSet) expire() {
  // cleanup both ps.set and ps.records for entries whose time is > ProviderLifetime
}

the memory usage is not prohibitive and yields higher req/s

filtered = append(filtered, p)
for _, provs := range pm.providers {
for p, t := range provs {
if time.Now().Sub(t) > time.Hour*24 {
Copy link
Member

Choose a reason for hiding this comment

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

constant:

var ProviderLifetime = time.Hour*24

@whyrusleeping
Copy link
Member Author

I would argue that the memory usage on that is prohibitive, we are going to have to store a lot of providers (or set limits, which opens pandoras box). a 2x bump in memory usage is gonna hurt.

@whyrusleeping
Copy link
Member Author

but i guess we can cross that bridge when we get there. I'll go ahead and implement the map/slice combo.

address comments from CR

use map and array combo for better perf
jbenet added a commit that referenced this pull request Jun 2, 2015
fix rampant memory leak in providers records storage
@jbenet jbenet merged commit c9ad7a9 into master Jun 2, 2015
@jbenet jbenet removed the status/in-progress In progress label Jun 2, 2015
@jbenet jbenet deleted the fix/prov-store branch June 2, 2015 00:25
@wking wking mentioned this pull request Jun 12, 2015
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.

3 participants