Skip to content

Instantly share code, notes, and snippets.

View wjkoh's full-sized avatar
🎯
Focusing

Woojong Koh wjkoh

🎯
Focusing
View GitHub Profile
@wjkoh
wjkoh / http_server.go
Last active May 5, 2025 05:40
Go: How to Run an HTTP Server Correctly
package main
import (
"context"
"embed"
"html/template"
"log"
"log/slog"
"net"
"net/http"
@wjkoh
wjkoh / line_reader_iterator.go
Created April 5, 2025 05:31
Go: Line reader iterator (JSONL, NDJSON)
func Lines(f io.Reader) iter.Seq2[[]byte, error] {
r := bufio.NewReader(f)
return func(yield func([]byte, error) bool) {
for {
data, err := r.ReadBytes('\n')
if errors.Is(err, io.EOF) {
return
}
if !yield(data, err) {
return
@wjkoh
wjkoh / double_channeling.md
Created March 26, 2025 17:49
Go: Double Channeling

Core Idea:

The primary goal of this pattern is to allow the http.HandlerFunc to always have access to the latest available set of []Company data without blocking, even while a potentially long-running crawlCompanies function is fetching new data in the background. It provides a form of non-blocking data exchange between a background worker and a request handler.

How it Works:

  1. Two Buffered Channels (ch1, ch2):
    • Two channels (ch1, ch2) are created, each capable of holding exactly one []Company slice (make(chan []Company, 1)). The buffer size of 1 is key.
    • They are initialized by sending nil into each (ch1 <- nil, ch2 <- nil). This means both channels start "full" with a placeholder value.
@wjkoh
wjkoh / sqlite_bug.go
Created March 24, 2025 06:45
Go + SQLite3: Temporary Table Not Removed
package main
import (
"context"
"database/sql"
"log"
"os"
_ "github.com/mattn/go-sqlite3"
)
@wjkoh
wjkoh / limit_or_take.go
Created March 20, 2025 03:18
Go: Limit the size of an iterator; Limit(n) or Take(n)
func Limit[E any](seq iter.Seq[E], limit int) iter.Seq[E] {
return func(yield func(E) bool) {
var count int
for e := range seq {
if count >= limit {
return
}
if !yield(e) {
return
}
@wjkoh
wjkoh / inverse_has.go
Created March 19, 2025 13:34
Go: The Correct Way of Relationships
type Person struct {
Email string
Name string
}
type Resume struct {
Author *Person
Content string
}
@wjkoh
wjkoh / data_race_quiz.go
Last active March 18, 2025 06:55
Go: Data Race Quiz! Shadowing or Stomping?
package main
import (
"context"
"io"
"time"
)
type uploader struct{}
@wjkoh
wjkoh / multivalue.go
Last active March 13, 2025 06:02
Go: Using a multi-value function return as arguments
package main
import "fmt"
func main() {
fmt.Println(max(threeInts()))
}
func threeInts() (int, int, int) {
return 32, 8, 64
@wjkoh
wjkoh / double_quotes.md
Last active March 11, 2025 11:41
html/template: Implicit Double Quotes

In Go's html/template, you don't have to enclose a template action within double quotes. The html/template package automatically adds double quotes to your string.

<span title="{{.Title}}">Hello World</span>
<span title={{.Title}}>Hello World</span>

Both examples produce the same HTML:

<span title="This is title">Hello World</span>
@wjkoh
wjkoh / cache_ttl.go
Last active February 12, 2025 15:18
Go: A Simple TTL Cache Using time.AfterFunc()
package cache
import (
"sync"
"time"
)
type Cache[K comparable, V any] interface {
Set(K, V)
Get(K) (V, bool)