You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I spotted that each Scan() call leaves a couple of goroutines alive (an iterator is closed). Minimum reproducing example:
package main
import (
"context""fmt""log""runtime""time""github.com/buraksezer/olric""github.com/buraksezer/olric/config"
)
funcmain() {
// Sample for Olric v0.5.x// Deployment scenario: embedded-member// This creates a single-node Olric cluster. It's good enough for experimenting.// config.New returns a new config.Config with sane defaults. Available values for env:// local, lan, wancfg:=config.New("local")
// Callback function. It's called when this node is ready to accept connections.ready:=make(chanstruct{}, 1)
cfg.Started=func() {
ready<-struct{}{}
log.Println("[INFO] Olric is ready to accept connections")
}
// Create a new Olric instance.db, err:=olric.New(cfg)
iferr!=nil {
log.Fatalf("Failed to create Olric instance: %v", err)
}
// Start the instance. It will form a single-node cluster.gofunc() {
// Call Start at background. It's a blocker call.err=db.Start()
iferr!=nil {
log.Fatalf("olric.Start returned an error: %v", err)
}
}()
<-ready// In embedded-member scenario, you can use the EmbeddedClient. It implements// the Client interface.client:=db.NewEmbeddedClient()
dm, err:=client.NewDMap("bucket-of-arbitrary-items")
iferr!=nil {
log.Fatalf("olric.NewDMap returned an error: %v", err)
}
ctx, cancel:=context.WithTimeout(context.Background(), 10*time.Second)
// Create N key-value pairs:constN=10fori:=rangeN {
key:=fmt.Sprintf("key-%d", i)
value:=fmt.Sprintf("value-%d", i)
iferr=dm.Put(ctx, key, value); err!=nil {
log.Fatalf("DMap.Put returned an error: %v", err)
}
}
// Iterate M times over N keys:constM=10forrangeM {
iter, err:=dm.Scan(ctx)
iferr!=nil {
log.Fatalf("DMap.Scan returned an error: %v", err)
}
foriter.Next() {
// Do nothing
}
iter.Close() // close the iterator explicitly
}
// Dispose all the allocated resources:iferr:=dm.Destroy(ctx); err!=nil {
log.Fatalf("Failed to destroy DMap: %v", err)
}
iferr:=client.Close(ctx); err!=nil {
log.Fatalf("Failed to close EmbeddedClient: %v", err)
}
iferr:=db.Shutdown(ctx); err!=nil {
log.Fatalf("Failed to shutdown Olric: %v", err)
}
cancel() // cancel the context, passed to the all methods above, explicitlyruntime.GC() // run GC explicitlytime.Sleep(time.Second) // wait a bits:= runtime.MemStats{}
runtime.ReadMemStats(&s)
constKB=1<<10fmt.Printf("Non-Freed objects: %d, Mem in use(KB): %d\n", s.Mallocs-s.Frees, s.HeapAlloc/KB)
fmt.Printf("GoRoutines remained: %d\n", runtime.NumGoroutine())
}
Outputs:
Non-Freed objects: 7597, Mem in use(KB): 966
GoRoutines remained: 22
Hi!
I spotted that each Scan() call leaves a couple of goroutines alive (an iterator is closed). Minimum reproducing example:
Outputs:
Goroutines are got stuck at:
The text was updated successfully, but these errors were encountered: