Skip to content
This repository has been archived by the owner on Sep 6, 2022. It is now read-only.

connmgr: introduce abstractions and functions for decaying tags. #104

Merged
merged 4 commits into from
May 14, 2020

Conversation

raulk
Copy link
Member

@raulk raulk commented Dec 26, 2019

Implementation in libp2p/go-libp2p-connmgr#61


This PR introduces a decaying trait for the connection manager.

  • It is optional for connection managers to implement it.
  • The connmgr.SupportsDecay() function can be used to check if a given implementation supports decay.
  • I'd like to make this pattern more prevalent across go-libp2p.
    • Golang is a terrible language for composability, but I suspect this pattern is reasonable and simple enough to adopt across the board when enhancing existing components (e.g. like with the upcoming Peerstore change to support certified records), without breaking the world for existing implementations.

A decaying connection manager can register decaying tags. When doing so, the user provides four things:

  • name.
  • interval at which the decay ticks.
  • a decaying function: takes the old value and returns the new value, or whether the tag should be eliminated.
  • a bump function: takes the current value of the tag, and an incoming delta, and returns the new value of the tag.

The solution is decidedly modular and relies on pluggable components to put the power in the hands of users, and to prevent us from overfitting for our particular use cases. Yet, to provide a smooth DX, the upcoming go-libp2p-connmgr PR contributes a pile of useful decay and bump functions.

Usage

Some example use cases.

Expiring inactive tags after 10 minutes

decay, ok := connmgr.SupportsDecay(mgr)
if !ok {
     return
}

// this tag ticks every minute, and deletes tags that have been inactive for 10 minutes. Every incoming value overwrites the previous value.
tag, err := decay.RegisterDecayingTag("pop", 1*time.Minute, connmgr.ExpireWhenInactive(10*time.Minute), connmgr.Overwrite())
if err != nil {
    return
}

tag.Bump(<peer id>, 100)
time.Sleep(9 * time.Minute)
tag.Bump(<peer id>, 100)	// refreshes for another 10 minutes

Decrease the value of a tag every minute by half

tag, err := decay.RegisterDecayingTag("pop", 1*time.Minute, connmgr.LinearDecay(0.5), connmgr.Overwrite())
if err != nil {
    return
}

tag.Bump(<peer id>, 100)
time.Sleep(1 * time.Minute)
// value will be 50
time.Sleep(1 * time.Minute)
// value will be 25

connmgr/connmgr.go Outdated Show resolved Hide resolved
@Stebalien
Copy link
Member

What if we provided a helper instead of baking this into the connection manager? That is, every service that needs a decaying tag would wrap the connection manager with a decaying tag manager (for that tag):

tag := DecayingTag(myConnmgr, "my-tag", interval, decayFn, bumpFn)
defer tag.Close() // or cancel with a context?

tag.Bump(peerID, value)

Having to call SupportsDecay is really awkward. Either:

  1. It'll always return a connection manager that supports this feature.
  2. The service will have to handle the case when it doesn't. That's going to suck.

@yusefnapora
Copy link
Contributor

@raulk I've been working against this branch locally but had to rebase against master. I'm going to force-push it up. Just wanted to give a heads-up since it's not my branch :)

For context, we're hoping to get libp2p/go-libp2p-pubsub#306 sorted out by Monday, which depends on the decaying tag functionality.

@raulk
Copy link
Member Author

raulk commented May 14, 2020

@yusefnapora I've moved the out-of-the-box decay and bump functions here, so you can now use them without depending on the actual implementation.

I also made the tag interval more lenient, and added Name() and Interval() methods to the decaying tag, so you can fetch its name and the effective interval at runtime.

@raulk raulk changed the title connmgr: introduce abstractions for decaying tags. connmgr: introduce abstractions and functions for decaying tags. May 14, 2020
@raulk raulk merged commit e5edab1 into master May 14, 2020
@raulk raulk deleted the feat/decayer branch May 14, 2020 14:54
@Stebalien Stebalien mentioned this pull request May 26, 2020
77 tasks
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants