Using runtime.SetFinalizer with timed goroutine

1,352 views
Skip to first unread message

John Barham

unread,
Mar 17, 2011, 1:23:40 AM3/17/11
to golang-nuts
I'm trying to write a database connection pool that will create new
connections on demand up to some maximum count, but also periodically
close any connections that haven't been accessed for some timeout
period.

However, I'd also like to add a finalizer to the pool object, using
runtime.SetFinalizer, to close any connections when the pool is
garbage collected, in case the user forgets to explicitly close it.
But if I have a background timeout goroutine, it seems to me that it
must hold a reference to the pool object in order to close the pool's
connections, but that reference means the finalizer will never be
called on the pool... So it looks like I can have either a finalizer
or a timeout handler, but not both. How to resolve this seeming
Catch-22? Or do I need to wait for weakrefs? ;)

John

Russ Cox

unread,
Mar 17, 2011, 1:27:56 AM3/17/11
to John Barham, golang-nuts
type conn struct {
...
}

type Conn struct {
*conn
}

give out *Conn to the clients and put the finalizer there.
keep conn in your timeout cache.

John Barham

unread,
Mar 18, 2011, 2:21:27 AM3/18/11
to r...@golang.org, golang-nuts
Subtle, but it works. Thanks.

Is the rule that a reference to an embedded struct doesn't prevent the
container struct from being garbage collected (and therefore
finalized)?

FWIW I'm using this on a connection pool I've implemented for my
PostgreSQL client wrapper. Source is at
https://github.com/jbarham/pgsql.go/blob/master/pool.go. Initially I
tried using a channel but in the end decided it was simpler just to a
use a list w/ sync.Cond. Is there some Go concurrency idiom I'm
missing and should be using instead?

John

Jessta

unread,
Mar 18, 2011, 2:30:18 AM3/18/11
to John Barham, r...@golang.org, golang-nuts
On Fri, Mar 18, 2011 at 5:21 PM, John Barham <jba...@gmail.com> wrote:
> Subtle, but it works.  Thanks.
>
> Is the rule that a reference to an embedded struct doesn't prevent the
> container struct from being garbage collected (and therefore
> finalized)?

The rule is that if there is no references to an object it gets
garbage collected( and finalized)
A reference to an embedded struct would prevent it's container from
being collected.
But in this case it's just an embedded pointer.

- jessta


--
=====================
http://jessta.id.au

Steven

unread,
Mar 18, 2011, 9:49:36 AM3/18/11
to John Barham, r...@golang.org, golang-nuts
If you had a pointer into the memory of the containing structure (ie `c := new(Conn); p := &c.conn`), that would prevent the containing structure from being garbage collected. However, in this case, the memory in the containing structure contains a pointer to an external object. This pointer gets garbage collected along with the rest of the containing structure, but the external object it points to does not. So you can safely store a copy of the pointer to the external object elsewhere and it will not prevent the containing structure from being finalized.
Reply all
Reply to author
Forward
0 new messages