Eventually consistent distributed in-memory cache Go library

Overview

bcache

godoc Build Status codecov Go Report Card Maintainability

A Go Library to create distributed in-memory cache inside your app.

Features

  • LRU cache with configurable maximum keys
  • Eventual Consistency synchronization between peers
  • Data are replicated to all nodes
  • cache filling mechanism. When the cache of the given key is not exist, bcache coordinates cache fills such that only one call populates the cache to avoid thundering herd or cache stampede

Why using it

  • if extra network hops needed by external caches like redis or memcached is not acceptable for you
  • you only need cache with simple Set, Get, and Delete operation
  • you have enough RAM to hold the cache data

How it Works

  1. Nodes find each other using Gossip Protocol

Only need to specify one or few nodes as bootstrap nodes, and all nodes will find each other using gossip protocol

  1. When there is cache Set and Delete, the event will be propagated to all of the nodes.

So, all of the nodes will eventually have synced data.

Cache filling

Cache filling mechanism is provided in GetWithFiller func.

When the cache for the given key is not exists:

  • it will call the provided Filler
  • set the cache using value returned by the Filler

Even there are many goroutines which call GetWithFiller, the given Filler func will only called once for each of the key. Cache stampede could be avoided this way.

Quick Start

In server 1

bc, err := New(Config{
	// PeerID:     1, // leave it, will be set automatically based on mac addr
	ListenAddr: "192.168.0.1:12345",
	Peers:      nil, // it nil because we will use this node as bootstrap node
	MaxKeys:    1000,
	Logger:     logrus.New(),
})
if err != nil {
    log.Fatalf("failed to create cache: %v", err)
}
bc.Set("my_key", "my_val",86400)

In server 2

bc, err := New(Config{
	// PeerID:     2, // leave it, will be set automatically based on mac addr
	ListenAddr: "192.168.0.2:12345",
	Peers:      []string{"192.168.0.1:12345"},
	MaxKeys:    1000,
	Logger:     logrus.New(),
})
if err != nil {
    log.Fatalf("failed to create cache: %v", err)
}
bc.Set("my_key2", "my_val2", 86400)

In server 3

bc, err := New(Config{
	// PeerID:     3,// will be set automatically based on mac addr
	ListenAddr: "192.168.0.3:12345",
	Peers:      []string{"192.168.0.1:12345"},
	MaxKeys:    1000,
	Logger:     logrus.New(),
})
if err != nil {
    log.Fatalf("failed to create cache: %v", err)
}
val, exists := bc.Get("my_key2")

GetWithFiller example

c, err := New(Config{
	PeerID:     3,
	ListenAddr: "192.168.0.3:12345",
	Peers:      []string{"192.168.0.1:12345"},
	MaxKeys:    1000,
})
if err != nil {
    log.Fatalf("failed to create cache: %v", err)
}
val, exp,err  := bc.GetWithFiller("my_key2",func(key string) (string, error) {
        // get value from database
         .....
         //
		return value, 0, nil
}, 86400)

Credits

