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

Improve performance of websocket subscription using buffered pool #1477

Closed
arijitAD opened this issue Mar 18, 2021 · 3 comments · Fixed by #1693
Closed

Improve performance of websocket subscription using buffered pool #1477

arijitAD opened this issue Mar 18, 2021 · 3 comments · Fixed by #1693
Assignees

Comments

@arijitAD
Copy link
Contributor

Issue summary

  • Currently, we are generating a random number for subscriptions ID to find an empty slot for a subscription. We might end up wasting too much time generating a random number because Intn doesn't generate a purely random number.
  • Instead, we can use a buffered pool to achieve the same.
  • Buffered pool implemented using channels is also thread-safe. (Locks are not required)

Other information and links

@dutterbutter dutterbutter changed the title Improve performance of websocket subscription using buffered pool. Improve performance of websocket subscription using buffered pool Mar 18, 2021
@EclesioMeloJunior
Copy link
Member

EclesioMeloJunior commented May 4, 2021

hey @arijitAD, you suggest that we create a buffered pool with size = 256 * 256 (256 for imported and 256 for finalised ) then populate the buffered pool with the bytes generated by generateID() function and when we need to insert a new register on the map we call:

id := bs.bufferdpool.Get()
// ...omitted code
bs.finalised[id] = ch // or bs.imported[id] = ch

I don't know if this is the intended approach, but I've implemented a buffered pool to use with generatedID() here https://play.golang.org/p/_QFnMeqlNj1

@arijitAD
Copy link
Contributor Author

arijitAD commented May 4, 2021

hey @arijitAD, you suggest that we create a buffered pool with size = 256 * 256 (256 for imported and 256 for finalised ) then populate the buffered pool with the bytes generated by generateID() function and when we need to insert a new register on the map we call:

id := bs.bufferdpool.Get()
// ...omitted code
bs.finalised[id] = ch // or bs.imported[id] = ch

I don't know if this is the intended approach, but I've implemented a buffered pool to use with generatedID() here https://play.golang.org/p/_QFnMeqlNj1

Your buffer pool will not have a upper limit on the number of connection.

You can take a look at this buffer pool code. https://github.com/oxtoacart/bpool/blob/master/bufferpool.go

We just need to modify Get() and Put() APIs.

func (bp *BufferPool) Get() (b *bytes.Buffer) error {
	select {
	case b = <-bp.c:
	    return nil
	default:
		return fmt.Errorf("All slots used")
	}
}
// Put returns the given Buffer to the BufferPool.
func (bp *BufferPool) Put(b *bytes.Buffer) error {
	b.Reset()
	select {
	case bp.c <- b:
                return nil
	default:
		return fmt.Errorf("Pool is full")
	}
}
bp.c = make(chan *bytes.Buffer, 256)

@github-actions
Copy link

github-actions bot commented Dec 3, 2021

🎉 This issue has been resolved in version 0.6.0 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
4 participants