diff options
| author | haturatu <taro@eyes4you.org> | 2025-10-12 20:17:28 +0900 |
|---|---|---|
| committer | haturatu <taro@eyes4you.org> | 2025-10-12 20:17:46 +0900 |
| commit | 5943ca5e9856b9ec08efc372f1ee515460432620 (patch) | |
| tree | 55562880591b622de00941fc750cff45d1532558 /handlers/admin.go | |
| parent | 96f2fed1577e69b62134187c61a4dcf7d864c52b (diff) | |
feat(goroutine): workerpool
Diffstat (limited to 'handlers/admin.go')
| -rw-r--r-- | handlers/admin.go | 54 |
1 files changed, 51 insertions, 3 deletions
diff --git a/handlers/admin.go b/handlers/admin.go index 44c36a5..61519fa 100644 --- a/handlers/admin.go +++ b/handlers/admin.go @@ -5,11 +5,22 @@ import ( "auth-proxy/logging" "auth-proxy/models" "auth-proxy/types" + "auth-proxy/worker" "encoding/json" + "fmt" "net/http" "strconv" + "sync" + "time" ) +var workerPool *types.WorkerPool + +// SetWorkerPool sets the package-level worker pool instance. +func SetWorkerPool(pool *types.WorkerPool) { + workerPool = pool +} + // AdminPageHandler serves the admin dashboard page. func AdminPageHandler(w http.ResponseWriter, r *http.Request) { // Fetch all users to render on the page @@ -24,12 +35,20 @@ func AdminPageHandler(w http.ResponseWriter, r *http.Request) { "Paths": config.Paths, "Users": users, } - if err := templates.ExecuteTemplate(w, "admin.html", data); err != nil { + if err := templates.ExecuteTemplate(w, "admin.html", data); err != nil { logging.AppLog.Error("Failed to execute admin template", "error", err) } } -// GetUsersHandler returns a list of all users. +// EnrichedUser is a wrapper for User with additional computed fields. +// Note: We use pointers to the original User to avoid copying large structs. +type EnrichedUser struct { + *types.User + TimeSinceLogin string `json:"time_since_login"` +} + +// GetUsersHandler returns a list of all users with enriched information. +// It uses a worker pool to calculate extra information for each user in parallel. func GetUsersHandler(w http.ResponseWriter, r *http.Request) { ip := logging.GetClientIP(r) users, err := models.GetAllUsers() @@ -39,8 +58,37 @@ func GetUsersHandler(w http.ResponseWriter, r *http.Request) { return } + enrichedUsers := make([]EnrichedUser, len(users)) + var wg sync.WaitGroup + + for i, user := range users { + wg.Add(1) + // Create copies of loop variables to avoid race conditions in the closure + index := i + userCopy := user + + task := func() { + defer wg.Done() + // Simulate some work, e.g., calculating a value or fetching related data. + time.Sleep(5 * time.Millisecond) + + timeSinceLogin := "N/A" + if userCopy.LastLoginAt.Valid { + timeSinceLogin = fmt.Sprintf("%.0fm ago", time.Since(userCopy.LastLoginAt.Time).Minutes()) + } + + enrichedUsers[index] = EnrichedUser{ + User: &userCopy, + TimeSinceLogin: timeSinceLogin, + } + } + worker.Submit(workerPool, task) + } + + wg.Wait() // Wait for all tasks to complete + w.Header().Set("Content-Type", "application/json") - if err := json.NewEncoder(w).Encode(users); err != nil { + if err := json.NewEncoder(w).Encode(enrichedUsers); err != nil { logging.AppLog.Error("Failed to encode users to JSON", "error", err, "ip", ip) } } |
