Add concurrency

This commit is contained in:
dwrz
2026-10-27 12:41:06 +00:00
commit 2334f4eaf0
31 changed files with 43061 additions and 0 deletions
+41
View File
@@ -0,0 +1,41 @@
package main
import (
"encoding/csv"
"io"
"os"
"sync"
"time"
)
// The free tier of the OpenWeatherMap API allows for 60 requests per minute.
// ∴ we limit our requests to 1 per second.
var interval = 1 * time.Second
func processCSV(
file *os.File, ztchan chan *ZipTemp,
) {
var (
limiter = time.Tick(interval)
wg sync.WaitGroup
)
reader := csv.NewReader(file)
for {
record, err := reader.Read()
if err == io.EOF {
break
}
if err != nil {
panic(err)
}
<-limiter
wg.Add(1)
go getZipTemp(&wg, record, ztchan)
}
wg.Wait()
close(ztchan)
}
+47
View File
@@ -0,0 +1,47 @@
package main
import (
"fmt"
"time"
)
const (
title = "TOP TEN ZIP CODES BY HIGHEST CURRENT TEMPERATURE"
)
func display(ztchan chan []*ZipTemp, done chan struct{}) {
for {
locations, more := <-ztchan
if !more {
done <- struct{}{}
return
}
// Clear the screen.
print("\033[H\033[2J")
// Print the title and top ten.
fmt.Println(title)
fmt.Printf(
"Last update: %s.\n\n",
time.Now().Format(time.RFC1123),
)
for i, zt := range locations {
if zt == nil {
fmt.Printf("%d. No data\n", i+1)
continue
}
fmt.Printf(
"%d. %.02f°F %s (%s, %s)\n",
i+1,
zt.Temperature,
zt.ZipCode,
zt.City,
zt.State,
)
}
}
}
+42
View File
@@ -0,0 +1,42 @@
package main
import (
"log"
"os"
"time"
)
type ZipTemp struct {
City string
Latitude string
Longitude string
State string
Temperature float64
Time time.Time
ZipCode string
}
func main() {
file, err := os.Open("./zipcodes-50.csv")
if err != nil {
log.Fatal(err)
}
defer file.Close()
// Set up channels.
var (
done = make(chan struct{})
ztchan = make(chan *ZipTemp)
ttchan = make(chan []*ZipTemp)
)
// Start the rank and display goroutines.
go rank(ztchan, ttchan)
go display(ttchan, done)
// Process the CSV.
processCSV(file, ztchan)
// Wait for the last display output.
<-done
}
+50
View File
@@ -0,0 +1,50 @@
package main
func rank(ztchan chan *ZipTemp, ttchan chan []*ZipTemp) {
var topTen = make([]*ZipTemp, 10)
for {
zt, more := <-ztchan
if !more {
close(ttchan)
return
}
var newItem bool
for i, tt := range topTen {
if tt != nil && tt.Temperature > zt.Temperature {
continue
}
// We've found a zip code with a higher temperature.
// Insert it into the top ten.
topTen = append(topTen, nil)
copy(topTen[i+1:], topTen[i:])
topTen[i] = zt
// Drop the last value.
topTen = topTen[:10]
newItem = true
break
}
// If the top ten hasn't changed, process the next zip code.
if !newItem {
continue
}
// If the top ten has changed, message the display goroutine.
// Send a copy, to prevent race conditions.
var newTopTen = make([]*ZipTemp, 10)
for i, tt := range topTen {
if tt == nil {
continue
}
newTopTen[i] = tt
}
ttchan <- newTopTen
}
}
+5
View File
@@ -0,0 +1,5 @@
#!/bin/bash
export OPEN_WEATHER_MAP_API_KEY="$(pass open-weather-map/api-key)"
go run ./*.go
+38
View File
@@ -0,0 +1,38 @@
package main
import (
"sync"
"time"
"github.com/dwrz/talks/concurrency/pkg/weather"
)
func getZipTemp(
wg *sync.WaitGroup, record []string, ztchan chan *ZipTemp,
) {
defer wg.Done()
// Ignore malformed records.
if len(record) < 5 {
return
}
var zt = &ZipTemp{
City: record[3],
Latitude: record[1],
Longitude: record[2],
State: record[4],
ZipCode: record[0],
}
// Ignore zip codes we were not able to get the weather for.
weather, err := weather.GetGeo(zt.Latitude, zt.Longitude)
if err != nil {
return
}
zt.Temperature = weather.Temp
zt.Time = time.Now()
ztchan <- zt
}
+50
View File
@@ -0,0 +1,50 @@
15336,40.260141,-79.992678,Gastonville,PA,Washington
64475,40.439298,-94.62247,Parnell,MO,Nodaway
62864,38.293269,-88.892273,Mount Vernon,IL,Jefferson
36049,31.754655,-86.291595,Luverne,AL,Crenshaw
30549,34.10601,-83.589021,Jefferson,GA,Jackson
49235,41.930577,-84.156209,Clayton,MI,Lenawee
21561,39.538568,-79.190791,Swanton,MD,Garrett
13165,42.892556,-76.882263,Waterloo,NY,Seneca
36473,31.466945,-87.044687,Range,AL,Conecuh
98181,47.432251,-121.803388,Seattle,WA,King
54874,46.568809,-91.935156,South Range,WI,Douglas
45840,41.015219,-83.664786,Findlay,OH,Hancock
97303,44.992731,-123.01672,Salem,OR,Marion
91709,34.839964,-115.967051,Chino Hills,CA,San Bernardino
68048,40.971961,-96.001244,Plattsmouth,NE,Cass
15327,39.764089,-79.937419,Dilliner,PA,Greene
38954,33.445684,-89.910076,Sidon,MS,Carroll
29581,34.000746,-79.102314,Nichols,SC,Horry
81504,39.123554,-108.589414,Grand Junction,CO,Mesa
39161,32.498294,-89.868563,Sandhill,MS,Rankin
85737,32.435158,-110.984499,Tucson,AZ,Pima
55365,45.200875,-93.888099,Monticello,MN,Wright
99176,47.12196,-117.433708,Thornton,WA,Whitman
72532,36.061757,-91.607603,Evening Shade,AR,Sharp
72145,35.277393,-91.732556,Searcy,AR,White
75662,32.410306,-94.793392,Kilgore,TX,Gregg
23272,37.524246,-77.493157,Richmond,VA,Richmond City
99023,47.557733,-117.183637,Mica,WA,Spokane
77802,30.620983,-96.319377,Bryan,TX,Brazos
05463,44.878094,-73.338597,Isle La Motte,VT,Grand Isle
27110,36.027482,-80.20728,Winston Salem,NC,Forsyth
33404,26.645895,-80.430269,West Palm Beach,FL,Palm Beach
84141,40.668068,-111.908297,Salt Lake City,UT,Salt Lake
32867,28.566338,-81.260818,Orlando,FL,Orange
78461,27.777,-97.463213,Corpus Christi,TX,Nueces
84123,40.65963,-111.919269,Salt Lake City,UT,Salt Lake
76299,33.20743,-97.116282,Roanoke,TX,Denton
24830,37.375246,-81.653889,Elbert,WV,Mcdowell
61914,39.638,-88.75367,Bethany,IL,Moultrie
13089,43.02143,-76.197701,Liverpool,NY,Onondaga
03774,44.077803,-72.014608,North Haverhill,NH,Grafton
01098,42.40494,-72.896133,Worthington,MA,Hampshire
14517,42.591883,-77.894474,Nunda,NY,Livingston
16743,41.881851,-78.457878,Port Allegany,PA,Mckean
10048,40.71254,-74.013289,New York,NY,New York
19375,39.901177,-75.750203,Unionville,PA,Chester
44608,40.665824,-81.592696,Beach City,OH,Stark
14883,42.203102,-76.471165,Spencer,NY,Tioga
34218,27.499515,-82.709871,Holmes Beach,FL,Manatee
75037,32.767268,-96.777626,Irving,TX,Dallas
1 15336 40.260141 -79.992678 Gastonville PA Washington
2 64475 40.439298 -94.62247 Parnell MO Nodaway
3 62864 38.293269 -88.892273 Mount Vernon IL Jefferson
4 36049 31.754655 -86.291595 Luverne AL Crenshaw
5 30549 34.10601 -83.589021 Jefferson GA Jackson
6 49235 41.930577 -84.156209 Clayton MI Lenawee
7 21561 39.538568 -79.190791 Swanton MD Garrett
8 13165 42.892556 -76.882263 Waterloo NY Seneca
9 36473 31.466945 -87.044687 Range AL Conecuh
10 98181 47.432251 -121.803388 Seattle WA King
11 54874 46.568809 -91.935156 South Range WI Douglas
12 45840 41.015219 -83.664786 Findlay OH Hancock
13 97303 44.992731 -123.01672 Salem OR Marion
14 91709 34.839964 -115.967051 Chino Hills CA San Bernardino
15 68048 40.971961 -96.001244 Plattsmouth NE Cass
16 15327 39.764089 -79.937419 Dilliner PA Greene
17 38954 33.445684 -89.910076 Sidon MS Carroll
18 29581 34.000746 -79.102314 Nichols SC Horry
19 81504 39.123554 -108.589414 Grand Junction CO Mesa
20 39161 32.498294 -89.868563 Sandhill MS Rankin
21 85737 32.435158 -110.984499 Tucson AZ Pima
22 55365 45.200875 -93.888099 Monticello MN Wright
23 99176 47.12196 -117.433708 Thornton WA Whitman
24 72532 36.061757 -91.607603 Evening Shade AR Sharp
25 72145 35.277393 -91.732556 Searcy AR White
26 75662 32.410306 -94.793392 Kilgore TX Gregg
27 23272 37.524246 -77.493157 Richmond VA Richmond City
28 99023 47.557733 -117.183637 Mica WA Spokane
29 77802 30.620983 -96.319377 Bryan TX Brazos
30 05463 44.878094 -73.338597 Isle La Motte VT Grand Isle
31 27110 36.027482 -80.20728 Winston Salem NC Forsyth
32 33404 26.645895 -80.430269 West Palm Beach FL Palm Beach
33 84141 40.668068 -111.908297 Salt Lake City UT Salt Lake
34 32867 28.566338 -81.260818 Orlando FL Orange
35 78461 27.777 -97.463213 Corpus Christi TX Nueces
36 84123 40.65963 -111.919269 Salt Lake City UT Salt Lake
37 76299 33.20743 -97.116282 Roanoke TX Denton
38 24830 37.375246 -81.653889 Elbert WV Mcdowell
39 61914 39.638 -88.75367 Bethany IL Moultrie
40 13089 43.02143 -76.197701 Liverpool NY Onondaga
41 03774 44.077803 -72.014608 North Haverhill NH Grafton
42 01098 42.40494 -72.896133 Worthington MA Hampshire
43 14517 42.591883 -77.894474 Nunda NY Livingston
44 16743 41.881851 -78.457878 Port Allegany PA Mckean
45 10048 40.71254 -74.013289 New York NY New York
46 19375 39.901177 -75.750203 Unionville PA Chester
47 44608 40.665824 -81.592696 Beach City OH Stark
48 14883 42.203102 -76.471165 Spencer NY Tioga
49 34218 27.499515 -82.709871 Holmes Beach FL Manatee
50 75037 32.767268 -96.777626 Irving TX Dallas
File diff suppressed because it is too large Load Diff