Comments
  • Delete key in underlying cache when calling Delete API

    Delete key in underlying cache when calling Delete API

    When calling Delete API we currently only mark it as delete, not delete the key from underlying cache.

    The reason is that i'm still not sure when is the safe time to delete it.

    Consider this example situation, when we have three nodes:

    • Node 2 has network issue, make it unreachable by the others
    • Node 1 delete they key A
    • Node 1 broadcasts the change
    • Node 3 got the change

    What happens to node 2 when it become reachable again, will it see the change? Will mesh handle it for us?

    If we only marked it as deleted, the state will be kept by node 1 & node 3, and it will reach eventual consistency (to node 2) as promised by mesh library that used by bcache.

    enhancement 
    opened by iwanbk 6
  • message.Encode optimization

    message.Encode optimization

    some ideas:

    • [x] Need to think whether to continue using map or move to slice for the Entries(https://github.com/iwanbk/bcache/issues/16#issuecomment-488174054)
    • [x] change to other serialization, protobuf? (https://github.com/iwanbk/bcache/issues/16#issuecomment-488174054)
    • [ ] incremental encoding
    enhancement 
    opened by iwanbk 4
  • BCache + Linux Kernel 5.12 broken

    BCache + Linux Kernel 5.12 broken

    I've been using bcache + btrfs for a while on two different machines with no issue, up to kernel 5.11. After I've upgraded to kernel 5.12, I can't access the bcache device any more.

    I guess there is something to do with this.

    > uname -a 
    Linux Zerver 5.12.0-1-MANJARO #1 SMP PREEMPT Mon Apr 26 22:09:28 UTC 2021 x86_64 GNU/Linux
    
    > lsblk 
    NAME        MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
    sda           8:0    0   3.6T  0 disk 
    ├─sda1        8:1    0   512M  0 part 
    ├─sda2        8:2    0    40G  0 part 
    └─sda3        8:3    0   3.6T  0 part /backup
    sdb           8:16   0 931.5G  0 disk 
    └─sdb1        8:17   0 931.5G  0 part 
      └─bcache0 254:0    0 931.5G  0 disk /hdd
    sdc           8:32   0 238.5G  0 disk 
    ├─sdc1        8:33   0   150G  0 part /
    ├─sdc2        8:34   0    99M  0 part /boot/efi
    ├─sdc3        8:35   0  75.4G  0 part 
    │ └─bcache0 254:0    0 931.5G  0 disk /hdd
    └─sdc4        8:36   0  12.8G  0 part [SWAP]
    
    dmesg | grep -i bcache
    [   19.927658] bcache: register_bdev() registered backing device sdb1
    [   20.187699] bcache: bch_journal_replay() journal replay done, 167 keys in 6 entries, seq 1294607
    [   20.235498] bcache: bch_cached_dev_attach() Caching sdb1 as bcache0 on set c37f21c6-5f1d-4bd3-9fb0-5181a4908e08
    [   20.235544] bcache: register_cache() registered cache device sdc3
    [   20.312354] BTRFS: device label Data devid 1 transid 78169 /dev/bcache0 scanned by systemd-udevd (360)
    [   20.329275] BTRFS info (device bcache0): enabling auto defrag
    [   20.329279] BTRFS info (device bcache0): disk space caching is enabled
    [   20.329280] BTRFS info (device bcache0): has skinny extents
    [   22.940838] BTRFS info (device bcache0): enabling ssd optimizations
    [15167.365514]  cached_dev_cache_miss+0xf7/0x2f0 [bcache]
    [15167.365536]  cache_lookup_fn+0x13a/0x310 [bcache]
    [15167.365549]  ? bch_data_invalidate+0x190/0x190 [bcache]
    [15167.365562]  bch_btree_map_keys_recurse+0x9f/0x1a0 [bcache]
    [15167.365575]  ? bch_data_invalidate+0x190/0x190 [bcache]
    [15167.365588]  bch_btree_map_keys_recurse+0x11a/0x1a0 [bcache]
    [15167.365600]  bch_btree_map_keys+0x1cb/0x1f0 [bcache]
    [15167.365612]  ? bch_data_invalidate+0x190/0x190 [bcache]
    [15167.365625]  cache_lookup+0xa1/0x160 [bcache]
    [15167.365645]  cached_dev_submit_bio+0x9c1/0xd30 [bcache]
    [15167.365944] Modules linked in: udp_diag tcp_diag inet_diag xt_nat xt_tcpudp veth xt_conntrack xt_MASQUERADE nf_conntrack_netlink nfnetlink xt_addrtype iptable_filter iptable_nat nf_nat nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 br_netfilter bridge stp llc hid_logitech_hidpp joydev mousedev hid_logitech_dj usbhid snd_hda_codec_hdmi rfkill intel_rapl_msr intel_rapl_common x86_pkg_temp_thermal intel_powerclamp coretemp kvm_intel vfat fat iTCO_wdt intel_pmc_bxt mxm_wmi intel_wmi_thunderbolt overlay iTCO_vendor_support kvm irqbypass crct10dif_pclmul crc32_pclmul ghash_clmulni_intel aesni_intel crypto_simd cryptd btrfs rapl intel_cstate snd_hda_codec_realtek intel_uncore snd_hda_codec_generic blake2b_generic ledtrig_audio xor bcache raid6_pq snd_hda_intel snd_intel_dspcfg snd_intel_sdw_acpi pcspkr snd_hda_codec libcrc32c crc64 snd_hda_core snd_hwdep snd_pcm snd_timer snd mei_me i2c_i801 lpc_ich i2c_smbus e1000e mei soundcore wmi mac_hid tcp_bbr uinput nvidia_drm(POE) nvidia_modeset(POE)
    [15167.366003]  drm_kms_helper cec drm agpgart syscopyarea sysfillrect sysimgblt fb_sys_fops nvidia(POE) ipmi_devintf ipmi_msghandler vboxnetflt(OE) vboxnetadp(OE) vboxdrv(OE) crypto_user fuse ip_tables x_tables ext4 crc32c_generic crc16 mbcache jbd2 crc32c_intel xhci_pci
    
    > dmesg | grep -i btrfs
    [   20.089833] Btrfs loaded, crc32c=crc32c-intel, zoned=yes
    [   20.090760] BTRFS: device label Backup devid 1 transid 6286 /dev/sda3 scanned by systemd-udevd (343)
    [   20.263819] BTRFS info (device sda3): enabling auto defrag
    [   20.263826] BTRFS info (device sda3): disk space caching is enabled
    [   20.263827] BTRFS info (device sda3): has skinny extents
    [   20.312354] BTRFS: device label Data devid 1 transid 78169 /dev/bcache0 scanned by systemd-udevd (360)
    [   20.329275] BTRFS info (device bcache0): enabling auto defrag
    [   20.329279] BTRFS info (device bcache0): disk space caching is enabled
    [   20.329280] BTRFS info (device bcache0): has skinny extents
    [   22.940838] BTRFS info (device bcache0): enabling ssd optimizations
    [15167.365673]  btrfs_map_bio+0x19b/0x4b0 [btrfs]
    [15167.365731]  btrfs_submit_data_bio+0xbd/0x210 [btrfs]
    [15167.365768]  submit_one_bio+0x44/0x70 [btrfs]
    [15167.365809]  extent_readahead+0x3b4/0x3e0 [btrfs]
    [15167.365944] Modules linked in: udp_diag tcp_diag inet_diag xt_nat xt_tcpudp veth xt_conntrack xt_MASQUERADE nf_conntrack_netlink nfnetlink xt_addrtype iptable_filter iptable_nat nf_nat nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 br_netfilter bridge stp llc hid_logitech_hidpp joydev mousedev hid_logitech_dj usbhid snd_hda_codec_hdmi rfkill intel_rapl_msr intel_rapl_common x86_pkg_temp_thermal intel_powerclamp coretemp kvm_intel vfat fat iTCO_wdt intel_pmc_bxt mxm_wmi intel_wmi_thunderbolt overlay iTCO_vendor_support kvm irqbypass crct10dif_pclmul crc32_pclmul ghash_clmulni_intel aesni_intel crypto_simd cryptd btrfs rapl intel_cstate snd_hda_codec_realtek intel_uncore snd_hda_codec_generic blake2b_generic ledtrig_audio xor bcache raid6_pq snd_hda_intel snd_intel_dspcfg snd_intel_sdw_acpi pcspkr snd_hda_codec libcrc32c crc64 snd_hda_core snd_hwdep snd_pcm snd_timer snd mei_me i2c_i801 lpc_ich i2c_smbus e1000e mei soundcore wmi mac_hid tcp_bbr uinput nvidia_drm(POE) nvidia_modeset(POE)
    
    opened by duzun 3
  • Bcache now handles key expiration.

    Bcache now handles key expiration.

    key points:

    • expiration will be handled by bcache, previous version which basically do nothing with expiration
    • passive key deletion, data deleted when Get found that the key is expired. No GC-like mechanism at this phase, could be added later if needed
    • deletion delay: add delay before actually delete the key, it is used to handle temporary network connection issue, which prevent data syncing between nodes
    • specify ttl instead of expirationTimestamp

    Fixes #23

    opened by iwanbk 1
  • integration test: concurrent map iteration and map write

    integration test: concurrent map iteration and map write

    The integration test is supposed to be not thread safe, but there is intermittent unexpected concurrent map access there. Should do further check about this, make sure it is not from bcache

    log

    $ export GO111MODULE="auto"
    travis_time:end:05ebcc60:start=1555427327851098711,finish=1555427327932732509,duration=81633798
    $ gimme version
    v1.5.3
    $ go version
    go version go1.11.9 linux/amd64
    travis_fold:start:go.env
    $ go env
    GOARCH="amd64"
    GOBIN=""
    GOCACHE="/home/travis/.cache/go-build"
    GOEXE=""
    GOFLAGS=""
    GOHOSTARCH="amd64"
    GOHOSTOS="linux"
    GOOS="linux"
    GOPATH="/home/travis/gopath"
    GOPROXY=""
    GORACE=""
    GOROOT="/home/travis/.gimme/versions/go1.11.9.linux.amd64"
    GOTMPDIR=""
    GOTOOLDIR="/home/travis/.gimme/versions/go1.11.9.linux.amd64/pkg/tool/linux_amd64"
    GCCGO="gccgo"
    CC="gcc"
    CXX="g++"
    CGO_ENABLED="1"
    GOMOD=""
    CGO_CFLAGS="-g -O2"
    CGO_CPPFLAGS=""
    CGO_CXXFLAGS="-g -O2"
    CGO_FFLAGS="-g -O2"
    CGO_LDFLAGS="-g -O2"
    PKG_CONFIG="pkg-config"
    GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build023390760=/tmp/go-build -gno-record-gcc-switches"
    travis_fold:end:go.env
    travis_fold:start:install
    travis_time:start:2d70d67c
    $ go get -v -t
    github.com/hashicorp/golang-lru (download)
    github.com/json-iterator/go (download)
    github.com/modern-go/concurrent (download)
    github.com/modern-go/reflect2 (download)
    github.com/weaveworks/mesh (download)
    Fetching https://golang.org/x/crypto/nacl/box?go-get=1
    Parsing meta tags from https://golang.org/x/crypto/nacl/box?go-get=1 (status code 200)
    get "golang.org/x/crypto/nacl/box": found meta tag get.metaImport{Prefix:"golang.org/x/crypto", VCS:"git", RepoRoot:"https://go.googlesource.com/crypto"} at https://golang.org/x/crypto/nacl/box?go-get=1
    get "golang.org/x/crypto/nacl/box": verifying non-authoritative meta tag
    Fetching https://golang.org/x/crypto?go-get=1
    Parsing meta tags from https://golang.org/x/crypto?go-get=1 (status code 200)
    golang.org/x/crypto (download)
    Fetching https://golang.org/x/crypto/nacl/secretbox?go-get=1
    Parsing meta tags from https://golang.org/x/crypto/nacl/secretbox?go-get=1 (status code 200)
    get "golang.org/x/crypto/nacl/secretbox": found meta tag get.metaImport{Prefix:"golang.org/x/crypto", VCS:"git", RepoRoot:"https://go.googlesource.com/crypto"} at https://golang.org/x/crypto/nacl/secretbox?go-get=1
    get "golang.org/x/crypto/nacl/secretbox": verifying non-authoritative meta tag
    Fetching https://golang.org/x/sync/singleflight?go-get=1
    Parsing meta tags from https://golang.org/x/sync/singleflight?go-get=1 (status code 200)
    get "golang.org/x/sync/singleflight": found meta tag get.metaImport{Prefix:"golang.org/x/sync", VCS:"git", RepoRoot:"https://go.googlesource.com/sync"} at https://golang.org/x/sync/singleflight?go-get=1
    get "golang.org/x/sync/singleflight": verifying non-authoritative meta tag
    Fetching https://golang.org/x/sync?go-get=1
    Parsing meta tags from https://golang.org/x/sync?go-get=1 (status code 200)
    golang.org/x/sync (download)
    github.com/sirupsen/logrus (download)
    Fetching https://golang.org/x/sys/unix?go-get=1
    Parsing meta tags from https://golang.org/x/sys/unix?go-get=1 (status code 200)
    get "golang.org/x/sys/unix": found meta tag get.metaImport{Prefix:"golang.org/x/sys", VCS:"git", RepoRoot:"https://go.googlesource.com/sys"} at https://golang.org/x/sys/unix?go-get=1
    get "golang.org/x/sys/unix": verifying non-authoritative meta tag
    Fetching https://golang.org/x/sys?go-get=1
    Parsing meta tags from https://golang.org/x/sys?go-get=1 (status code 200)
    golang.org/x/sys (download)
    github.com/stretchr/testify (download)
    github.com/hashicorp/golang-lru/simplelru
    github.com/hashicorp/golang-lru
    github.com/modern-go/concurrent
    github.com/modern-go/reflect2
    golang.org/x/crypto/curve25519
    golang.org/x/crypto/internal/subtle
    golang.org/x/crypto/poly1305
    golang.org/x/crypto/salsa20/salsa
    golang.org/x/crypto/nacl/secretbox
    golang.org/x/crypto/nacl/box
    github.com/weaveworks/mesh
    github.com/json-iterator/go
    golang.org/x/sync/singleflight
    github.com/iwanbk/bcache
    travis_time:end:2d70d67c:start=1555427328004585270,finish=1555427336379863770,duration=8375278500
    travis_fold:end:install
    travis_time:start:091201e1
    $ go build
    travis_time:end:091201e1:start=1555427336384722777,finish=1555427336502743696,duration=118020919
    The command "go build" exited with 0.
    
    travis_time:start:01f7757e
    $ go test -race -coverprofile=coverage.txt -covermode=atomic
    PASS
    coverage: 49.5% of statements
    ok  	github.com/iwanbk/bcache	1.031s
    travis_time:end:01f7757e:start=1555427336508045718,finish=1555427346309279719,duration=9801234001
    The command "go test -race -coverprofile=coverage.txt -covermode=atomic" exited with 0.
    
    travis_time:start:00be5070
    $ go test -tags integration -coverprofile=coverage.txt -covermode=atomic
    fatal error: concurrent map iteration and map write
    
    goroutine 29 [running]:
    runtime.throw(0x884cd0, 0x26)
    	/home/travis/.gimme/versions/go1.11.9.linux.amd64/src/runtime/panic.go:608 +0x72 fp=0xc00018f918 sp=0xc00018f8e8 pc=0x42db62
    runtime.mapiternext(0xc000272b40)
    	/home/travis/.gimme/versions/go1.11.9.linux.amd64/src/runtime/map.go:790 +0x525 fp=0xc00018f9a0 sp=0xc00018f918 pc=0x410555
    reflect.mapiternext(0xc000272b40)
    	/home/travis/.gimme/versions/go1.11.9.linux.amd64/src/runtime/map.go:1277 +0x2b fp=0xc00018f9b8 sp=0xc00018f9a0 pc=0x4113fb
    github.com/modern-go/reflect2.(*UnsafeMapIterator).UnsafeNext(0xc0002c7340, 0x0, 0x40)
    	/home/travis/gopath/src/github.com/modern-go/reflect2/unsafe_map.go:136 +0x41 fp=0xc00018f9e0 sp=0xc00018f9b8 pc=0x60e441
    github.com/json-iterator/go.(*sortKeysMapEncoder).Encode(0xc0001bec30, 0xc000155550, 0xc00012f320)
    	/home/travis/gopath/src/github.com/json-iterator/go/reflect_map.go:293 +0x1b2 fp=0xc00018fb40 sp=0xc00018f9e0 pc=0x6594b2
    github.com/json-iterator/go.(*structFieldEncoder).Encode(0xc0001becf0, 0xc000155530, 0xc00012f320)
    	/home/travis/gopath/src/github.com/json-iterator/go/reflect_struct_encoder.go:110 +0x7b fp=0xc00018fbc8 sp=0xc00018fb40 pc=0x667bcb
    github.com/json-iterator/go.(*structEncoder).Encode(0xc0001bed50, 0xc000155530, 0xc00012f320)
    	/home/travis/gopath/src/github.com/json-iterator/go/reflect_struct_encoder.go:158 +0x2c9 fp=0xc00018fc78 sp=0xc00018fbc8 pc=0x668179
    github.com/json-iterator/go.(*OptionalEncoder).Encode(0xc000139830, 0xc00027e348, 0xc00012f320)
    	/home/travis/gopath/src/github.com/json-iterator/go/reflect_optional.go:74 +0xe9 fp=0xc00018fcc8 sp=0xc00018fc78 pc=0x65ea59
    github.com/json-iterator/go.(*onePtrEncoder).Encode(0xc000139840, 0xc000155530, 0xc00012f320)
    	/home/travis/gopath/src/github.com/json-iterator/go/reflect.go:214 +0x68 fp=0xc00018fcf0 sp=0xc00018fcc8 pc=0x650b48
    github.com/json-iterator/go.(*Stream).WriteVal(0xc00012f320, 0x8165a0, 0xc000155530)
    	/home/travis/gopath/src/github.com/json-iterator/go/reflect.go:93 +0x118 fp=0xc00018fd50 sp=0xc00018fcf0 pc=0x64faf8
    github.com/json-iterator/go.(*frozenConfig).Marshal(0xc0000ae1e0, 0x8165a0, 0xc000155530, 0x0, 0x0, 0x0, 0x0, 0x0)
    	/home/travis/gopath/src/github.com/json-iterator/go/config.go:299 +0xac fp=0xc00018fdc0 sp=0xc00018fd50 pc=0x6461fc
    github.com/json-iterator/go.API.Marshal-fm(0x8165a0, 0xc000155530, 0xc000155530, 0xc000144cf0, 0xc0000dd380, 0xc0000dd380, 0x0)
    	/home/travis/gopath/src/github.com/iwanbk/bcache/json.go:7 +0x43 fp=0xc00018fe10 sp=0xc00018fdc0 pc=0x7927e3
    github.com/iwanbk/bcache.(*message).Encode(0xc000155530, 0x0, 0x0, 0x0)
    	/home/travis/gopath/src/github.com/iwanbk/bcache/message.go:67 +0xa0 fp=0xc00018fe80 sp=0xc00018fe10 pc=0x788790
    github.com/weaveworks/mesh.(*gossipSender).deliver(0xc000132320, 0xc000158060, 0x3, 0x1, 0x1)
    	/home/travis/gopath/src/github.com/weaveworks/mesh/gossip.go:144 +0x88 fp=0xc00018fef0 sp=0xc00018fe80 pc=0x5ed778
    github.com/weaveworks/mesh.(*gossipSender).run(0xc000132320, 0xc000158060, 0xc000158240, 0xc0001582a0)
    	/home/travis/gopath/src/github.com/weaveworks/mesh/gossip.go:105 +0x1c5 fp=0xc00018ffc0 sp=0xc00018fef0 pc=0x5ed6a5
    runtime.goexit()
    	/home/travis/.gimme/versions/go1.11.9.linux.amd64/src/runtime/asm_amd64.s:1333 +0x1 fp=0xc00018ffc8 sp=0xc00018ffc0 pc=0x45ce71
    created by github.com/weaveworks/mesh.newGossipSender
    	/home/travis/gopath/src/github.com/weaveworks/mesh/gossip.go:94 +0x118
    
    goroutine 1 [chan receive]:
    testing.(*T).Run(0xc0000d4200, 0x87ac92, 0xf, 0x890528, 0x47c7b6)
    	/home/travis/.gimme/versions/go1.11.9.linux.amd64/src/testing/testing.go:879 +0x383
    testing.runTests.func1(0xc0000d4100)
    	/home/travis/.gimme/versions/go1.11.9.linux.amd64/src/testing/testing.go:1119 +0x78
    testing.tRunner(0xc0000d4100, 0xc0000a1da0)
    	/home/travis/.gimme/versions/go1.11.9.linux.amd64/src/testing/testing.go:827 +0xbf
    testing.runTests(0xc00000d240, 0xbd1ae0, 0xb, 0xb, 0x40d55f)
    	/home/travis/.gimme/versions/go1.11.9.linux.amd64/src/testing/testing.go:1117 +0x2aa
    testing.(*M).Run(0xc000122000, 0x0)
    	/home/travis/.gimme/versions/go1.11.9.linux.amd64/src/testing/testing.go:1034 +0x165
    main.main()
    	_testmain.go:124 +0x205
    
    goroutine 5 [chan receive]:
    github.com/iwanbk/bcache.(*peer).Delete(0xc000075fc0, 0xc000026c80, 0x5, 0x1595fcf156964cf2, 0xbf2599e7ef77d6f2)
    	/home/travis/gopath/src/github.com/iwanbk/bcache/peer.go:142 +0xf9
    github.com/iwanbk/bcache.(*Bcache).Delete(0xc00012c040, 0xc000026c80, 0x5)
    	/home/travis/gopath/src/github.com/iwanbk/bcache/bcache.go:128 +0xbb
    github.com/iwanbk/bcache.TestIntegration(0xc0000d4200)
    	/home/travis/gopath/src/github.com/iwanbk/bcache/bcache_test.go:108 +0xbd1
    testing.tRunner(0xc0000d4200, 0x890528)
    	/home/travis/.gimme/versions/go1.11.9.linux.amd64/src/testing/testing.go:827 +0xbf
    created by testing.(*T).Run
    	/home/travis/.gimme/versions/go1.11.9.linux.amd64/src/testing/testing.go:878 +0x35c
    
    goroutine 6 [select]:
    github.com/weaveworks/mesh.(*localPeer).actorLoop(0xc0000e6990, 0xc000076480)
    	/home/travis/gopath/src/github.com/weaveworks/mesh/local_peer.go:141 +0xcf
    created by github.com/weaveworks/mesh.newLocalPeer
    	/home/travis/gopath/src/github.com/weaveworks/mesh/local_peer.go:31 +0x105
    
    goroutine 7 [select]:
    github.com/weaveworks/mesh.(*routes).run(0xc000122100, 0xc0000765a0, 0xc000030600, 0xc000030660)
    	/home/travis/gopath/src/github.com/weaveworks/mesh/routes.go:177 +0xfb
    created by github.com/weaveworks/mesh.newRoutes
    	/home/travis/gopath/src/github.com/weaveworks/mesh/routes.go:44 +0x2e9
    
    goroutine 8 [select]:
    github.com/weaveworks/mesh.(*connectionMaker).queryLoop(0xc0000c49a0, 0xc000076600)
    	/home/travis/gopath/src/github.com/weaveworks/mesh/connection_maker.go:226 +0x107
    created by github.com/weaveworks/mesh.newConnectionMaker
    	/home/travis/gopath/src/github.com/weaveworks/mesh/connection_maker.go:75 +0x148
    
    goroutine 9 [runnable]:
    github.com/iwanbk/bcache.(*message).mergeComplete(0xc0001558f0, 0xc000155980, 0x0, 0x0)
    	/home/travis/gopath/src/github.com/iwanbk/bcache/message.go:90 +0x27a
    github.com/iwanbk/bcache.(*message).Merge(0xc0001558f0, 0x8e3c60, 0xc000155980, 0xc00027a458, 0xc000132601)
    	/home/travis/gopath/src/github.com/iwanbk/bcache/message.go:76 +0x5a
    github.com/weaveworks/mesh.(*gossipSender).Broadcast(0xc0001326e0, 0x1, 0x8e3c60, 0xc000155980)
    	/home/travis/gopath/src/github.com/weaveworks/mesh/gossip.go:199 +0xd0
    github.com/weaveworks/mesh.(*gossipChannel).relayBroadcast(0xc00012c000, 0x1, 0x8e3c60, 0xc000155980)
    	/home/travis/gopath/src/github.com/weaveworks/mesh/gossip_channel.go:110 +0x162
    github.com/weaveworks/mesh.(*gossipChannel).GossipBroadcast(0xc00012c000, 0x8e3c60, 0xc000155980)
    	/home/travis/gopath/src/github.com/weaveworks/mesh/gossip_channel.go:83 +0x4f
    github.com/iwanbk/bcache.(*peer).broadcast(0xc000075fc0, 0xc000155980)
    	/home/travis/gopath/src/github.com/iwanbk/bcache/peer.go:165 +0x75
    github.com/iwanbk/bcache.(*peer).Delete.func1()
    	/home/travis/gopath/src/github.com/iwanbk/bcache/peer.go:139 +0x207
    github.com/iwanbk/bcache.(*peer).loop(0xc000075fc0)
    	/home/travis/gopath/src/github.com/iwanbk/bcache/peer.go:154 +0x5b
    created by github.com/iwanbk/bcache.newPeer
    	/home/travis/gopath/src/github.com/iwanbk/bcache/peer.go:30 +0x151
    
    goroutine 10 [IO wait]:
    internal/poll.runtime_pollWait(0x7f9111d08f00, 0x72, 0x0)
    	/home/travis/.gimme/versions/go1.11.9.linux.amd64/src/runtime/netpoll.go:173 +0x66
    internal/poll.(*pollDesc).wait(0xc000122298, 0x72, 0xc000142000, 0x0, 0x0)
    	/home/travis/.gimme/versions/go1.11.9.linux.amd64/src/internal/poll/fd_poll_runtime.go:85 +0x9a
    internal/poll.(*pollDesc).waitRead(0xc000122298, 0xffffffffffffff00, 0x0, 0x0)
    	/home/travis/.gimme/versions/go1.11.9.linux.amd64/src/internal/poll/fd_poll_runtime.go:90 +0x3d
    internal/poll.(*FD).Accept(0xc000122280, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0)
    	/home/travis/.gimme/versions/go1.11.9.linux.amd64/src/internal/poll/fd_unix.go:384 +0x1a0
    net.(*netFD).accept(0xc000122280, 0x35a4e900, 0xed447e70e, 0xbd75a0)
    	/home/travis/.gimme/versions/go1.11.9.linux.amd64/src/net/fd_unix.go:238 +0x42
    net.(*TCPListener).accept(0xc00000e730, 0xbd75a0, 0x29b92700, 0xed447e70e)
    	/home/travis/.gimme/versions/go1.11.9.linux.amd64/src/net/tcpsock_posix.go:139 +0x2e
    net.(*TCPListener).AcceptTCP(0xc00000e730, 0xc000134e18, 0x0, 0x0)
    	/home/travis/.gimme/versions/go1.11.9.linux.amd64/src/net/tcpsock.go:247 +0x47
    github.com/weaveworks/mesh.(*Router).listenTCP.func1(0xc00000e730, 0xc0000dca90)
    	/home/travis/gopath/src/github.com/weaveworks/mesh/router.go:113 +0x59
    created by github.com/weaveworks/mesh.(*Router).listenTCP
    	/home/travis/gopath/src/github.com/weaveworks/mesh/router.go:110 +0x152
    
    goroutine 11 [select]:
    github.com/weaveworks/mesh.(*localPeer).actorLoop(0xc0000e6db0, 0xc000076780)
    	/home/travis/gopath/src/github.com/weaveworks/mesh/local_peer.go:141 +0xcf
    created by github.com/weaveworks/mesh.newLocalPeer
    	/home/travis/gopath/src/github.com/weaveworks/mesh/local_peer.go:31 +0x105
    
    goroutine 12 [select]:
    github.com/weaveworks/mesh.(*routes).run(0xc000122380, 0xc0000768a0, 0xc000030780, 0xc0000307e0)
    	/home/travis/gopath/src/github.com/weaveworks/mesh/routes.go:177 +0xfb
    created by github.com/weaveworks/mesh.newRoutes
    	/home/travis/gopath/src/github.com/weaveworks/mesh/routes.go:44 +0x2e9
    
    goroutine 13 [select]:
    github.com/weaveworks/mesh.(*connectionMaker).queryLoop(0xc0000c4a10, 0xc000076900)
    	/home/travis/gopath/src/github.com/weaveworks/mesh/connection_maker.go:226 +0x107
    created by github.com/weaveworks/mesh.newConnectionMaker
    	/home/travis/gopath/src/github.com/weaveworks/mesh/connection_maker.go:75 +0x148
    
    goroutine 14 [select]:
    github.com/iwanbk/bcache.(*peer).loop(0xc00012c0c0)
    	/home/travis/gopath/src/github.com/iwanbk/bcache/peer.go:152 +0xef
    created by github.com/iwanbk/bcache.newPeer
    	/home/travis/gopath/src/github.com/iwanbk/bcache/peer.go:30 +0x151
    
    goroutine 15 [IO wait]:
    internal/poll.runtime_pollWait(0x7f9111d08e30, 0x72, 0x0)
    	/home/travis/.gimme/versions/go1.11.9.linux.amd64/src/runtime/netpoll.go:173 +0x66
    internal/poll.(*pollDesc).wait(0xc000122498, 0x72, 0xc000142000, 0x0, 0x0)
    	/home/travis/.gimme/versions/go1.11.9.linux.amd64/src/internal/poll/fd_poll_runtime.go:85 +0x9a
    internal/poll.(*pollDesc).waitRead(0xc000122498, 0xffffffffffffff00, 0x0, 0x0)
    	/home/travis/.gimme/versions/go1.11.9.linux.amd64/src/internal/poll/fd_poll_runtime.go:90 +0x3d
    internal/poll.(*FD).Accept(0xc000122480, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0)
    	/home/travis/.gimme/versions/go1.11.9.linux.amd64/src/internal/poll/fd_unix.go:384 +0x1a0
    net.(*netFD).accept(0xc000122480, 0x2faf0800, 0xed447e70e, 0xbd75a0)
    	/home/travis/.gimme/versions/go1.11.9.linux.amd64/src/net/fd_unix.go:238 +0x42
    net.(*TCPListener).accept(0xc00000e748, 0xbd75a0, 0x29b92700, 0xed447e70e)
    	/home/travis/.gimme/versions/go1.11.9.linux.amd64/src/net/tcpsock_posix.go:139 +0x2e
    net.(*TCPListener).AcceptTCP(0xc00000e748, 0xc000135ab8, 0x0, 0x0)
    	/home/travis/.gimme/versions/go1.11.9.linux.amd64/src/net/tcpsock.go:247 +0x47
    github.com/weaveworks/mesh.(*Router).listenTCP.func1(0xc00000e748, 0xc0000dcc30)
    	/home/travis/gopath/src/github.com/weaveworks/mesh/router.go:113 +0x59
    created by github.com/weaveworks/mesh.(*Router).listenTCP
    	/home/travis/gopath/src/github.com/weaveworks/mesh/router.go:110 +0x152
    
    goroutine 16 [select]:
    github.com/weaveworks/mesh.(*localPeer).actorLoop(0xc0000e7200, 0xc000076a20)
    	/home/travis/gopath/src/github.com/weaveworks/mesh/local_peer.go:141 +0xcf
    created by github.com/weaveworks/mesh.newLocalPeer
    	/home/travis/gopath/src/github.com/weaveworks/mesh/local_peer.go:31 +0x105
    
    goroutine 34 [select]:
    github.com/weaveworks/mesh.(*routes).run(0xc000122580, 0xc000076b40, 0xc000030900, 0xc000030960)
    	/home/travis/gopath/src/github.com/weaveworks/mesh/routes.go:177 +0xfb
    created by github.com/weaveworks/mesh.newRoutes
    	/home/travis/gopath/src/github.com/weaveworks/mesh/routes.go:44 +0x2e9
    
    goroutine 35 [select]:
    github.com/weaveworks/mesh.(*connectionMaker).queryLoop(0xc0000c4a80, 0xc000076ba0)
    	/home/travis/gopath/src/github.com/weaveworks/mesh/connection_maker.go:226 +0x107
    created by github.com/weaveworks/mesh.newConnectionMaker
    	/home/travis/gopath/src/github.com/weaveworks/mesh/connection_maker.go:75 +0x148
    
    goroutine 36 [select]:
    github.com/iwanbk/bcache.(*peer).loop(0xc00012c1c0)
    	/home/travis/gopath/src/github.com/iwanbk/bcache/peer.go:152 +0xef
    created by github.com/iwanbk/bcache.newPeer
    	/home/travis/gopath/src/github.com/iwanbk/bcache/peer.go:30 +0x151
    
    goroutine 37 [IO wait]:
    internal/poll.runtime_pollWait(0x7f9111d08d60, 0x72, 0x0)
    	/home/travis/.gimme/versions/go1.11.9.linux.amd64/src/runtime/netpoll.go:173 +0x66
    internal/poll.(*pollDesc).wait(0xc000122698, 0x72, 0xc0001f5300, 0x0, 0x0)
    	/home/travis/.gimme/versions/go1.11.9.linux.amd64/src/internal/poll/fd_poll_runtime.go:85 +0x9a
    internal/poll.(*pollDesc).waitRead(0xc000122698, 0xffffffffffffff00, 0x0, 0x0)
    	/home/travis/.gimme/versions/go1.11.9.linux.amd64/src/internal/poll/fd_poll_runtime.go:90 +0x3d
    internal/poll.(*FD).Accept(0xc000122680, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0)
    	/home/travis/.gimme/versions/go1.11.9.linux.amd64/src/internal/poll/fd_unix.go:384 +0x1a0
    net.(*netFD).accept(0xc000122680, 0x2faf0800, 0xed447e70e, 0xbd75a0)
    	/home/travis/.gimme/versions/go1.11.9.linux.amd64/src/net/fd_unix.go:238 +0x42
    net.(*TCPListener).accept(0xc00000e760, 0xbd75a0, 0x29b92700, 0xed447e70e)
    	/home/travis/.gimme/versions/go1.11.9.linux.amd64/src/net/tcpsock_posix.go:139 +0x2e
    net.(*TCPListener).AcceptTCP(0xc00000e760, 0xc00027e088, 0x0, 0x0)
    	/home/travis/.gimme/versions/go1.11.9.linux.amd64/src/net/tcpsock.go:247 +0x47
    github.com/weaveworks/mesh.(*Router).listenTCP.func1(0xc00000e760, 0xc0000dcea0)
    	/home/travis/gopath/src/github.com/weaveworks/mesh/router.go:113 +0x59
    created by github.com/weaveworks/mesh.(*Router).listenTCP
    	/home/travis/gopath/src/github.com/weaveworks/mesh/router.go:110 +0x152
    
    goroutine 22 [select]:
    github.com/weaveworks/mesh.(*LocalConnection).actorLoop(0xc00015e0a0, 0xc00012e780, 0xc00015e0a0, 0x8e2060)
    	/home/travis/gopath/src/github.com/weaveworks/mesh/connection.go:354 +0x292
    github.com/weaveworks/mesh.(*LocalConnection).run(0xc00015e0a0, 0xc00012e780, 0xc000158060, 0xc000051f01)
    	/home/travis/gopath/src/github.com/weaveworks/mesh/connection.go:256 +0x752
    created by github.com/weaveworks/mesh.startLocalConnection
    	/home/travis/gopath/src/github.com/weaveworks/mesh/connection.go:99 +0x1fe
    
    goroutine 20 [select]:
    github.com/weaveworks/mesh.(*LocalConnection).actorLoop(0xc00015e000, 0xc00012e6c0, 0xc00015e000, 0x8e2060)
    	/home/travis/gopath/src/github.com/weaveworks/mesh/connection.go:354 +0x292
    github.com/weaveworks/mesh.(*LocalConnection).run(0xc00015e000, 0xc00012e6c0, 0xc000158000, 0x1)
    	/home/travis/gopath/src/github.com/weaveworks/mesh/connection.go:256 +0x752
    created by github.com/weaveworks/mesh.startLocalConnection
    	/home/travis/gopath/src/github.com/weaveworks/mesh/connection.go:99 +0x1fe
    
    goroutine 28 [select]:
    github.com/weaveworks/mesh.(*gossipSender).run(0xc0001322d0, 0xc000158060, 0xc000158180, 0xc0001581e0)
    	/home/travis/gopath/src/github.com/weaveworks/mesh/gossip.go:101 +0xeb
    created by github.com/weaveworks/mesh.newGossipSender
    	/home/travis/gopath/src/github.com/weaveworks/mesh/gossip.go:94 +0x118
    
    goroutine 30 [IO wait]:
    internal/poll.runtime_pollWait(0x7f9111d08bc0, 0x72, 0xc000217d10)
    	/home/travis/.gimme/versions/go1.11.9.linux.amd64/src/runtime/netpoll.go:173 +0x66
    internal/poll.(*pollDesc).wait(0xc00014c098, 0x72, 0xffffffffffffff00, 0x8e2da0, 0xb9d4f0)
    	/home/travis/.gimme/versions/go1.11.9.linux.amd64/src/internal/poll/fd_poll_runtime.go:85 +0x9a
    internal/poll.(*pollDesc).waitRead(0xc00014c098, 0xc0002c4100, 0x4, 0x4)
    	/home/travis/.gimme/versions/go1.11.9.linux.amd64/src/internal/poll/fd_poll_runtime.go:90 +0x3d
    internal/poll.(*FD).Read(0xc00014c080, 0xc0002c4180, 0x4, 0x4, 0x0, 0x0, 0x0)
    	/home/travis/.gimme/versions/go1.11.9.linux.amd64/src/internal/poll/fd_unix.go:169 +0x179
    net.(*netFD).Read(0xc00014c080, 0xc0002c4180, 0x4, 0x4, 0xc000132200, 0xc000217e10, 0xc000217e50)
    	/home/travis/.gimme/versions/go1.11.9.linux.amd64/src/net/fd_unix.go:202 +0x4f
    net.(*conn).Read(0xc000134010, 0xc0002c4180, 0x4, 0x4, 0x0, 0x0, 0x0)
    	/home/travis/.gimme/versions/go1.11.9.linux.amd64/src/net/net.go:177 +0x68
    io.ReadAtLeast(0x8e2220, 0xc000134010, 0xc0002c4180, 0x4, 0x4, 0x4, 0x7d73e0, 0x1, 0xc0002c4180)
    	/home/travis/.gimme/versions/go1.11.9.linux.amd64/src/io/io.go:310 +0x88
    io.ReadFull(0x8e2220, 0xc000134010, 0xc0002c4180, 0x4, 0x4, 0x4, 0xc000217f38, 0x3c)
    	/home/travis/.gimme/versions/go1.11.9.linux.amd64/src/io/io.go:329 +0x58
    github.com/weaveworks/mesh.(*lengthPrefixTCPReceiver).Receive(0xc000138310, 0x0, 0x0, 0xfec, 0xfec, 0x0)
    	/home/travis/gopath/src/github.com/weaveworks/mesh/protocol_crypto.go:168 +0x96
    github.com/weaveworks/mesh.(*LocalConnection).receiveTCP(0xc00015e0a0, 0x8e2060, 0xc000138310)
    	/home/travis/gopath/src/github.com/weaveworks/mesh/connection.go:420 +0x56
    created by github.com/weaveworks/mesh.(*LocalConnection).run
    	/home/travis/gopath/src/github.com/weaveworks/mesh/connection.go:247 +0x734
    
    goroutine 31 [select]:
    github.com/weaveworks/mesh.(*gossipSender).run(0xc0001324b0, 0xc000158000, 0xc000158540, 0xc0001585a0)
    	/home/travis/gopath/src/github.com/weaveworks/mesh/gossip.go:101 +0xeb
    created by github.com/weaveworks/mesh.newGossipSender
    	/home/travis/gopath/src/github.com/weaveworks/mesh/gossip.go:94 +0x118
    
    goroutine 32 [select]:
    github.com/weaveworks/mesh.(*gossipSender).run(0xc000132500, 0xc000158000, 0xc000158600, 0xc000158660)
    	/home/travis/gopath/src/github.com/weaveworks/mesh/gossip.go:101 +0xeb
    created by github.com/weaveworks/mesh.newGossipSender
    	/home/travis/gopath/src/github.com/weaveworks/mesh/gossip.go:94 +0x118
    
    goroutine 33 [IO wait]:
    internal/poll.runtime_pollWait(0x7f9111d08c90, 0x72, 0xc0001e3d10)
    	/home/travis/.gimme/versions/go1.11.9.linux.amd64/src/runtime/netpoll.go:173 +0x66
    internal/poll.(*pollDesc).wait(0xc00014c018, 0x72, 0xffffffffffffff00, 0x8e2da0, 0xb9d4f0)
    	/home/travis/.gimme/versions/go1.11.9.linux.amd64/src/internal/poll/fd_poll_runtime.go:85 +0x9a
    internal/poll.(*pollDesc).waitRead(0xc00014c018, 0xc000250f00, 0x4, 0x4)
    	/home/travis/.gimme/versions/go1.11.9.linux.amd64/src/internal/poll/fd_poll_runtime.go:90 +0x3d
    internal/poll.(*FD).Read(0xc00014c000, 0xc000250f5c, 0x4, 0x4, 0x0, 0x0, 0x0)
    	/home/travis/.gimme/versions/go1.11.9.linux.amd64/src/internal/poll/fd_unix.go:169 +0x179
    net.(*netFD).Read(0xc00014c000, 0xc000250f5c, 0x4, 0x4, 0xc000132100, 0xc0001e3e10, 0xc0001e3e50)
    	/home/travis/.gimme/versions/go1.11.9.linux.amd64/src/net/fd_unix.go:202 +0x4f
    net.(*conn).Read(0xc000134008, 0xc000250f5c, 0x4, 0x4, 0x0, 0x0, 0x0)
    	/home/travis/.gimme/versions/go1.11.9.linux.amd64/src/net/net.go:177 +0x68
    io.ReadAtLeast(0x8e2220, 0xc000134008, 0xc000250f5c, 0x4, 0x4, 0x4, 0x7d73e0, 0x1, 0xc000250f5c)
    	/home/travis/.gimme/versions/go1.11.9.linux.amd64/src/io/io.go:310 +0x88
    io.ReadFull(0x8e2220, 0xc000134008, 0xc000250f5c, 0x4, 0x4, 0x4, 0xc0001e3f38, 0x3c)
    	/home/travis/.gimme/versions/go1.11.9.linux.amd64/src/io/io.go:329 +0x58
    github.com/weaveworks/mesh.(*lengthPrefixTCPReceiver).Receive(0xc000138100, 0x0, 0x0, 0x1a3, 0x1a3, 0x0)
    	/home/travis/gopath/src/github.com/weaveworks/mesh/protocol_crypto.go:168 +0x96
    github.com/weaveworks/mesh.(*LocalConnection).receiveTCP(0xc00015e000, 0x8e2060, 0xc000138100)
    	/home/travis/gopath/src/github.com/weaveworks/mesh/connection.go:420 +0x56
    created by github.com/weaveworks/mesh.(*LocalConnection).run
    	/home/travis/gopath/src/github.com/weaveworks/mesh/connection.go:247 +0x734
    
    goroutine 53 [select]:
    github.com/weaveworks/mesh.(*LocalConnection).actorLoop(0xc00015ea00, 0xc00021a420, 0xc00015ea00, 0x8e2060)
    	/home/travis/gopath/src/github.com/weaveworks/mesh/connection.go:354 +0x292
    github.com/weaveworks/mesh.(*LocalConnection).run(0xc00015ea00, 0xc00021a420, 0xc000158b40, 0xc00005ff01)
    	/home/travis/gopath/src/github.com/weaveworks/mesh/connection.go:256 +0x752
    created by github.com/weaveworks/mesh.startLocalConnection
    	/home/travis/gopath/src/github.com/weaveworks/mesh/connection.go:99 +0x1fe
    
    goroutine 51 [select]:
    github.com/weaveworks/mesh.(*LocalConnection).actorLoop(0xc00015e960, 0xc00021a360, 0xc00015e960, 0x8e2060)
    	/home/travis/gopath/src/github.com/weaveworks/mesh/connection.go:354 +0x292
    github.com/weaveworks/mesh.(*LocalConnection).run(0xc00015e960, 0xc00021a360, 0xc000158ae0, 0x1)
    	/home/travis/gopath/src/github.com/weaveworks/mesh/connection.go:256 +0x752
    created by github.com/weaveworks/mesh.startLocalConnection
    	/home/travis/gopath/src/github.com/weaveworks/mesh/connection.go:99 +0x1fe
    
    goroutine 59 [runnable]:
    github.com/weaveworks/mesh.(*gossipSender).run(0xc0001326e0, 0xc000158b40, 0xc000158c60, 0xc000158cc0)
    	/home/travis/gopath/src/github.com/weaveworks/mesh/gossip.go:101 +0xeb
    created by github.com/weaveworks/mesh.newGossipSender
    	/home/travis/gopath/src/github.com/weaveworks/mesh/gossip.go:94 +0x118
    
    goroutine 60 [select]:
    github.com/weaveworks/mesh.(*gossipSender).run(0xc000132730, 0xc000158b40, 0xc000158d20, 0xc000158d80)
    	/home/travis/gopath/src/github.com/weaveworks/mesh/gossip.go:101 +0xeb
    created by github.com/weaveworks/mesh.newGossipSender
    	/home/travis/gopath/src/github.com/weaveworks/mesh/gossip.go:94 +0x118
    
    goroutine 61 [IO wait]:
    internal/poll.runtime_pollWait(0x7f9111d08a20, 0x72, 0xc000267d10)
    	/home/travis/.gimme/versions/go1.11.9.linux.amd64/src/runtime/netpoll.go:173 +0x66
    internal/poll.(*pollDesc).wait(0xc000205a98, 0x72, 0xffffffffffffff00, 0x8e2da0, 0xb9d4f0)
    	/home/travis/.gimme/versions/go1.11.9.linux.amd64/src/internal/poll/fd_poll_runtime.go:85 +0x9a
    internal/poll.(*pollDesc).waitRead(0xc000205a98, 0xc000250800, 0x4, 0x4)
    	/home/travis/.gimme/versions/go1.11.9.linux.amd64/src/internal/poll/fd_poll_runtime.go:90 +0x3d
    internal/poll.(*FD).Read(0xc000205a80, 0xc0002508c0, 0x4, 0x4, 0x0, 0x0, 0x0)
    	/home/travis/.gimme/versions/go1.11.9.linux.amd64/src/internal/poll/fd_unix.go:169 +0x179
    net.(*netFD).Read(0xc000205a80, 0xc0002508c0, 0x4, 0x4, 0xc000132100, 0xc000267e10, 0xc000267e50)
    	/home/travis/.gimme/versions/go1.11.9.linux.amd64/src/net/fd_unix.go:202 +0x4f
    net.(*conn).Read(0xc000134e18, 0xc0002508c0, 0x4, 0x4, 0x0, 0x0, 0x0)
    	/home/travis/.gimme/versions/go1.11.9.linux.amd64/src/net/net.go:177 +0x68
    io.ReadAtLeast(0x8e2220, 0xc000134e18, 0xc0002508c0, 0x4, 0x4, 0x4, 0x7d73e0, 0x1, 0xc0002508c0)
    	/home/travis/.gimme/versions/go1.11.9.linux.amd64/src/io/io.go:310 +0x88
    io.ReadFull(0x8e2220, 0xc000134e18, 0xc0002508c0, 0x4, 0x4, 0x4, 0xc000267f38, 0x3c)
    	/home/travis/.gimme/versions/go1.11.9.linux.amd64/src/io/io.go:329 +0x58
    github.com/weaveworks/mesh.(*lengthPrefixTCPReceiver).Receive(0xc0001fdd20, 0x0, 0x0, 0x2b, 0x2b, 0x0)
    	/home/travis/gopath/src/github.com/weaveworks/mesh/protocol_crypto.go:168 +0x96
    github.com/weaveworks/mesh.(*LocalConnection).receiveTCP(0xc00015ea00, 0x8e2060, 0xc0001fdd20)
    	/home/travis/gopath/src/github.com/weaveworks/mesh/connection.go:420 +0x56
    created by github.com/weaveworks/mesh.(*LocalConnection).run
    	/home/travis/gopath/src/github.com/weaveworks/mesh/connection.go:247 +0x734
    
    goroutine 63 [select]:
    github.com/weaveworks/mesh.(*gossipSender).run(0xc000132870, 0xc000158ae0, 0xc0001590e0, 0xc000159140)
    	/home/travis/gopath/src/github.com/weaveworks/mesh/gossip.go:101 +0xeb
    created by github.com/weaveworks/mesh.newGossipSender
    	/home/travis/gopath/src/github.com/weaveworks/mesh/gossip.go:94 +0x118
    
    goroutine 64 [select]:
    github.com/weaveworks/mesh.(*gossipSender).run(0xc0001328c0, 0xc000158ae0, 0xc0001591a0, 0xc000159200)
    	/home/travis/gopath/src/github.com/weaveworks/mesh/gossip.go:101 +0xeb
    created by github.com/weaveworks/mesh.newGossipSender
    	/home/travis/gopath/src/github.com/weaveworks/mesh/gossip.go:94 +0x118
    
    goroutine 65 [IO wait]:
    internal/poll.runtime_pollWait(0x7f9111d08af0, 0x72, 0xc000237d10)
    	/home/travis/.gimme/versions/go1.11.9.linux.amd64/src/runtime/netpoll.go:173 +0x66
    internal/poll.(*pollDesc).wait(0xc000205a18, 0x72, 0xffffffffffffff00, 0x8e2da0, 0xb9d4f0)
    	/home/travis/.gimme/versions/go1.11.9.linux.amd64/src/internal/poll/fd_poll_runtime.go:85 +0x9a
    internal/poll.(*pollDesc).waitRead(0xc000205a18, 0xc0002c4c00, 0x4, 0x4)
    	/home/travis/.gimme/versions/go1.11.9.linux.amd64/src/internal/poll/fd_poll_runtime.go:90 +0x3d
    internal/poll.(*FD).Read(0xc000205a00, 0xc0002c4c58, 0x4, 0x4, 0x0, 0x0, 0x0)
    	/home/travis/.gimme/versions/go1.11.9.linux.amd64/src/internal/poll/fd_unix.go:169 +0x179
    net.(*netFD).Read(0xc000205a00, 0xc0002c4c58, 0x4, 0x4, 0xc000132200, 0xc000237e10, 0xc000237e50)
    	/home/travis/.gimme/versions/go1.11.9.linux.amd64/src/net/fd_unix.go:202 +0x4f
    net.(*conn).Read(0xc000134e10, 0xc0002c4c58, 0x4, 0x4, 0x0, 0x0, 0x0)
    	/home/travis/.gimme/versions/go1.11.9.linux.amd64/src/net/net.go:177 +0x68
    io.ReadAtLeast(0x8e2220, 0xc000134e10, 0xc0002c4c58, 0x4, 0x4, 0x4, 0x7d73e0, 0x1, 0xc0002c4c58)
    	/home/travis/.gimme/versions/go1.11.9.linux.amd64/src/io/io.go:310 +0x88
    io.ReadFull(0x8e2220, 0xc000134e10, 0xc0002c4c58, 0x4, 0x4, 0x4, 0xc000237f38, 0x3c)
    	/home/travis/.gimme/versions/go1.11.9.linux.amd64/src/io/io.go:329 +0x58
    github.com/weaveworks/mesh.(*lengthPrefixTCPReceiver).Receive(0xc0001fdc10, 0x0, 0x0, 0xfec, 0xfec, 0x0)
    	/home/travis/gopath/src/github.com/weaveworks/mesh/protocol_crypto.go:168 +0x96
    github.com/weaveworks/mesh.(*LocalConnection).receiveTCP(0xc00015e960, 0x8e2060, 0xc0001fdc10)
    	/home/travis/gopath/src/github.com/weaveworks/mesh/connection.go:420 +0x56
    created by github.com/weaveworks/mesh.(*LocalConnection).run
    	/home/travis/gopath/src/github.com/weaveworks/mesh/connection.go:247 +0x734
    exit status 2
    FAIL	github.com/iwanbk/bcache	6.019s
    travis_time:end:00be5070:start=1555427346315028359,finish=1555427358937196900,duration=12622168541
    The command "go test -tags integration -coverprofile=coverage.txt -covermode=atomic" exited with 1.
    
    
    
    Done. Your build exited with 1.
    
    opened by iwanbk 0
  • Scaling limits and full examples?

    Scaling limits and full examples?

    Hello,

    I have been investigating distributed KV libraries for a P2P project that will basically spread out a database across many hundreds of noes.

    I look at Groupcache but then came across your work and am wondering how well it scales?

    Also, are there any full examples that I can compile and run to set up a small cluster to test?

    Thanks

    opened by lonnietc 2
Releases(v0.2)
Owner
Iwan Budi Kusnanto
Iwan Budi Kusnanto
An in-memory key:value store/cache (similar to Memcached) library for Go, suitable for single-machine applications.

go-cache go-cache is an in-memory key:value store/cache similar to memcached that is suitable for applications running on a single machine. Its major

Patrick Mylund Nielsen 6.7k Nov 25, 2022
The most concise and efficient algorithm of consistent hash based on golang

consistent This package of consistent is the most concise and efficient algorithm of consistent hash based on golang. Example Quick start: package mai

null 1 Dec 28, 2021
Distributed cache with gossip peer membership enrollment.

Autocache Groupcache enhanced with memberlist for distributed peer discovery. TL;DR See /_example/ for usage. Run docker-compose -f _example/docker-co

null 99 Sep 23, 2022
MyCache - A distributed cache based on GeeCache

借鉴GeeCache实现了MyCache(https://geektutu.com/post/geecache.html) 主要功能: 1.实现了fifo和lr

null 2 Feb 18, 2022
Distributed reliable key-value store for the most critical data of a distributed system

etcd Note: The master branch may be in an unstable or even broken state during development. Please use releases instead of the master branch in order

etcd-io 41.9k Nov 23, 2022
groupcache is a caching and cache-filling library, intended as a replacement for memcached in many cases.

groupcache Summary groupcache is a distributed caching and cache-filling library, intended as a replacement for a pool of memcached nodes in many case

Go 11.8k Nov 28, 2022
Efficient cache for gigabytes of data written in Go.

BigCache Fast, concurrent, evicting in-memory cache written to keep big number of entries without impact on performance. BigCache keeps entries on hea

Allegro Tech 6.1k Nov 22, 2022
:handbag: Cache arbitrary data with an expiration time.

cache Cache arbitrary data with an expiration time. Features 0 dependencies About 100 lines of code 100% test coverage Usage // New cache c := cache.N

Eduard Urbach 121 Nov 18, 2022
Fast thread-safe inmemory cache for big number of entries in Go. Minimizes GC overhead

fastcache - fast thread-safe inmemory cache for big number of entries in Go Features Fast. Performance scales on multi-core CPUs. See benchmark result

VictoriaMetrics 1.6k Nov 28, 2022
BuntDB is an embeddable, in-memory key/value database for Go with custom indexing and geospatial support

BuntDB is a low-level, in-memory, key/value store in pure Go. It persists to disk, is ACID compliant, and uses locking for multiple readers and a sing

Josh Baker 3.9k Nov 27, 2022
Golang in-memory database built on immutable radix trees

go-memdb Provides the memdb package that implements a simple in-memory database built on immutable radix trees. The database provides Atomicity, Consi

HashiCorp 2.6k Nov 21, 2022
Nipo is a powerful, fast, multi-thread, clustered and in-memory key-value database, with ability to configure token and acl on commands and key-regexes written by GO

Welcome to NIPO Nipo is a powerful, fast, multi-thread, clustered and in-memory key-value database, with ability to configure token and acl on command

Morteza Bashsiz 16 Jun 13, 2022
A tiny date object in Go. Tinydate uses only 4 bytes of memory

go-tinydate A tiny date object in Go. Tinydate uses 4 bytes of memory vs the 24 bytes of a standard time.Time{} A tinydate only has day precision. It

Lane Wagner 34 Mar 17, 2022
A minimalistic in-memory key value store.

A minimalistic in-memory key value store. Overview You can think of Kiwi as thread safe global variables. This kind of library comes in helpful when y

SDSLabs 159 Dec 6, 2021
Membin is an in-memory database that can be stored on disk. Data model smiliar to key-value but values store as JSON byte array.

Membin Docs | Contributing | License What is Membin? The Membin database system is in-memory database smiliar to key-value databases, target to effici

Membin 3 Jun 3, 2021
A simple memory database. It's nothing but a homework to learn primary datastruct of golang.

A simple memory database. It's nothing but a homework to learn primary datastruct of golang.

常乐村喵蕉君 0 Nov 8, 2021
A rest-api that works with golang as an in-memory key value store

Rest API Service in GOLANG A rest-api that works with golang as an in-memory key value store Usage Run command below in terminal in project directory.

sercan aydın 0 Dec 6, 2021
CockroachDB - the open source, cloud-native distributed SQL database.

CockroachDB is a cloud-native SQL database for building global, scalable cloud services that survive disasters. What is CockroachDB? Docs Quickstart C

CockroachDB 26.1k Nov 21, 2022
The lightweight, distributed relational database built on SQLite.

rqlite is a lightweight, distributed relational database, which uses SQLite as its storage engine. Forming a cluster is very straightforward, it grace

rqlite 12.5k Nov 23, 2022