[perf] dont immediately update view cache
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
2024-01-21 11:29:26 -05:00
parent 9bd6bf7727
commit 2d63a7d109
7 changed files with 41 additions and 131 deletions

View File

@@ -5,9 +5,11 @@ import (
"database/sql"
_ "embed"
"fmt"
"path"
"time"
log "github.com/sirupsen/logrus"
_ "modernc.org/sqlite"
"path"
"reichard.io/antholume/config"
)
@@ -20,12 +22,6 @@ type DBManager struct {
//go:embed schema.sql
var ddl string
//go:embed update_temp_tables.sql
var tsql string
//go:embed update_document_user_statistics.sql
var doc_user_stat_sql string
func NewMgr(c *config.Config) *DBManager {
// Create Manager
dbm := &DBManager{
@@ -63,24 +59,26 @@ func (dbm *DBManager) Shutdown() error {
return dbm.DB.Close()
}
func (dbm *DBManager) UpdateDocumentUserStatistic(documentID string, userID string) error {
// Prepare Statement
stmt, err := dbm.DB.PrepareContext(dbm.Ctx, doc_user_stat_sql)
if err != nil {
return err
}
defer stmt.Close()
// Execute
if _, err := stmt.ExecContext(dbm.Ctx, documentID, userID); err != nil {
return err
}
return nil
}
func (dbm *DBManager) CacheTempTables() error {
if _, err := dbm.DB.ExecContext(dbm.Ctx, tsql); err != nil {
start := time.Now()
user_streaks_sql := `
DELETE FROM user_streaks;
INSERT INTO user_streaks SELECT * FROM view_user_streaks;
`
if _, err := dbm.DB.ExecContext(dbm.Ctx, user_streaks_sql); err != nil {
return err
}
log.Debug("[CacheTempTables] Cached 'user_streaks' in: ", time.Since(start))
start = time.Now()
document_statistics_sql := `
DELETE FROM document_user_statistics;
INSERT INTO document_user_statistics SELECT * FROM view_document_user_statistics;
`
if _, err := dbm.DB.ExecContext(dbm.Ctx, document_statistics_sql); err != nil {
return err
}
log.Debug("[CacheTempTables] Cached 'document_user_statistics' in: ", time.Since(start))
return nil
}

View File

@@ -1,77 +0,0 @@
INSERT INTO document_user_statistics
WITH intermediate_ga AS (
SELECT
ga1.id AS row_id,
ga1.user_id,
ga1.document_id,
ga1.duration,
ga1.start_time,
ga1.start_percentage,
ga1.end_percentage,
-- Find Overlapping Events (Assign Unique ID)
(
SELECT MIN(id)
FROM activity AS ga2
WHERE
ga1.document_id = ga2.document_id
AND ga1.user_id = ga2.user_id
AND ga1.start_percentage <= ga2.end_percentage
AND ga1.end_percentage >= ga2.start_percentage
) AS group_leader
FROM activity AS ga1
WHERE
document_id = ?
AND user_id = ?
),
grouped_activity AS (
SELECT
user_id,
document_id,
MAX(start_time) AS start_time,
MIN(start_percentage) AS start_percentage,
MAX(end_percentage) AS end_percentage,
MAX(end_percentage) - MIN(start_percentage) AS read_percentage,
SUM(duration) AS duration
FROM intermediate_ga
GROUP BY group_leader
),
current_progress AS (
SELECT
user_id,
document_id,
COALESCE((
SELECT percentage
FROM document_progress AS dp
WHERE
dp.user_id = iga.user_id
AND dp.document_id = iga.document_id
ORDER BY created_at DESC
LIMIT 1
), end_percentage) AS percentage
FROM intermediate_ga AS iga
GROUP BY user_id, document_id
HAVING MAX(start_time)
)
SELECT
ga.document_id,
ga.user_id,
MAX(start_time) AS last_read,
SUM(duration) AS total_time_seconds,
SUM(read_percentage) AS read_percentage,
cp.percentage,
(CAST(COALESCE(d.words, 0.0) AS REAL) * SUM(read_percentage))
AS words_read,
(CAST(COALESCE(d.words, 0.0) AS REAL) * SUM(read_percentage))
/ (SUM(duration) / 60.0) AS wpm
FROM grouped_activity AS ga
INNER JOIN
current_progress AS cp
ON ga.user_id = cp.user_id AND ga.document_id = cp.document_id
INNER JOIN
documents AS d
ON d.id = ga.document_id
GROUP BY ga.document_id, ga.user_id
ORDER BY wpm DESC;

View File

@@ -1,6 +0,0 @@
DELETE FROM user_streaks;
INSERT INTO user_streaks SELECT * FROM view_user_streaks;
DELETE FROM document_user_statistics;
INSERT INTO document_user_statistics
SELECT *
FROM view_document_user_statistics;