add kv-counter example

This commit is contained in:
syumai 2022-07-31 18:36:16 +09:00
parent 2d97bb8234
commit e71f283499
8 changed files with 178 additions and 0 deletions

1
examples/kv-counter/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
dist

View File

@ -0,0 +1,12 @@
.PHONY: dev
dev:
wrangler dev
.PHONY: build
build:
mkdir -p dist
tinygo build -o ./dist/app.wasm -target wasm ./...
.PHONY: publish
publish:
wrangler publish

View File

@ -0,0 +1,32 @@
# kv-counter
* This app counts page view using Cloudflare KV.
## Demo
* https://kv-counter.syumai.workers.dev/
## Development
### Requirements
This project requires these tools to be installed globally.
* wrangler
* tinygo
### Commands
```
make dev # run dev server
make build # build Go Wasm binary
make publish # publish worker
```
## Author
syumai
## License
MIT

View File

@ -0,0 +1,7 @@
module github.com/syumai/workers/examples/kv-counter
go 1.18
require github.com/syumai/workers v0.0.0
replace github.com/syumai/workers => ../../

View File

View File

@ -0,0 +1,92 @@
package main
import (
"fmt"
"log"
"net/http"
"os"
"strconv"
"github.com/syumai/workers"
)
// counterNamespace is a bounded KV namespace for storing counter.
const counterNamespace = "COUNTER"
// countKey is a key to store current count value to the KV namespace.
const countKey = "count"
func handleErr(w http.ResponseWriter, msg string, err error) {
log.Println(err)
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(msg))
}
func main() {
// initialize KV namespace instance
kv, err := workers.NewKVNamespace(counterNamespace)
if err != nil {
fmt.Fprintf(os.Stderr, "failed to init KV: %v", err)
os.Exit(1)
}
http.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
if req.URL.Path != "/" {
w.WriteHeader(http.StatusNotFound)
return
}
countStr, err := kv.GetString(countKey, nil)
if err != nil {
handleErr(w, "failed to get current count\n", err)
return
}
/*
countReader, err := kv.GetReader(countKey, nil)
if err != nil {
handleErr(w, "failed to get current count\n", err)
return
}
b, _ := io.ReadAll(countReader)
countStr := string(b)
*/
// ignore err and treat count value as 0
count, _ := strconv.Atoi(countStr)
nextCountStr := strconv.Itoa(count + 1)
err = kv.PutString(countKey, nextCountStr, nil)
if err != nil {
handleErr(w, "failed to put next count\n", err)
return
}
/*
err = kv.PutReader(countKey, strings.NewReader(nextCountStr), nil)
if err != nil {
handleErr(w, "failed to put next count\n", err)
return
}
*/
w.Header().Set("Content-Type", "text/plain")
/*
// List returns only `count` as the keys in this namespace.
v, err := kv.List(nil)
if err != nil {
handleErr(w, "failed to list\n", err)
return
}
for i, key := range v.Keys {
fmt.Fprintf(w, "%d: %s\n", i, key.Name)
}
*/
w.Write([]byte(nextCountStr))
})
workers.Serve(nil)
}

View File

@ -0,0 +1,20 @@
import "../assets/polyfill_performance.js";
import "../assets/wasm_exec.js";
import mod from "./dist/app.wasm";
const go = new Go();
const load = WebAssembly.instantiate(mod, go.importObject).then((instance) => {
go.run(instance);
return instance;
});
async function processRequest(event) {
const req = event.request;
await load;
return handleRequest(req);
}
addEventListener("fetch", (event) => {
event.respondWith(processRequest(event));
})

View File

@ -0,0 +1,14 @@
name = "kv-counter"
main = "./worker.mjs"
compatibility_date = "2022-05-13"
compatibility_flags = [
"streams_enable_constructors"
]
[[kv_namespaces]]
binding = "COUNTER"
id = "fe0ef36853f04fe986c1ade5271ea6a4"
preview_id = "916f05d37f4741e0a19aa3d0bd4d282e"
[build]
command = "make build"