Use Golangs contextes

This commit is contained in:
Lou Knauer 2021-09-08 09:08:51 +02:00
parent c50ab30470
commit e4c3bc4db1
4 changed files with 33 additions and 20 deletions

4
api.go
View File

@ -187,7 +187,7 @@ func handleFree(rw http.ResponseWriter, r *http.Request) {
rw.Write([]byte(fmt.Sprintf("buffers freed: %d\n", n))) rw.Write([]byte(fmt.Sprintf("buffers freed: %d\n", n)))
} }
func StartApiServer(address string, done chan bool) error { func StartApiServer(address string, ctx context.Context) error {
r := mux.NewRouter() r := mux.NewRouter()
r.HandleFunc("/api/{from:[0-9]+}/{to:[0-9]+}/timeseries", handleTimeseries) r.HandleFunc("/api/{from:[0-9]+}/{to:[0-9]+}/timeseries", handleTimeseries)
@ -210,7 +210,7 @@ func StartApiServer(address string, done chan bool) error {
}() }()
for { for {
_ = <-done _ = <-ctx.Done()
err := server.Shutdown(context.Background()) err := server.Shutdown(context.Background())
log.Println("API server shut down") log.Println("API server shut down")
return err return err

View File

@ -65,7 +65,7 @@ func (l *level) toArchiveFile(from, to int64) (*ArchiveFile, error) {
} }
for metric, b := range l.metrics { for metric, b := range l.metrics {
data := make([]Float, (to-from)/b.frequency) data := make([]Float, (to-from)/b.frequency+1)
data, start, end, err := b.read(from, to, data) data, start, end, err := b.read(from, to, data)
if err != nil { if err != nil {
return nil, err return nil, err

View File

@ -2,6 +2,7 @@ package main
import ( import (
"bufio" "bufio"
"context"
"errors" "errors"
"io" "io"
"log" "log"
@ -175,7 +176,7 @@ func ReceiveTCP(address string, handleLine func(line *Line), done chan bool) err
// Connect to a nats server and subscribe to "updates". This is a blocking // Connect to a nats server and subscribe to "updates". This is a blocking
// function. handleLine will be called for each line recieved via nats. // function. handleLine will be called for each line recieved via nats.
// Send `true` through the done channel for gracefull termination. // Send `true` through the done channel for gracefull termination.
func ReceiveNats(address string, handleLine func(line *Line), workers int, done chan bool) error { func ReceiveNats(address string, handleLine func(line *Line), workers int, ctx context.Context) error {
nc, err := nats.Connect(nats.DefaultURL) nc, err := nats.Connect(nats.DefaultURL)
if err != nil { if err != nil {
return err return err
@ -194,6 +195,14 @@ func ReceiveNats(address string, handleLine func(line *Line), workers int, done
handleLine(line) handleLine(line)
}) })
if err != nil {
return err
}
log.Printf("NATS subscription to 'updates' on '%s' established\n", address)
_ = <-ctx.Done()
err = sub.Unsubscribe()
} else { } else {
msgs := make(chan *nats.Msg, 16) msgs := make(chan *nats.Msg, 16)
var wg sync.WaitGroup var wg sync.WaitGroup
@ -210,14 +219,22 @@ func ReceiveNats(address string, handleLine func(line *Line), workers int, done
handleLine(line) handleLine(line)
} }
wg.Done()
}() }()
} }
sub, err = nc.Subscribe("updates", func(m *nats.Msg) { sub, err = nc.Subscribe("updates", func(m *nats.Msg) {
msgs <- m msgs <- m
}) })
if err != nil {
return err
}
_ = <-done log.Printf("NATS subscription to 'updates' on '%s' established\n", address)
_ = <-ctx.Done()
err = sub.Unsubscribe()
close(msgs) close(msgs)
wg.Wait() wg.Wait()
} }
@ -226,12 +243,7 @@ func ReceiveNats(address string, handleLine func(line *Line), workers int, done
return err return err
} }
log.Printf("NATS subscription to 'updates' on '%s' established\n", address)
for {
_ = <-done
sub.Unsubscribe()
nc.Close() nc.Close()
log.Println("NATS connection closed") log.Println("NATS connection closed")
return nil return nil
}
} }

View File

@ -1,6 +1,7 @@
package main package main
import ( import (
"context"
"encoding/json" "encoding/json"
"fmt" "fmt"
"log" "log"
@ -62,7 +63,7 @@ func handleLine(line *Line) {
} }
ts := line.Ts.Unix() ts := line.Ts.Unix()
log.Printf("ts=%d, tags=%v\n", ts, selector) // log.Printf("ts=%d, tags=%v\n", ts, selector)
err := memoryStore.Write(selector, ts, line.Fields) err := memoryStore.Write(selector, ts, line.Fields)
if err != nil { if err != nil {
log.Printf("error: %s\n", err.Error()) log.Printf("error: %s\n", err.Error())
@ -87,15 +88,15 @@ func main() {
} }
} }
ctx, shutdown := context.WithCancel(context.Background())
var wg sync.WaitGroup var wg sync.WaitGroup
sigs := make(chan os.Signal, 1) sigs := make(chan os.Signal, 1)
done := make(chan bool, 1)
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM) signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
go func() { go func() {
_ = <-sigs _ = <-sigs
log.Println("Shuting down...") log.Println("Shuting down...")
done <- true shutdown()
close(done)
}() }()
lastCheckpoint = startupTime lastCheckpoint = startupTime
@ -106,7 +107,7 @@ func main() {
ticks := time.Tick(d) ticks := time.Tick(d)
for { for {
select { select {
case <-done: case <-ctx.Done():
wg.Done() wg.Done()
return return
case <-ticks: case <-ticks:
@ -137,7 +138,7 @@ func main() {
} }
go func() { go func() {
err := StartApiServer(":8080", done) err := StartApiServer(":8080", ctx)
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
@ -145,7 +146,7 @@ func main() {
}() }()
go func() { go func() {
err := ReceiveNats(conf.Nats, handleLine, runtime.NumCPU()-1, done) err := ReceiveNats(conf.Nats, handleLine, runtime.NumCPU()-1, ctx)
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }