Skip to content

Commit 83de13d

Browse files
authored
Merge pull request #9 from syumai/add-kv
add KV implementation
2 parents 44df564 + 3ad19ea commit 83de13d

File tree

10 files changed

+420
-2
lines changed

10 files changed

+420
-2
lines changed

README.md

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,22 @@
77
## Features
88

99
* [x] serve http.Handler
10-
* [ ] R2 - Partially supported
10+
* [ ] R2
1111
- [x] Head
1212
- [x] Get
1313
- [x] Put
1414
- [x] Delete
1515
- [x] List
1616
- [ ] Options for R2 methods
17+
* [ ] KV
18+
- [x] Get
19+
- [x] List
20+
- [x] Put
21+
- [x] Delete
22+
- [ ] Options for KV methods
23+
* [ ] Cache API
24+
* [ ] Durable Objects
1725
* [ ] environment variables (WIP)
18-
* [ ] KV (WIP)
1926

2027
## Installation
2128

examples/kv-counter/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
dist

examples/kv-counter/Makefile

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
.PHONY: dev
2+
dev:
3+
wrangler dev
4+
5+
.PHONY: build
6+
build:
7+
mkdir -p dist
8+
tinygo build -o ./dist/app.wasm -target wasm ./...
9+
10+
.PHONY: publish
11+
publish:
12+
wrangler publish

examples/kv-counter/README.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# kv-counter
2+
3+
* This app counts page view using Cloudflare KV.
4+
5+
## Demo
6+
7+
* https://kv-counter.syumai.workers.dev/
8+
9+
## Development
10+
11+
### Requirements
12+
13+
This project requires these tools to be installed globally.
14+
15+
* wrangler
16+
* tinygo
17+
18+
### Commands
19+
20+
```
21+
make dev # run dev server
22+
make build # build Go Wasm binary
23+
make publish # publish worker
24+
```
25+
26+
## Author
27+
28+
syumai
29+
30+
## License
31+
32+
MIT

examples/kv-counter/go.mod

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
module github.com/syumai/workers/examples/kv-counter
2+
3+
go 1.18
4+
5+
require github.com/syumai/workers v0.0.0
6+
7+
replace github.com/syumai/workers => ../../

examples/kv-counter/go.sum

Whitespace-only changes.

examples/kv-counter/main.go

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"log"
6+
"net/http"
7+
"os"
8+
"strconv"
9+
10+
"github.com/syumai/workers"
11+
)
12+
13+
// counterNamespace is a bounded KV namespace for storing counter.
14+
const counterNamespace = "COUNTER"
15+
16+
// countKey is a key to store current count value to the KV namespace.
17+
const countKey = "count"
18+
19+
func handleErr(w http.ResponseWriter, msg string, err error) {
20+
log.Println(err)
21+
w.WriteHeader(http.StatusInternalServerError)
22+
w.Write([]byte(msg))
23+
}
24+
25+
func main() {
26+
// initialize KV namespace instance
27+
kv, err := workers.NewKVNamespace(counterNamespace)
28+
if err != nil {
29+
fmt.Fprintf(os.Stderr, "failed to init KV: %v", err)
30+
os.Exit(1)
31+
}
32+
33+
http.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
34+
if req.URL.Path != "/" {
35+
w.WriteHeader(http.StatusNotFound)
36+
return
37+
}
38+
39+
countStr, err := kv.GetString(countKey, nil)
40+
if err != nil {
41+
handleErr(w, "failed to get current count\n", err)
42+
return
43+
}
44+
45+
/*
46+
countReader, err := kv.GetReader(countKey, nil)
47+
if err != nil {
48+
handleErr(w, "failed to get current count\n", err)
49+
return
50+
}
51+
b, _ := io.ReadAll(countReader)
52+
countStr := string(b)
53+
*/
54+
55+
// ignore err and treat count value as 0
56+
count, _ := strconv.Atoi(countStr)
57+
58+
nextCountStr := strconv.Itoa(count + 1)
59+
60+
err = kv.PutString(countKey, nextCountStr, nil)
61+
if err != nil {
62+
handleErr(w, "failed to put next count\n", err)
63+
return
64+
}
65+
66+
/*
67+
err = kv.PutReader(countKey, strings.NewReader(nextCountStr), nil)
68+
if err != nil {
69+
handleErr(w, "failed to put next count\n", err)
70+
return
71+
}
72+
*/
73+
74+
w.Header().Set("Content-Type", "text/plain")
75+
76+
/*
77+
// List returns only `count` as the keys in this namespace.
78+
v, err := kv.List(nil)
79+
if err != nil {
80+
handleErr(w, "failed to list\n", err)
81+
return
82+
}
83+
for i, key := range v.Keys {
84+
fmt.Fprintf(w, "%d: %s\n", i, key.Name)
85+
}
86+
*/
87+
88+
w.Write([]byte(nextCountStr))
89+
})
90+
91+
workers.Serve(nil)
92+
}

examples/kv-counter/worker.mjs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import "../assets/polyfill_performance.js";
2+
import "../assets/wasm_exec.js";
3+
import mod from "./dist/app.wasm";
4+
5+
const go = new Go();
6+
7+
const load = WebAssembly.instantiate(mod, go.importObject).then((instance) => {
8+
go.run(instance);
9+
return instance;
10+
});
11+
12+
async function processRequest(event) {
13+
const req = event.request;
14+
await load;
15+
return handleRequest(req);
16+
}
17+
18+
addEventListener("fetch", (event) => {
19+
event.respondWith(processRequest(event));
20+
})

examples/kv-counter/wrangler.toml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
name = "kv-counter"
2+
main = "./worker.mjs"
3+
compatibility_date = "2022-05-13"
4+
compatibility_flags = [
5+
"streams_enable_constructors"
6+
]
7+
8+
[[kv_namespaces]]
9+
binding = "COUNTER"
10+
id = "fe0ef36853f04fe986c1ade5271ea6a4"
11+
preview_id = "916f05d37f4741e0a19aa3d0bd4d282e"
12+
13+
[build]
14+
command = "make build"

0 commit comments

Comments
 (0)