Sobes.tech
Senior

You are a writer, running your own mini blog where you publish articles. Users (readers) of your blog, after logging in, can view/read them. It is necessary to implement a functionality to count unique views per day for each article. Functional requirements: - Today's statistics: The author can see how many unique users viewed their article today (data is accumulated in real-time). - Past days' statistics: The author can see statistics for any past day (for example, yesterday). Technical constraints and conditions: - The application runs on 1 server (1 pod) - Storage in memory - Time in UTC0

sobes.tech AI

Answer from AI

To count unique article views per day considering requirements and limitations (single server, in-memory, UTC0 time), the following scheme can be implemented:

  • For each day and each article, store a set of unique user IDs who viewed the article on that day.
  • Data for the current day is accumulated in real-time.
  • Data for past days is stored in a separate structure (e.g., in a map with key date+article).

Example in Go:

import (
    "sync"
    "time"
)

// Structure for storing views
// map[date][articleID] -> set of userIDs
var (
    mu sync.RWMutex
    views = make(map[string]map[string]map[string]struct{})
)

func getDateUTC(t time.Time) string {
    return t.UTC().Format("2006-01-02")
}

// Function to register a view
func RegisterView(articleID, userID string) {
    date := getDateUTC(time.Now())

    mu.Lock()
    defer mu.Unlock()

    if _, ok := views[date]; !ok {
        views[date] = make(map[string]map[string]struct{})
    }
    if _, ok := views[date][articleID]; !ok {
        views[date][articleID] = make(map[string]struct{})
    }
    views[date][articleID][userID] = struct{}{}
}

// Get the number of unique views for a specific day
func GetUniqueViews(articleID, date string) int {
    mu.RLock()
    defer mu.RUnlock()

    if dayData, ok := views[date]; ok {
        if users, ok := dayData[articleID]; ok {
            return len(users)
        }
    }
    return 0
}

Features:

  • Uses a nested map to store unique users.
  • Uses a set (map[string]struct{}) for user uniqueness.
  • Time is in UTC to correctly group views by date.
  • For statistics of past days, simply access the relevant date.

Since the application runs on a single server and in-memory, this approach will work efficiently. Periodic cleanup of old data can be added if necessary.

You are a writer, running your own mini blog where… - sobes.tech