-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
feat: Add File-based Caching #862
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 4 commits
dfcdd61
13e83a0
197824b
0f7a62f
473c149
f63392f
474059a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7,6 +7,9 @@ yarn.lock | |
| package-lock.json | ||
| .vercel | ||
|
|
||
| # Cache directory | ||
| cache/ | ||
|
|
||
| # Local Configuration | ||
| .DS_Store | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,171 @@ | ||||||||||||||
| <?php | ||||||||||||||
|
|
||||||||||||||
| declare(strict_types=1); | ||||||||||||||
|
|
||||||||||||||
| /** | ||||||||||||||
| * Simple file-based cache for GitHub contribution stats | ||||||||||||||
| * | ||||||||||||||
| * Caches stats for 24 hours to avoid repeated API calls | ||||||||||||||
| */ | ||||||||||||||
|
|
||||||||||||||
| // Default cache duration: 24 hours (in seconds) | ||||||||||||||
| define("CACHE_DURATION", 24 * 60 * 60); | ||||||||||||||
| define("CACHE_DIR", __DIR__ . "/../cache"); | ||||||||||||||
|
|
||||||||||||||
| /** | ||||||||||||||
| * Generate a cache key for a user's request | ||||||||||||||
| * | ||||||||||||||
| * @param string $user GitHub username | ||||||||||||||
| * @param array $options Additional options that affect the stats (mode, exclude_days, starting_year) | ||||||||||||||
| * @return string Cache key (filename-safe) | ||||||||||||||
| */ | ||||||||||||||
| function getCacheKey(string $user, array $options = []): string | ||||||||||||||
| { | ||||||||||||||
| // Normalize options | ||||||||||||||
| ksort($options); | ||||||||||||||
| $optionsString = json_encode($options); | ||||||||||||||
| return hash("sha256", $user . $optionsString); | ||||||||||||||
|
ironashram marked this conversation as resolved.
Outdated
|
||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| /** | ||||||||||||||
| * Get the cache file path for a given key | ||||||||||||||
| * | ||||||||||||||
| * @param string $key Cache key | ||||||||||||||
| * @return string Full path to cache file | ||||||||||||||
| */ | ||||||||||||||
| function getCacheFilePath(string $key): string | ||||||||||||||
| { | ||||||||||||||
| return CACHE_DIR . "/" . $key . ".json"; | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| /** | ||||||||||||||
| * Ensure the cache directory exists | ||||||||||||||
| * | ||||||||||||||
| * @return bool True if directory exists or was created | ||||||||||||||
| */ | ||||||||||||||
| function ensureCacheDir(): bool | ||||||||||||||
| { | ||||||||||||||
| if (!is_dir(CACHE_DIR)) { | ||||||||||||||
| return mkdir(CACHE_DIR, 0755, true); | ||||||||||||||
| } | ||||||||||||||
| return true; | ||||||||||||||
| } | ||||||||||||||
|
DenverCoder1 marked this conversation as resolved.
|
||||||||||||||
|
|
||||||||||||||
| /** | ||||||||||||||
| * Get cached stats if available and not expired | ||||||||||||||
| * | ||||||||||||||
| * @param string $user GitHub username | ||||||||||||||
| * @param array $options Additional options | ||||||||||||||
| * @param int $maxAge Maximum age in seconds (default: 24 hours) | ||||||||||||||
| * @return array|null Cached stats array or null if not cached/expired | ||||||||||||||
| */ | ||||||||||||||
| function getCachedStats(string $user, array $options = [], int $maxAge = CACHE_DURATION): ?array | ||||||||||||||
| { | ||||||||||||||
| $key = getCacheKey($user, $options); | ||||||||||||||
| $filePath = getCacheFilePath($key); | ||||||||||||||
|
|
||||||||||||||
| if (!file_exists($filePath)) { | ||||||||||||||
| return null; | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| $fileAge = time() - filemtime($filePath); | ||||||||||||||
| if ($fileAge > $maxAge) { | ||||||||||||||
| // Cache expired, delete the file | ||||||||||||||
| if (file_exists($filePath)) { | ||||||||||||||
| unlink($filePath); | ||||||||||||||
| } | ||||||||||||||
|
||||||||||||||
| // Cache expired, delete the file | |
| if (file_exists($filePath)) { | |
| unlink($filePath); | |
| } | |
| // Cache expired, delete the file (ignore errors if it was already removed) | |
| @unlink($filePath); |
Uh oh!
There was an error while loading. Please reload this page.