איך המטמון עובד

המטמון של WIZZO CMS הוא קבצים בלבד, בלי Redis: מחלקת cache_engine, ארבעה סוגי מטמון, תיקייה לכל דומיין, תוקף שנקבע לפי זמן השינוי של הקובץ וכתיבה אטומית. מה נשמר ואיפה.

⏱ 4 דק' קריאה 713 מילים ערוך דף זה ב-GitHub

כל המטמון של WIZZO CMS נשמר כקבצים בתיקייה אחת, ואת כולו מנהלת מחלקה אחת: cache_engine בקובץ api/core/collections/cache_engine.php. אין Redis ואין Memcached. בדף הזה תבינו אילו סוגי מטמון יש, איפה כל אחד נשמר, איך נקבע תוקף, ומה חשוב לדעת כדי לא להתבלבל.

בעמוד הזה system/ הוא תיקיית הליבה הפרוסה (= api/core בריפו) ו-{admin} הוא CONFIG::$admin_url של האתר.

ארבעה סוגי מטמון#

סוגמתי משתמשיםAPIקובץ
נתוניםתוצאת שאילתה או חישוב שמחזיקים כל ערך PHPget, remove, save_cache_file, get_cache_file<key>.chc.gz
קטע HTMLבלוק כבד בתבנית (תפריט, sidebar) שמשותף לעמודים רביםget_html, remove_html<key>.html
Itemsרשומה בודדת לפי id שהבנייה שלה יקרהset_item, get_item, remove_item, refresh_itemitems/<type>/<id>
עמוד שלםכל ה-HTML של עמוד ציבוריcache_all_page, cache_php_check, cache_all_page_remove, ping_cachepages/<url>.html.gz

כל הפונקציות סטטיות. רשימה מלאה של חתימות ב-cache_engine API, והעמודים השלמים בפירוט ב-מטמון עמודים מלא.

// נתונים: מחזיר מהמטמון, ואם אין, בונה ושומר ל-24 שעות
$cats = cache_engine::get("categories", function () {
    return DB::query("categories", [], "ord ASC")->get_all("id");
}, 24);

מיקום הקבצים#

השורש הוא CONFIG::$cache_folder (מוגדר בקונפיגורציית האתר, ונהפך לנתיב מלא בעת האתחול). בתוכו:

cache/
  params.chc.gz               נתונים גלובליים (in_platform = false)
  table_list.chc.gz
  items/<type>/12/34/12345.chc.gz   items (id מפוצל לזוגות ספרות)
  Smarty/templates_c/         תבניות Smarty מקומפלות
  www.example.com/            תיקייה לכל דומיין
    <key>.chc.gz              נתונים (ברירת מחדל: in_platform = true)
    <key>.html                קטעי HTML
    pages/<url>.html.gz       עמודים לדסקטופ
    pages_mobile/<url>.html.gz עמודים לטלפון
    scss/<url>.css            CSS שקומפל
    locks/ locks_mobile/      קבצי נעילת בנייה

שם תיקיית הדומיין הוא $_SERVER["SERVER_NAME"]. שם שריק או שמכיל /, \, .. או תו NUL מוחלף ב-_invalid_host_<hash>, כדי שבקשה עם כותרת Host עוינת לא תכתוב מחוץ לתיקייה.

פר דומיין או גלובלי#

הפרמטר $in_platform קובע את המיקום: true (ברירת המחדל של get, save_cache_file, get_cache_file) שומר בתיקיית הדומיין, ו-false שומר בשורש, משותף לכל הדומיינים של ההתקנה. הליבה שומרת גלובלית, בין השאר, את platforms, params ו-table_list, ואילו modules_lang<lang> שמור לפי פלטפורמה.

מחיקה חוצה דומיינים
cache_engine::remove($key) מוחק את המפתח מכל תיקיות הדומיינים ומהשורש, וגם כל קובץ שמתחיל בשם הזה (remove("params") מוחק גם params_backup). בחרו שמות מפתח שאינם קידומת של מפתח אחר.

תוקף: זמן השינוי של הקובץ#

אין שדה "תוקף" בתוך הקובץ. אחרי כל כתיבה הקובץ מקבל touch($file, time() + שעות * 3600), כלומר זמן השינוי שלו הוא זמן התפוגה, והוא נחשב תקף כל עוד filemtime > time().

  • ls -l על תיקיית המטמון מראה תאריכים בעתיד. זה תקין.
  • כלי שמשנה זמני שינוי (touch, rsync בלי שמירת זמנים) משנה גם את התפוגה.
  • קובץ שפג לא נמחק מיד: ניקוי פיזי מתבצע רק אחרי $gc_grace_hours (48 שעות), כדי שאפשר יהיה להגיש אותו בזמן שמישהו בונה מחדש. ראו ניקוי ותחזוקה.

כתיבה אטומית#

atomic_write כותבת לקובץ זמני (.<pid>.<uniqid>.tmp), מציבה לו את זמן התפוגה, ומחליפה את היעד ב-rename. קורא אף פעם לא רואה קובץ חצי-כתוב, וכתיבות מקבילות לאותו מפתח לא פוגעות זו בזו.

הגדרות (משתנים סטטיים)#

משתנהברירת מחדלמשמעות
$compress_pagestrueדחיסת gzip לקבצי עמודים
$compress_datatrueדחיסת gzip (רמה 6) לקבצי .chc
$use_build_locktrueנעילה נגד "עדר" בנייה של אותו עמוד
$build_lock_wait_ms750כמה זמן מחכה בקשה שהפסידה במרוץ הבנייה
$serve_stale_while_buildingtrueהגשת עמוד שפג בזמן שאחר בונה אותו
$gc_grace_hours48כמה שעות קובץ שפג נשאר לפני שנמחק
$serve_gz_directtrueשליחת הבייטים הדחוסים כמו שהם
$tracking_paramsרשימהפרמטרי מעקב שמוסרים מכתובת העמוד

שימו לב שהמחלקה אינה מכילה הגדרה של התיקייה עצמה: CONFIG::$cache_folder, CONFIG::$allow_cache ו-CONFIG::$system_type נקבעים בקונפיגורציית האתר (תצורה).

הגנה מפני שמירת כישלון
cache_engine::get עם פונקציית בנייה לא שומר את התוצאה אם DB::$error_count עלה בזמן הבנייה, כך ששאילתה שנכשלה לא נשמרת כאמת למשך כל ה-TTL. ההגנה הזאת קיימת רק ב-get: get_html ו-get_item שומרים בלי לבדוק.

הרשאות תיקיות

תיקיות המטמון נוצרות דרך FILES::make_dir(), שברירת המחדל שלה היא 0777 עם umask(0). בשרת משותף זה חושף את הקבצים למשתמשים אחרים. הגדירו הרשאות הדוקות ברמת השרת.

מה לא נשמר במטמון עמודים#

עמודי אדמין (CONFIG::$system_type == "admin") אינם נשמרים, וגם לא עמוד שהבקר שלו לא ביקש מטמון (cache_all_page). תגובת 503 ועמוד 404 שמגיע דרך MODULE::errorpage() מסומנים במפורש PAGE::$cache_this_page = false. ראו מטמון עמודים מלא.

ראו גם#

מצאתם טעות או חוסר? תקנו את הדף או פתחו Issue בריפו. התיעוד נכתב מתוך הקוד של ליבה 5.0.115.