Comments (8)
@jon-whit I know this won't help and I don't have the answer, but I did try your code against the original groupcache
package (https://github.com/golang/groupcache), that this one is based on and am able to reproduce the issue there as well.
from groupcache.
Yeah, it's like the package literally doesn't do what it's meant to do 😂
from groupcache.
@jon-whit your example has a bug because you never expose pool
over http
. pool
itself is an http.Handler
and in this example it is only instantiated and never passed to the server to be used as handler for requests. So the scenario you described worked as expected because there was no connection between peers. Also the interpretation of "reverse" scenario is wrong because you need to restart processes to wipe out data from first scenario. If you do that you will get `error "key not set" for both scenarios.
from groupcache.
@tymeshifter I changed the code as follows:
package main
import (...)
var store = map[string]string{}
var group = groupcache.NewGroup("cache1", 64<<20, groupcache.GetterFunc(
func(ctx context.Context, key string, dest groupcache.Sink) error {
v, ok := store[key]
if !ok {
return fmt.Errorf("key not set")
} else {
if err := dest.SetBytes([]byte(v), time.Now().Add(10*time.Minute)); err != nil {
log.Printf("Failed to set cache value for key '%s' - %v\n", key, err)
return err
}
}
return nil
},
))
func main() {
addr := flag.String("addr", ":8080", "server address")
addr2 := flag.String("api-addr", ":8081", "api server address")
peers := flag.String("pool", "http://localhost:8080", "server pool list")
flag.Parse()
p := strings.Split(*peers, ",")
pool := groupcache.NewHTTPPoolOpts(*addr, &groupcache.HTTPPoolOptions{})
pool.Set(p...)
http.HandleFunc("/set", func(w http.ResponseWriter, r *http.Request) {
key := r.FormValue("key")
value := r.FormValue("value")
store[key] = value
})
http.HandleFunc("/cache", func(w http.ResponseWriter, r *http.Request) {
key := r.FormValue("key")
fmt.Printf("Fetching value for key '%s'\n", key)
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
defer cancel()
var b []byte
err := group.Get(ctx, key, groupcache.AllocatingByteSliceSink(&b))
if err != nil {
http.Error(w, err.Error(), http.StatusNotFound)
return
}
w.Write(b)
w.Write([]byte{'\n'})
})
server := http.Server{
Addr: *addr,
Handler: pool,
}
go func() {
if err := server.ListenAndServe(); err != nil {
log.Fatalf("Failed to start HTTP server - %v", err)
}
}()
go func() {
if err := http.ListenAndServe(*addr2, nil); err != nil {
log.Fatalf("Failed to start API HTTP server - %v", err)
}
}()
termChan := make(chan os.Signal, 1)
signal.Notify(termChan, syscall.SIGINT, syscall.SIGTERM)
<-termChan
}
And I get the same issues I mentioned above. So I'm not so sure that it's an issue of the pool not being exposed over HTTP. In the old example it is exposed over the DefaultServeMux.
Maybe you can provide an example that exhibits the behavior I'm expecting to see? Because I'm not able to get it to work at all like I'd expect.
from groupcache.
I don't follow the issue here, I'm not sure what you are trying to accomplish. The README contains a working example of how the library is to be used. The code you posted doesn't appear to call the pool handler at all, so it's not going to work in the way the library was designed.
from groupcache.
@thrawn01 how do you figure? I passed the pool into the http.Server just like README and implemented some handlers that leverage the group and it doesn't behave as described.
Could you clarify the rationale behind your comment?
from groupcache.
I understand what you are trying todo now! Amazing what a good night sleep will do. 😄
You have a few things wrong, also maybe some miss-understanding of what the library does and how it works.
- the
groupcache.NewHTTPPoolOpts()
call is incorrect, you have to tell groupcache who the current instance is, which is the first arg in that call. So in your code it should bepool := groupcache.NewHTTPPoolOpts(fmt.Sprintf("http://%s", *addr), &groupcache.HTTPPoolOptions{})
such that the instance passed topool.Set()
likehttp://127.0.0.1:8081
will match theself
arg we passed toNewHTTPPoolOpts()
- You need to pass in the full interface address to which you want to bind. Passing in
:8081
will most likely bind to ipv6 although some systems will bind to both ipv6 and ipv4 interfaces when you do this. To be clear, and to allow groupcache to match peers correctly you should call your app like thisgo run main.go -api-addr=127.0.0.1:9081 -addr=127.0.0.1:8081 -pool=http://127.0.0.1:8081,http://127.0.0.1:8082
- Group cache doesn't distribute the value to all peers in the cluster, if a peer doesn't have the value it will figure out which peer has the value and ask that peer for the value. So in your example, asking one peer for a value you set on an arbitrary peer might not work, it will only work if you set the value on the peer that the consistent hash algorithm has determined "owns" the value.
I hope this makes more sense.
I'll add an additional comment in the example to explicitly call out that you MUST identify the current instance by passing the argument self
such that the pool can find self
in the list passed to pool.Set()
. Any other thoughts on making the documentation clear would be appreciated.
from groupcache.
See ece2929
from groupcache.
Related Issues (20)
- Question(s) HOT 4
- Support to Attach to Already Running Server HOT 1
- Deadlock in groupcache lookup HOT 3
- What should we do when membership changes ? HOT 2
- context deadline on specific keys HOT 5
- Add the ability to warm the cache HOT 1
- [feature-request] Provide an option to set http client options, like headers or maybe update the http req. HOT 2
- Deadlocks after panic inside Getter
- Peer pods autodiscovery within kubernetes cluster HOT 1
- Can you update key? HOT 1
- getgroup from different main instances will it work ?
- HTTP Error Handling Problem
- Upgrade the Protobuf API version
- [Feature Request]: Redis SetNX() equivalent
- Move global state to explicit var to allow deallocation?
- Prometheus metrics
- Authorization to refactor this library HOT 10
- how to use group cache with k8s container deployment HOT 1
- Example from cmd/server does not work as expected HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from groupcache.