blog

Categories     Timeline     RSS

Betriebsamkeit

Ganz schön was los

Minimal three tier Golang app v2

Building on Minimal three tier Golang app, I made a three tier app with a Go frontend (as Web Assembly), a Go backend and a .txt as exemplary “data store”. Still no external dependencies, all compiling to a single binary. You need Go, Make and a browser. Compile and start with make, then open http://localhost:8000 and hit the button.

$ cat Makefile
all: hellofront hello

hellofront: hellofront.go
        GOOS=js GOARCH=wasm go build hellofront.go structures.go

hello:
        go run hello.go structures.go


$ cat structures.go
package main

type Answer struct {
        Current int
}


$ cat hellofront.go
package main

import (
        "encoding/json"
        "fmt"
        "net/http"
        "syscall/js"
)

var current js.Value

func main() {
        done := make(chan struct{}, 0)
        current = js.Global().Get("document").Call("getElementById", "current")
        js.Global().Set("GetCurrent", js.FuncOf(func(this js.Value, args []js.Value) interface{} {
                go GetCurrent()
                return nil
        }))
        <-done
}

func GetCurrent() {
        resp, err := http.Get("/current")
        if err != nil {
                fmt.Println(err)
        }
        var res Answer
        err = json.NewDecoder(resp.Body).Decode(&res)
        if err != nil {
                fmt.Println(err)
        }
        current.Set("innerText", res.Current)
}


$ cat hello.go
package main

import (
	_ "embed"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
)

//go:embed hellofront
var wasm []byte

// copied from $(go env GOROOT)/misc/wasm/wasm_exec.js
//go:embed wasm_exec.js
var wasm_exec string

var html = `<html>
<head>
<script>` + wasm_exec + `</script>
<script>
const go = new Go();
var module = WebAssembly.instantiateStreaming(fetch("hellofront"), go.importObject).then((result) => {
	go.run(result.instance);
});
</script>
</head>
<body>
<h1 id="current"></h1>
<button onclick="GetCurrent()">Load Current</button>
</body>
</html>
`

const storefile = "myfancydatastore.txt"

func readFromStore() Answer {
	b, err := ioutil.ReadFile(storefile)
	if err != nil {
		// do something
	}
	var a Answer
	err = json.Unmarshal(b, &a)
	if err != nil {
		// do something
	}
	return a
}

func writeToStore(a Answer) {
	b, err := json.Marshal(a)
	if err != nil {
		// do something
	}
	ioutil.WriteFile(storefile, b, 0644)
}

func serveIndex(w http.ResponseWriter, r *http.Request) {
	if r.Method == http.MethodGet {
		w.Header().Set("content-type", "text/html; charset=utf-8")
		w.Write([]byte(html))
	}
}

func handler(w http.ResponseWriter, r *http.Request) {
	if r.Method == http.MethodGet {
		w.Header().Set("content-type", "application/json")
		a := readFromStore()
		b, err := json.Marshal(a)
		if err != nil {
			// do something
		}
		w.Write(b)
		a.Current = a.Current + 1
		writeToStore(a)
	}
}

func loadWASM(w http.ResponseWriter, r *http.Request) {
	if r.Method == http.MethodGet {
		w.Write(wasm)
	}
}

func main() {
	writeToStore(Answer{Current: 0})
	mux := http.NewServeMux()
	mux.HandleFunc("/", serveIndex)
	mux.HandleFunc("/current", handler)
	mux.HandleFunc("/hellofront", loadWASM)
	fmt.Println("Starting server on localhost:8000")
	http.ListenAndServe("localhost:8000", mux)
}

Receiver-side Cutoff the third

I guess what I was thinking of in Receiver-side Cutoff is just IRC without bouncers. People can’t continue sending when you’re not connected. Seems like a good idea. Also no GDPR/DSGVO problems, because messages aren’t saved.

AI is not the problem

… Peter Welch wrote

After six or seven years in this professional clink, what people pay software engineers for is their knowledge of what not to do. If my friends and family ask me to build them a website I send them to Squarespace, since it will be much cheaper and probably better than anything I could do for them. We get paid to grasp the ecosystem at large, stay vaguely up to date, and divert ruinous architectural traps before they show up on a quarterly report. Anyone can google the solutions to most of the particular problems we deal with; we get paid to know what to google and how to read the answer.

[…]

The fact that grammatically or syntactically correct semi-nonsense collected from shallow knowledge can displace real world tests of comprehension means we’re not holding ourselves to a particularly high standard. Actual use of ChatGPT for articles or essays or code will produce more of the content that made its output subpar, and achieve little besides accelerating the homogenization of mediocrity.

Accidental art

Ouch!

< Older

Newer >