Skip to content

Commit

Permalink
✨ feat: Day3 HTTP 服务端
Browse files Browse the repository at this point in the history
  • Loading branch information
p3ddd committed Mar 30, 2022
1 parent c53c30e commit d5a8815
Show file tree
Hide file tree
Showing 9 changed files with 106 additions and 8 deletions.
File renamed without changes.
2 changes: 1 addition & 1 deletion cache.go → geecache/cache.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package geecache

import (
"geecache/lru"
"gee/geecache/lru"
"sync"
)

Expand Down
File renamed without changes.
12 changes: 6 additions & 6 deletions geecache_test.go → geecache/geecache_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
63 changes: 63 additions & 0 deletions geecache/http.go
Original file line number Diff line number Diff line change
@@ -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)
// /<basepath>/<groupname>/<key> 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())
}
File renamed without changes.
File renamed without changes.
6 changes: 5 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
module geecache
module gee

go 1.18

replace geecache => ./geecache

// require geecache v0.0.0-00010101000000-000000000000 // indirect
31 changes: 31 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
@@ -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))
}

0 comments on commit d5a8815

Please sign in to comment.