File size: 1,750 Bytes
3c5a6a0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
"""๋ฆฌ๋”๋ณด๋“œ DataFrame ์ „์—ญ ์บ์‹œ + ํŒŒ์ผ ๊ธฐ๋ฐ˜ ์‹œ๊ทธ๋„.

๋งค ํŽ˜์ด์ง€ ๋กœ๋“œ๋งˆ๋‹ค Google Sheets ๋ฅผ ๋‹ค์‹œ ์น˜๋ฉด ๋А๋ฆฌ๊ณ  429(rate limit) ์œ„ํ—˜์ด
์žˆ์œผ๋ฏ€๋กœ, ์ตœ์ดˆ 1ํšŒ๋งŒ fetch ํ•ด์„œ ๋ฉ”๋ชจ๋ฆฌ์— ์บ์‹œํ•œ๋‹ค. Refresh ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๋ฉด
invalidate_cache() ๋กœ ๊ฐ•์ œ ์žฌfetch. ๋‹ค๋ฅธ ํ”„๋กœ์„ธ์Šค๊ฐ€ ์‹œ๊ทธ๋„ ํŒŒ์ผ์— ์ตœ์‹ 
ํƒ€์ž„์Šคํƒฌํ”„๋ฅผ ๊ธฐ๋กํ•˜๋ฉด refresh_if_signal_newer() ๊ฐ€ ์ด๋ฅผ ๊ฐ์ง€ํ•ด ๊ฐฑ์‹ ํ•œ๋‹ค.

(์›๋ณธ ๋ ˆํฌ์˜ DB ์ฝ๊ธฐ ๋ถ„๊ธฐ๋Š” ์ด Space ์—์„œ ๋ถˆํ•„์š”ํ•˜๋ฏ€๋กœ ์ œ๊ฑฐ โ€” Google Sheets ์ง์ ‘ ์ฝ๊ธฐ๋งŒ ๋‚จ๊น€)
"""

import os
import threading
import time

from sheet_manager.sheet_loader.sheet2df import sheet2df

_lock = threading.Lock()
_cached_df = None
_cache_timestamp = 0.0

SIGNAL_FILE = "/tmp/pia_leaderboard_cache_signal"


def get_cached_df():
    """์บ์‹œ๋œ DataFrame ๋ฐ˜ํ™˜. ์ตœ์ดˆ ํ˜ธ์ถœ ์‹œ fetch."""
    global _cached_df, _cache_timestamp
    with _lock:
        if _cached_df is None:
            _cached_df = sheet2df()
            _cache_timestamp = time.time()
        return _cached_df.copy()


def invalidate_cache():
    """์บ์‹œ๋ฅผ ์ฆ‰์‹œ ๊ฐฑ์‹  (Google Sheets ์—์„œ ๋‹ค์‹œ ์ฝ๊ธฐ)."""
    global _cached_df, _cache_timestamp
    new_df = sheet2df()
    with _lock:
        _cached_df = new_df
        _cache_timestamp = time.time()


def refresh_if_signal_newer():
    """์‹œ๊ทธ๋„ ํŒŒ์ผ์ด ์บ์‹œ๋ณด๋‹ค ์ตœ์‹ ์ด๋ฉด ๊ฐฑ์‹  ํ›„ ๋ฐ˜ํ™˜. ์•„๋‹ˆ๋ฉด ์บ์‹œ ๊ทธ๋Œ€๋กœ."""
    try:
        if os.path.exists(SIGNAL_FILE):
            with open(SIGNAL_FILE) as f:
                signal_ts = float(f.read().strip())
            if signal_ts > _cache_timestamp:
                invalidate_cache()
    except (ValueError, OSError):
        pass
    return get_cached_df()