Git Product home page Git Product logo

Comments (4)

jackc avatar jackc commented on June 8, 2024

Consider such a situation, when the maxSize is exceeded, the Acquire function is called again. If no resources have been released and ctx has timed out, the above logic is triggered. If other resources have not been released, it will wait until a new resource is released, triggering the unlocking.

Do you have an example or test demonstrating this erroneous behavior? The logic appears correct to me.

from puddle.

waponxie avatar waponxie commented on June 8, 2024

Yes. I wrote a demo to simulate this scene。

package main

import (
	"context"
	"fmt"
	"time"

	"github.com/jackc/puddle"
)

func main() {
	p := puddle.NewPool(
		func(ctx context.Context) (interface{}, error) {
			var value int
			return &value, nil
		},
		func(value interface{}) {},
		1,
	)
	resBg, _ := p.Acquire(context.Background())
	for i := 0; i < 10000; i++ {
		go func() {
			now := time.Now()
			ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond)
			_, err := p.Acquire(ctx)
			defer cancel()
			cost := time.Now().Sub(now)
			if cost > 110*time.Millisecond {
				fmt.Printf("err: %v, cost:%v\n", err, cost)
			}

		}()
	}
	time.Sleep(2 * time.Second)
	resBg.Release()
}

On my machine, it has the following output:

err: context deadline exceeded, cost:122.398036ms
err: context deadline exceeded, cost:121.074585ms
err: context deadline exceeded, cost:120.942892ms
err: context deadline exceeded, cost:120.154298ms
err: context deadline exceeded, cost:120.339236ms
err: context deadline exceeded, cost:117.905087ms
err: context deadline exceeded, cost:120.816183ms
...

I think it’s the same result on your machine

from puddle.

jackc avatar jackc commented on June 8, 2024

I think it’s the same result on your machine

Actually, nothing printed for me. I had to change the loop to 100000 to get any output.

err: context deadline exceeded, cost:742.378554ms
err: context deadline exceeded, cost:742.298367ms
err: context deadline exceeded, cost:740.731022ms
err: context deadline exceeded, cost:740.374492ms

But I still don't see the problem. It's spinning up 100,000 goroutines contending for a single resource --- plus 100,000 timers --- plus another 100,000 goroutines to handle the p.cond.Wait into a channel. I would expect to see a delay just because of the Go scheduler.

Just for kicks I reran it with the lock and canceledAcquireCount increment commented out. It reduced the "cost" by a couple hundred ms but did not eliminate the behavior you describe. And I really I don't want to lose the canceldAcquireCount stats.

I suppose that path could be optimized. Maybe using atomics. But IMO, at the point this becomes an issue the system is already extremely overloaded. The real problem is something needs to handle backpressure. Ideally this would be done by the caller of Acquire such that it never is called in a overload situation. This is one of the reasons the canceled acquire stat is important. That is a signal that could be used to detect an overload.

Or the pool could detect an overload situation and immediately drop new Acquire requests. But the strategy used to detect an overload and determine which requests to drop can be complicated and vary by application. puddle is designed to be a minimal, super lightweight pool. I'm not eager to add any features that could be handled by the calling application.

from puddle.

waponxie avatar waponxie commented on June 8, 2024

In my practice, I use puddle by pgx, I will report the cost of function Query, Exec etc. I found that the reported value exceeds the timeout of ctx. Sometimes it will exceed tens of milliseconds.
I can understand your design, that is vary great,but maybe we can have a better solution to implement it.
Finally, thank you for replying to me.

from puddle.

Related Issues (13)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.