Skip to content

Commit b3126ae

Browse files
committed
log package prototype
0 parents  commit b3126ae

File tree

9 files changed

+238
-0
lines changed

9 files changed

+238
-0
lines changed

.idea/LetsGo.iml

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/misc.xml

Lines changed: 14 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/modules.xml

Lines changed: 16 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/workspace.xml

Lines changed: 49 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cmd/server/main.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package main
2+
3+
import (
4+
"log"
5+
6+
"github.com/jibbscript/dlog/internal/server"
7+
)
8+
9+
func main() {
10+
srv := server.NewHTTPServer(":8080")
11+
log.Fatal(srv.ListenAndServe())
12+
}

go.mod

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
module github.com/jibbscript/dlog
2+
3+
go 1.19
4+
5+
require github.com/gorilla/mux v1.8.0

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
2+
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=

internal/server/http.go

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
package server
2+
3+
import (
4+
"encoding/json"
5+
"net/http"
6+
7+
"github.com/gorilla/mux"
8+
)
9+
10+
func NewHTTPServer(addr string) *http.Server {
11+
httpsrv := newHTTPServer()
12+
r := mux.NewRouter()
13+
r.HandleFunc("/", httpsrv.handleProduce).Methods("POST")
14+
r.HandleFunc("/", httpsrv.handleConsume).Methods("GET")
15+
return &http.Server{
16+
Addr: addr,
17+
Handler: r,
18+
}
19+
}
20+
21+
22+
type httpServer struct {
23+
Log *Log
24+
}
25+
26+
func newHTTPServer() *httpServer {
27+
return &httpServer{
28+
Log: NewLog(),
29+
}
30+
}
31+
32+
type ProduceRequest struct {
33+
Record Record `json:"record"`
34+
}
35+
36+
type ProduceResponse struct {
37+
Offset uint64 `json:"offset"`
38+
}
39+
40+
type ConsumeRequest struct {
41+
Offset uint64 `json:"offset"`
42+
}
43+
44+
type ConsumeResponse struct {
45+
Record Record `json:"record"`
46+
}
47+
48+
49+
func (s *httpServer) handleProduce(w http.ResponseWriter, r *http.Request) {
50+
var req ProduceRequest
51+
err := json.NewDecoder(r.Body).Decode(&req)
52+
if err != nil {
53+
http.Error(w, err.Error(), http.StatusBadRequest)
54+
return
55+
}
56+
off, err := s.Log.Append(req.Record)
57+
if err != nil {
58+
http.Error(w, err.Error(), http.StatusInternalServerError)
59+
return
60+
}
61+
res := ProduceResponse{Offset: off}
62+
err = json.NewEncoder(w).Encode(res)
63+
if err != nil {
64+
http.Error(w, err.Error(), http.StatusInternalServerError)
65+
return
66+
}
67+
}
68+
69+
70+
func (s *httpServer) handleConsume(w http.ResponseWriter, r *http.Request) {
71+
var req ConsumeRequest
72+
err := json.NewDecoder(r.Body).Decode(&req)
73+
if err != nil {
74+
http.Error(w, err.Error(), http.StatusBadRequest)
75+
return
76+
}
77+
record, err := s.Log.Read(req.Offset)
78+
if err == ErrOffsetNotFound {
79+
http.Error(w, err.Error(), http.StatusNotFound)
80+
return
81+
}
82+
if err != nil {
83+
http.Error(w, err.Error(), http.StatusInternalServerError)
84+
return
85+
}
86+
res := ConsumeResponse{Record: record}
87+
err = json.NewEncoder(w).Encode(res)
88+
if err != nil {
89+
http.Error(w, err.Error(), http.StatusInternalServerError)
90+
return
91+
}
92+
}
93+

internal/server/log.go

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package server
2+
3+
import (
4+
"fmt"
5+
"sync"
6+
)
7+
8+
type Log struct {
9+
mu sync.Mutex
10+
records []Record
11+
}
12+
13+
func NewLog() *Log {
14+
return &Log{}
15+
}
16+
17+
func (c *Log) Append(record Record) (uint64, error) {
18+
c.mu.Lock()
19+
defer c.mu.Unlock()
20+
record.Offset = uint64(len(c.records))
21+
c.records = append(c.records, record)
22+
return record.Offset, nil
23+
}
24+
25+
func (c *Log) Read(offset uint64) (Record, error) {
26+
c.mu.Lock()
27+
defer c.mu.Unlock()
28+
if offset >= uint64(len(c.records)) {
29+
return Record{}, ErrOffsetNotFound
30+
}
31+
return c.records[offset], nil
32+
}
33+
34+
type Record struct {
35+
Value []byte `json:"value"`
36+
Offset uint64 `json:"offset"`
37+
}
38+
39+
var ErrOffsetNotFound = fmt.Errorf("offset not found")

0 commit comments

Comments
 (0)