chore: many fixes to code
This commit is contained in:
195
app.go
Normal file
195
app.go
Normal file
@@ -0,0 +1,195 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"iter"
|
||||
"os"
|
||||
"runtime/debug"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
_ "embed"
|
||||
|
||||
_ "github.com/mattn/go-sqlite3"
|
||||
"github.com/uptrace/opentelemetry-go-extra/otelsql"
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
semconv "go.opentelemetry.io/otel/semconv/v1.4.0"
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
"go.sour.is/xt/internal/otel"
|
||||
"go.yarn.social/lextwt"
|
||||
"go.yarn.social/types"
|
||||
"golang.org/x/sync/errgroup"
|
||||
)
|
||||
|
||||
func run(c *console) error {
|
||||
ctx, span := otel.Span(c.Context)
|
||||
defer span.End()
|
||||
|
||||
bi, _ := debug.ReadBuildInfo()
|
||||
span.AddEvent(name, trace.WithAttributes(attribute.String("version", bi.Main.Version)))
|
||||
|
||||
a := c.Args()
|
||||
app := &appState{
|
||||
args: a,
|
||||
feeds: sync.Map{},
|
||||
queue: FibHeap(func(a, b *Feed) bool {
|
||||
return a.NextScanOn.Time.Before(b.NextScanOn.Time)
|
||||
}),
|
||||
}
|
||||
|
||||
// Setup DB
|
||||
err := func(ctx context.Context) error {
|
||||
ctx, span := otel.Span(ctx)
|
||||
defer span.End()
|
||||
|
||||
db, err := app.DB(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer db.Close()
|
||||
|
||||
for _, stmt := range strings.Split(initSQL, ";") {
|
||||
_, err = db.ExecContext(ctx, stmt)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Seed File
|
||||
err = func(ctx context.Context) error {
|
||||
ctx, span := otel.Span(ctx)
|
||||
defer span.End()
|
||||
|
||||
f, err := os.Open(a.baseFeed)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
twtfile, err := lextwt.ParseFile(f, &types.Twter{
|
||||
Nick: a.Nick,
|
||||
URI: a.URI,
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("%w: %w", ErrParseFailed, err)
|
||||
}
|
||||
|
||||
db, err := app.DB(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer db.Close()
|
||||
|
||||
return storeFeed(ctx, db, twtfile)
|
||||
}(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
wg, ctx := errgroup.WithContext(ctx)
|
||||
c.Context = ctx
|
||||
|
||||
wg.Go(func() error {
|
||||
return refreshLoop(c, app)
|
||||
})
|
||||
go httpServer(c, app)
|
||||
|
||||
err = wg.Wait()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return c.Context.Err()
|
||||
}
|
||||
|
||||
type appState struct {
|
||||
args args
|
||||
feeds sync.Map
|
||||
queue *fibHeap[Feed]
|
||||
}
|
||||
|
||||
type db struct {
|
||||
*sql.DB
|
||||
Version string
|
||||
Params map[string]string
|
||||
MaxLength int
|
||||
MaxVariableNumber int
|
||||
}
|
||||
|
||||
func (app *appState) DB(ctx context.Context) (db, error) {
|
||||
// return sql.Open(app.args.dbtype, app.args.dbfile)
|
||||
|
||||
var err error
|
||||
db := db{Params: make(map[string]string)}
|
||||
db.DB, err = otelsql.Open(app.args.dbtype, app.args.dbfile,
|
||||
otelsql.WithAttributes(semconv.DBSystemSqlite),
|
||||
otelsql.WithDBName("mydb"))
|
||||
if err != nil {
|
||||
return db, err
|
||||
}
|
||||
|
||||
rows, err := db.DB.QueryContext(ctx, `select sqlite_version()`)
|
||||
if err != nil {
|
||||
return db, err
|
||||
}
|
||||
|
||||
if rows.Next() {
|
||||
rows.Scan(&db.Version)
|
||||
}
|
||||
if err = rows.Err(); err != nil {
|
||||
return db, err
|
||||
}
|
||||
|
||||
rows, err = db.DB.QueryContext(ctx, `pragma compile_options`)
|
||||
if err != nil {
|
||||
return db, err
|
||||
}
|
||||
|
||||
for rows.Next() {
|
||||
var key, value string
|
||||
rows.Scan(&key)
|
||||
key, value, _ = strings.Cut(key, "=")
|
||||
db.Params[key] = value
|
||||
}
|
||||
if err = rows.Err(); err != nil {
|
||||
return db, err
|
||||
}
|
||||
|
||||
if m, ok := db.Params["MAX_VARIABLE_NUMBER"]; ok {
|
||||
db.MaxVariableNumber, _ = strconv.Atoi(m)
|
||||
}
|
||||
if m, ok := db.Params["MAX_LENGTH"]; ok {
|
||||
db.MaxLength, _ = strconv.Atoi(m)
|
||||
}
|
||||
|
||||
return db, err
|
||||
}
|
||||
|
||||
func (app *appState) Feed(feedID string) *Feed {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (app *appState) Feeds() iter.Seq2[string, *Feed] {
|
||||
return func(yield func(string, *Feed) bool) {
|
||||
app.feeds.Range(func(k, v any) bool {
|
||||
key, _ := k.(string)
|
||||
value, ok := v.(*Feed)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
if !yield(key, value) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user