auto-reconnecting jetstream proxy

initial commit

l4.pm 20de4af8

+106
+13
README.md
··· 1 + # jetstream-proxy 2 + 3 + # WIP LOL 4 + 5 + auto-reconnecting jetstream proxy with a default pool that should work 6 + 7 + NOTES: 8 + - this should run as close to your infrastructure as possible. you then 9 + would connect to `ws://localhost:6969/subscribe` 10 + 11 + ``` 12 + go build 13 + ```
+5
go.mod
··· 1 + module l4.pm/jetstream-proxy 2 + 3 + go 1.25.1 4 + 5 + require github.com/bluesky-social/jetstream v0.0.0-20251009222037-7d7efa58d7f1 // indirect
+2
go.sum
··· 1 + github.com/bluesky-social/jetstream v0.0.0-20251009222037-7d7efa58d7f1 h1:ovcRKN1iXZnY5WApVg+0Hw2RkwMH0ziA7lSAA8vellU= 2 + github.com/bluesky-social/jetstream v0.0.0-20251009222037-7d7efa58d7f1/go.mod h1:5PtGi4r/PjEVBBl+0xWuQn4mBEjr9h6xsfDBADS6cHs=
+86
main.go
··· 1 + package main 2 + 3 + import ( 4 + "fmt" 5 + "net/http" 6 + "os" 7 + "strings" 8 + "sync" 9 + "time" 10 + ) 11 + 12 + var DEFAULT_POOL = []string{ 13 + "wss://jetstream1.us-east.bsky.network", 14 + "wss://jetstream2.us-east.bsky.network", 15 + "wss://jetstream1.us-west.bsky.network", 16 + "wss://jetstream2.us-west.bsky.network", 17 + "wss://jetstream.fire.hose.cam", 18 + "wss://jetstream2.fr.hose.cam", 19 + // want yours here? contact me 20 + } 21 + 22 + type latencyResult struct { 23 + url string 24 + latency time.Duration 25 + err error 26 + } 27 + 28 + func measureLatency(url string) (time.Duration, error) { 29 + httpsURL := strings.Replace(url, "wss://", "https://", 1) 30 + 31 + start := time.Now() 32 + resp, err := http.Get(httpsURL) 33 + if err != nil { 34 + return 0, err 35 + } 36 + defer resp.Body.Close() 37 + 38 + return time.Since(start), nil 39 + } 40 + 41 + func main() { 42 + maybePool := os.Getenv("POOL") 43 + pool := DEFAULT_POOL 44 + if maybePool != "" { 45 + pool = strings.Split(maybePool, ",") 46 + } 47 + 48 + // Measure latency concurrently 49 + results := make(chan latencyResult, len(pool)) 50 + var wg sync.WaitGroup 51 + 52 + for _, url := range pool { 53 + wg.Add(1) 54 + go func(u string) { 55 + defer wg.Done() 56 + latency, err := measureLatency(u) 57 + results <- latencyResult{url: u, latency: latency, err: err} 58 + }(url) 59 + } 60 + 61 + wg.Wait() 62 + close(results) 63 + 64 + // Find the best connection 65 + var best latencyResult 66 + best.latency = time.Hour // Start with a very high latency 67 + 68 + fmt.Println("Latency results:") 69 + for result := range results { 70 + if result.err != nil { 71 + fmt.Printf(" %s: ERROR - %v\n", result.url, result.err) 72 + continue 73 + } 74 + fmt.Printf(" %s: %v\n", result.url, result.latency) 75 + 76 + if result.latency < best.latency { 77 + best = result 78 + } 79 + } 80 + 81 + if best.err == nil && best.latency < time.Hour { 82 + fmt.Printf("\nBest connection: %s (latency: %v)\n", best.url, best.latency) 83 + } else { 84 + fmt.Println("\nNo valid connections found") 85 + } 86 + }