From d5a881581475d115f18a8e27a214451e9fadb88c Mon Sep 17 00:00:00 2001 From: Petrichor <390983386@qq.com> Date: Wed, 30 Mar 2022 20:40:41 +0800 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20feat:=20Day3=20HTTP=20=E6=9C=8D?= =?UTF-8?q?=E5=8A=A1=E7=AB=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- byteview.go => geecache/byteview.go | 0 cache.go => geecache/cache.go | 2 +- geecache.go => geecache/geecache.go | 0 geecache_test.go => geecache/geecache_test.go | 12 ++-- geecache/http.go | 63 +++++++++++++++++++ {lru => geecache/lru}/lru.go | 0 {lru => geecache/lru}/lru_test.go | 0 go.mod | 6 +- main.go | 31 +++++++++ 9 files changed, 106 insertions(+), 8 deletions(-) rename byteview.go => geecache/byteview.go (100%) rename cache.go => geecache/cache.go (96%) rename geecache.go => geecache/geecache.go (100%) rename geecache_test.go => geecache/geecache_test.go (94%) create mode 100644 geecache/http.go rename {lru => geecache/lru}/lru.go (100%) rename {lru => geecache/lru}/lru_test.go (100%) create mode 100644 main.go diff --git a/byteview.go b/geecache/byteview.go similarity index 100% rename from byteview.go rename to geecache/byteview.go diff --git a/cache.go b/geecache/cache.go similarity index 96% rename from cache.go rename to geecache/cache.go index 5952808..1ac12e7 100644 --- a/cache.go +++ b/geecache/cache.go @@ -1,7 +1,7 @@ package geecache import ( - "geecache/lru" + "gee/geecache/lru" "sync" ) diff --git a/geecache.go b/geecache/geecache.go similarity index 100% rename from geecache.go rename to geecache/geecache.go diff --git a/geecache_test.go b/geecache/geecache_test.go similarity index 94% rename from geecache_test.go rename to geecache/geecache_test.go index b34a840..153b6b9 100644 --- a/geecache_test.go +++ b/geecache/geecache_test.go @@ -18,18 +18,18 @@ func TestGetter(t *testing.T) { } } -var db = map[string]string{ - "Tom": "630", - "Jack": "589", - "Sam": "567", -} - // 1、在缓存为空的情况下,能够通过回调函数获取到源数据。 // 2、在缓存已经存在的情况下,是否直接从缓存中获取, // 为了实现这一点,使用 loadCounts 统计某个键调用回调函数的次数, // 如果次数大于1,则表示调用了多次回调函数,没有缓存。 // go test -run TestGet func TestGet(t *testing.T) { + var db = map[string]string{ + "Tom": "630", + "Jack": "589", + "Sam": "567", + } + loadCounts := make(map[string]int, len(db)) gee := NewGroup("scores", 2<<10, GetterFunc( func(key string) ([]byte, error) { diff --git a/geecache/http.go b/geecache/http.go new file mode 100644 index 0000000..6c9e1fc --- /dev/null +++ b/geecache/http.go @@ -0,0 +1,63 @@ +package geecache + +import ( + "fmt" + "log" + "net/http" + "strings" +) + +const defaultBasePath = "/_geecache/" + +// HTTPPool implements PeerPicker for a pool of HTTP peers. +type HTTPPool struct { + self string // 记录自己的地址,包括主机名/ IP 和端口 + basePath string // 节点间通讯地址的前缀 +} + +// NewHTTPPool initializes an HTTP pool of peers. +func NewHTTPPool(self string) *HTTPPool { + return &HTTPPool{ + self: self, + basePath: defaultBasePath, + } +} + +// Log info with server name +func (p *HTTPPool) Log(format string, v ...interface{}) { + log.Printf("[Server %s] %s", p.self, fmt.Sprintf(format, v...)) +} + +func (p *HTTPPool) ServeHTTP(w http.ResponseWriter, r *http.Request) { + if !strings.HasPrefix(r.URL.Path, p.basePath) { + panic("HTTPPool serving unexpected path: " + r.URL.Path) + } + p.Log("%s %s", r.Method, r.URL.Path) + // /// required + // GET /_geecache/scores/Tom + parts := strings.SplitN(r.URL.Path[len(p.basePath):], "/", 2) + // log.Println(parts) // get [scores Tom] + if len(parts) != 2 { + http.Error(w, "bad request", http.StatusBadRequest) + return + } + + groupName := parts[0] + key := parts[1] + + group := GetGroup(groupName) + if group == nil { + http.Error(w, "no such group: "+groupName, http.StatusNotFound) + return + } + + view, err := group.Get(key) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + + w.Header().Set("Content-Type", "application/octet-stream") + w.Write(view.ByteSlice()) + // log.Println(view.ByteSlice()) +} diff --git a/lru/lru.go b/geecache/lru/lru.go similarity index 100% rename from lru/lru.go rename to geecache/lru/lru.go diff --git a/lru/lru_test.go b/geecache/lru/lru_test.go similarity index 100% rename from lru/lru_test.go rename to geecache/lru/lru_test.go diff --git a/go.mod b/go.mod index 1f7c52b..f471a68 100644 --- a/go.mod +++ b/go.mod @@ -1,3 +1,7 @@ -module geecache +module gee go 1.18 + +replace geecache => ./geecache + +// require geecache v0.0.0-00010101000000-000000000000 // indirect diff --git a/main.go b/main.go new file mode 100644 index 0000000..77f4009 --- /dev/null +++ b/main.go @@ -0,0 +1,31 @@ +package main + +import ( + "fmt" + "gee/geecache" + "log" + "net/http" +) + +var db = map[string]string{ + "Tom": "630", + "Jack": "589", + "Sam": "567", +} + +func main() { + geecache.NewGroup("scores", 2<<10, geecache.GetterFunc( + func(key string) ([]byte, error) { + log.Println("[SlowDB] search key", key) + if v, ok := db[key]; ok { + return []byte(v), nil + } + return nil, fmt.Errorf("%s not exist", key) + }, + )) + + addr := "localhost:9999" + peers := geecache.NewHTTPPool(addr) + log.Println("geecache is running at", addr) + log.Fatal(http.ListenAndServe(addr, peers)) +}