Last active
April 12, 2022 02:26
-
-
Save win-t/7ae0ab5fdea1f92c5bf4f96b87551996 to your computer and use it in GitHub Desktop.
golang owned goroutine
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package resource | |
import ( | |
"context" | |
"fmt" | |
"io" | |
"runtime" | |
"sync/atomic" | |
"time" | |
) | |
type Resource struct { | |
// we embed the inner representation, so all public method is also available in outer one | |
*resource | |
} | |
// this is inner representation of the resource | |
type resource struct { | |
ctx context.Context | |
cancel context.CancelFunc | |
counter int32 | |
} | |
// compile time check to make sure *Resource implement io.Closer | |
var _ io.Closer = (*Resource)(nil) | |
func (r *resource) Close() error { r.cancel(); return nil } | |
func (r *resource) main() { | |
fmt.Println("resource start") | |
defer fmt.Println("resource end") | |
for { | |
select { | |
case <-r.ctx.Done(): | |
return | |
case <-time.After(1 * time.Second): | |
} | |
r.PrintInc() | |
} | |
} | |
func (i *resource) PrintInc() { | |
fmt.Println("Hello", atomic.AddInt32(&i.counter, 1)) | |
} | |
func NewResource() *Resource { | |
ctx, cancel := context.WithCancel(context.Background()) | |
ret := &Resource{&resource{ctx, cancel, 0}} | |
runtime.SetFinalizer(ret, (*Resource).Close) | |
go ret.resource.main() | |
return ret | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
most golang resources (like files, socket, database connection) will be automatically closed when GC kick-in,
but, the GC cannot collect any object that is referenced by any goroutine
so, the GC itself cannot collect any resource that has a goroutine attached to them,
one solution is to wrap it behind another pointer, so when the outer pointer is collected, it will close the inner goroutine
for example
will output