--
---
You received this message because you are subscribed to the Google Groups "golang-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-dev+...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
On Mon, May 20, 2013 at 9:35 PM, Brad Fitzpatrick <brad...@golang.org> wrote:Good point.
> I'm nervous about having anything more than Get and Put for now.
The SetCapacity is intended to be used during initialization, before
> Also, if SetCapacity and Drain can't be used concurrently, how can I ever
> use it without a RWMutex around all the Get/Put calls, which somewhat
> negates the point of whole thing in the first place.
any Puts and Gets.
The Drain is intended to be used during shutdown, e.g. to close DB
connections or something.
> If we're going to have Drain, it should be allowed to be concurrent.Get can't get resources cached in other P's.
>
> But do we need Drain? A Get loop could work too. The pools should be small
> enough that a loop of maxprocs would be fine.
That's the point, other
P's can work with their resources w/o any synchronization.
1 local resource is not enough even for the simplest case of Sprintf()
calls v.String() which in turn calls Sprintf(). Not saying about more
recursive things and long resource usage, when a goroutine migrates
with non-zero probability.
> Also, if SetCapacity and Drain can't be used concurrently, how can I ever> use it without a RWMutex around all the Get/Put calls, which somewhatThe SetCapacity is intended to be used during initialization, before
> negates the point of whole thing in the first place.
any Puts and Gets.
The Drain is intended to be used during shutdown, e.g. to close DB
connections or something.
One problem completely unsolved until now is the type safety of pools.e.g. I can do pool.Put(int(3)) and pool.Put("foo") and have to use g := pool.Take().(int) to extract it,but it will fail on the string I just put accidentally into it.May I suggest at least checking the type on put and making the pools typed by the type of a value supplied on pool creation?Any other ideas how to solve this riddle?Is this a just another case of "doctor it hurts..."?
On Tue, May 21, 2013 at 10:07 AM, Dmitry Vyukov <dvy...@google.com> wrote:
On Tue, May 21, 2013 at 6:04 PM, Ian Lance Taylor <ia...@golang.org> wrote:Any suggestions on naming?
> On Tue, May 21, 2013 at 6:49 AM, Dmitry Vyukov <dvy...@google.com> wrote:
>>
>> I think that need for other types of Pools/Caches is better understood
>> by users. For example, db connection pooling that would require
>> something line non-losing FIFO pool with hard limit on resource number
>> and blocking Take(). Or expensive-to-compute resource pool that would
>> require something line concurrent timed map. While this Pool can be
>> used only as malloc optimization.
>
> It seems to me that we would want to use entirely different
> implementations for those.
>
>> Also, if we ever provide other types of pools/caches, we must not end
>> up with confusing naming, e.g. Pool vs FIFOPool.
>
> That's a good reason to pick a good package name. E.g., I'm not sure
> why this Pool should be in the sync package.
If this pool is just for managing allocations (as opposed to DB connections, say), then package alloc, type Pool.
If you call it Pool, users will assume it contains homogenous values, but will assume it doesn't leak.
Based on semantics, LeakyPool may be better, but if you call the package container/subtle, you could get away with Cache or Pool.
It appears that the motivation is to provide some kind of lightweight per-CPU caching, but that doesn't come out in the docs, nor the implementation. So I'm quite confused about the expected generality of the type.
I'm happy to talk about names, but I can't do that until I know what the goal is.
One object per CPU is not enough even for a trivial case of Stringercalling String() on a subobject.
+ goroutine can be descheduled while holding the object.
+ rpc, http need much larger caches
+ as far as I understand regexp wants more as well
On Mon, May 20, 2013 at 8:32 PM, Jan Mercl <0xj...@gmail.com> wrote:
> On Mon, May 20, 2013 at 6:11 PM, Dmitry Vyukov <dvy...@google.com> wrote:
>
> The Get method could also be alternatively
>
> func (c *Cache) Get(func(x interface{}) bool) interface{}
>
> where the passed function:
> - if nil -> ignored
> - otherwise it's passed cached (candidate) items until returns true.
> Then that item is returned from Get. If the function never returns
> true the Get returns interface{}(nil).
>
> The idea is that cached items can have properties and not every item
> have properties which the client of Get needs. For example, think of a
> Cache of []byte: the client may need only buffers of some minimal len
> or cap. Without such function the client would have to repeat .Get
> until satisfied, then return all the below-the-cut buffers back.
>
> Non-technical: I prefer Cache, the originally proposed name, instead of Pool.
In the issue tylor@ wrote:
"Please call this construct a Pool (or FixedPool) rather than a Cache
if it comes into existence. I can already imagine myself explaining to
new people over and over again on #go-nuts that sync.Cache is actually
a pool, etc etc..."
I also find it somewhat confusing. I think Cache is a more overloaded
term than Pool, there are LRUCache's, TimedCache's, etc.
I'll redundantly say I'm still interested.
It's time to decide whether we want this in 1.2 or not.
I am voting for including it as sync.Pool.