Filter
Exclude
Time range
-
Near
🚀 開発環境が更新されました。以下のPRがマージされました。#オプチャグラフ #496: [STG] perf: ルーム統計グラフの初回表示を軽量化し、アクセス集中時のDB競合を低減(タブ判定の事前計算+表示期間だけ取得) --- ## 何が変わるか ルーム個別ページ(/oc/{id})のグラフ初回表示で、サーバが叩くDBを大きく減らす。特に Googlebot 等のクロール集中時に出ていた `database is locked` 系のDB競合を緩和する。 ## これまでの問題 グラフ初回表示で2つの重い読み取りが毎回走っていた。 1. タブ/ボタン出し分け判定(可用性メタ)のために、表示のたびに4つのDB(統計・ローソク足・順位の各SQLiteと毎時データのMariaDB)へCOUNT。 2. 系列データを、表示は週/月/全をクライアントで切り出すだけなのに、初回に全期間ぶん取得。 アクセス集中時、statistics 等のSQLite読みが競合し `database is locked`(本番エラー: [TH] Googlebot, span=hour・meta=1 の初回ロードで `getDailyMemberStatsDateAsc` が locked)の一因になっていた。 ## 対処 1. 可用性メタを cron で事前計算し MySQL の `oc_page_cache.chart_meta` に持たせ、/oc 表示の既存1クエリで読みHTMLに埋め込む。初回の meta=1 リクエストを撃たない。 2. 系列は表示中の期間タブの窓だけ取得し、拡大時は足りない古い側の差分だけ取得(窓は最新日終端固定なので連続1範囲)。一度取得した範囲は再取得しない。 3. 系列を層(member / position / memberOhlc / positionOhlc)に分け、`?series=` で必要な層×不足範囲だけ取得(全期間で人数表示中に順位ONしても人数は再取得しない)。 4. 事前計算の毎時順位は実行ごとに1回の一括GROUP BY(バックフィルでも MySQL gone away を起こさない)。 5. 取得が一過性の5xx(リトライ後も不可)・403等で最終失敗したら、壊れた表示でなく再読み込みを促すエラー表示。5xx は fetcher が1回だけ自動リトライ。 ## アーキテクチャ(データの流れ) フロント → API: - 初回: /oc ページHTMLに埋め込んだ可用性メタ `#chart-meta` を `fetchRenderer.ts`(readEmbeddedChartMeta) が読む。埋め込みがあれば初回 meta=1 を撃たない(`App.tsx` init → `fetchChartData`)。 - 系列取得: `fetchRenderer.ts` が層別に `GET /oc/{id}/chart?series=<member,position,…>&sort&scope&category&mode&from&to` を叩く。各層を date→値でキャッシュし、必要層の足りない古い範囲だけ・同範囲の層はまとめて1リクエスト。`fetcher.ts` が URLキャッシュ+5xx 1回リトライ。操作時は `chartState.ts`(handleChangeLimit / handleChangeRankingRising / handleChangeChartMode / handleChangeCategory) → fetchChart。 API 処理: - ルート `oc/{open_chat_id}/chart` → `OpenChatChartApiController::chart` → `OpenChatChartApiService::buildChartResponse`。 - `series` 指定で層だけ返す/`from`・`to` で範囲化/`meta=1` でメタ同梱(埋め込み無し室のフォールバック)/`span=hour` は最新24時間。 - 系列の組み立て: 人数=`StatisticsChartArrayService::buildStatisticsChartArray`、順位=`RankingPositionChartArrayService::getRankingPositionChartArray`、ローソク足=`buildCandlestickSeries`、最新24時間=`buildHourSeries`。 リポジトリ: - 人数: `SqliteStatisticsPageRepository::getDailyMemberStatsDateAsc`(statistics SQLite・`date BETWEEN`)/日付範囲 `getMemberDateRange`。 - 順位: `SqliteRankingPositionPageRepository::getDailyPosition`(ranking_position SQLite)。 - ローソク足: `SqliteStatisticsOhlcRepository` / `SqliteRankingPositionOhlcRepository`(`getOhlcDateAsc`)。 - 最新24時間・メタのhour集計: `RankingPositionHourRepository`(MariaDB。1室 `getHourPositionCounts` / 一括 `getHourPositionCountsAll`)。 - メタの読み(primary): `OpenChatPageRepository::getOpenChatByIdWithTag` が `oc_page_cache` を LEFT JOIN(narrative と chart_meta を1クエリ)。`OpenChatPageController` が `#chart-meta` へ埋め込む。 cron でのキャッシュ更新(条件は下表): - `oc_page_cache.chart_meta` は `OcPageCacheGenerator::generateForIds`(per-room) が `ChartMeta\ChartMetaBuilder::build` で生成し `OcPageCacheRepository::upsertMany` で保存。毎時順位は `UpdateOcPageCacheService::handle` がチャンクループの外で一括 `getHourPositionCountsAll` を1回だけ取得して渡す(per-room MariaDB を撃たず gone away 回避)。 - 起動は `SyncOpenChat::hourlyTask`(毎時) / `dailyTask`(日次) / genetop(全件)。 フォールバック(埋め込みが無い室): - `#chart-meta` が null → フロントは meta=1 を撃つ → `OpenChatChartApiService` が `ChartMetaBuilder::build`(hourEntry 無し=ライブ・per-room で hour 取得)でメタを作る。primary(cron) と同一コードなので結果は一致する。 - メタ計算は `app/Services/Statistics/ChartMeta/ChartMetaBuilder.php` の1箇所のみ。`StatisticsChartArrayService` は「メンバー系列生成専用」。 ## oc_page_cache の生成タイミング(マッピング) chart_meta は分析文(narrative)と同じ `oc_page_cache` 行に同梱され、同じ再生成経路で作られる。件数は ja(本番同等ローカル)実測。 | タイミング | 起動 | 対象の室(条件) | 件数(ja実測) | |---|---|---|---| | 毎時 | `SyncOpenChat::hourlyTask`(毎時30分) | 直近1時間で人数が変わった室 + 新規ランク入り | 約 4,320 | | 日次 | `dailyTask`(23:30) | `getForDaily` = 変動(過去8日) + 新規(レコード8件未満) + 週次更新(最終記録が1週間以上前)。ランキング外の室も週次更新で拾い、最長でも約1週間で全室が一巡 | 約 108,274 | | genetop(全件) | 管理画面 | `getOpenChatIdAll` = 全室。毎時順位は一括化済みで全件でも gone away しない(ただし時間はかかる) | 約 242,386 | | バックフィル / write-through | 管理画面 / idCsv 指定 | 指定した室のみ | 指定数 | ## 未生成室(chart_meta が無い室)の挙動 - 新規室、または初回バックフィル前の室は chart_meta が無い → ページ埋め込みが null → フロントは meta=1 でライブ計算(ChartMetaBuilder)にフォールバックする。 - このときの系列は全期間取得になり、窓・差分の最適化は効かない。ただし表示は壊れない(従来どおり=無劣化)。 ## フォールバックを外せない理由 - 新規室が常時発生し、次の再生成まで chart_meta を持たないため、ライブ計算経路は恒久的に必要。 - ただしリファクタで「二重実装」は解消済み。フォールバックは同じ `ChartMetaBuilder` のライブ実行であって、余計なコードではない。 ## 主な変更箇所 - 事前計算: `Statistics/ChartMeta/ChartMetaBuilder`・`Statistics/ChartMeta/ChartAvailabilityCalculator`(しきい値の単一定義)・`OcPageCacheGenerator`(毎時順位は一括 `getHourPositionCountsAll`)・`UpdateOcPageCacheService`。 - 同梱: `OpenChatPageController` / `Views/oc_content.php` / `OpenChatPageRepository`(chart_meta をJOINで読む)。 - API: `OpenChatChartApiController` / `OpenChatChartApiService`(from/to 範囲+`series` 層)と各系列リポジトリ(`date BETWEEN`)。 - フロント: `frontend/oc-app`(層別の最小差分取得、取得失敗時のエラー表示、5xx 1回リトライ)。 - genetop: 全室の `oc_page_cache` 再生成を追加。 - CLAUDE.md: 毎時/日次にキャッシュ生成を足したら genetop で全件再生成できるようにするルールを明記。 ## デプロイ・運用 - `oc_page_cache` に `chart_meta` 列を追加(デプロイ時 `sync_mysql_schema` が自動反映、手動DDL不要)。CI/mock も `setup/init-database.sh` が schema から構築するので列は在る(NULL時はフォールバックで /oc は200)。`deploy.yml` 変更不要。 - 反映後に genetop を1回実行すると全室の chart_meta が揃い、全室が窓・差分の最適化経路に乗る。実行しなくても毎時/日次で順次埋まり(最長約1週間)、未生成室はそれまでフォールバックで無劣化。 ## 確認 - 埋め込みメタ == meta=1 ライブ計算 が実データ複数室で一致(同一 ChartMetaBuilder)。 - `series` 未指定の全レスポンス行列が改修前とバイト一致(後方互換)。`series` 各層は該当層のみ返し、範囲も有効。順位ON時は `series=position` 1本のみで人数を再取得しないことをNetworkで実証。 - 窓→拡大が差分のみ・再取得なし・繋ぎ目で連続描画、ローソク足のタブ維持、新規室のフォールバック、最新24時間をヘッドレスで確認。 - PHPStan / PHPUnit(新規テスト含む)green。 --- 🤖 Generated with Claude Code (claude-opus-4-8[1m]) Posted from: `user-B550M-Pro4:~/repos/Open-Chat-Graph` ## 追記: レスポンスのさらなる軽量化(2コミット) 層別取得のデータ形をさらに削った。 - ローソク足の日付を1本に集約: OHLCの各要素が持っていた `date` をやめ、OHLC専用の日付軸 `ohlcDate` を1本だけ返す。`memberOhlc`/`positionOhlc` はこの軸とindex整合の「値だけ」の配列にした(人数と順位の両方を表示すると日付配列が3本になっていたのを1本に。`positionOhlc` の `null` はその日が圏外)。 - 順位の時刻配列を急上昇のみに: 時刻ラベル `time` は終日時刻を持つ急上昇でだけ返し、ランキング・人数のみ・最新24時間・ローソク足では配列ごと返さない(フロントは「無ければ時刻表示なし」として扱う)。 - `frontend/oc-app/README.md` を追加し、表示状態ごとに送るAPIと返るデータ型を明記。 検証: PHPStan / 該当 PHPUnit(OpenChatChartApiServiceTest 10件)/ tsc 通過。折れ線・ローソク足 × ランキング・急上昇・なし × 期間タブの全ビューをヘッドレスで描画確認(JSエラーなし・順位オーバーレイ整合・tooltipが人数OHLCと順位OHLCの両方を表示)。 --- 🤖 Generated with Claude Code (claude-opus-4-8[1m]) Posted from: `user-B550M-Pro4:~/repos/Open-Chat-Graph`
2
460
SlayerD22 retweeted
Get your SPA on Sis! ❤️ Strive to be a better you, daily! 🦋 #DOS #Study #Pray #Apply #DailyTask #SPA #Growth
5
11
129
Be the thermostat for your life, control your emotions! 🦋👑 #DOS #SelfControl #Growth #DailyTask #Emotions
9
14
63
Hôm nay tôi vừa hoàn thành một trong những task khó nhất cuộc đời Web3 gamer của mình. Không phải trade future. Không phải debug smart contract. Cũng không phải săn whitelist. Mà là… bỏ quả cà chua vào chảo! Nghe thì đơn giản, nhưng tôi đã mất hơn 5 phút chiến đấu với camera, góc nhìn, thao tác và cả sự kiên nhẫn của bản thân mới hoàn thành được nhiệm vụ này. Khoảnh khắc hiện dòng chữ ‘Task Completed’ thật sự khiến tôi hạnh phúc hơn cả lúc claim airdrop. Đôi khi niềm vui trong cuộc sống chỉ đơn giản là đặt đúng quả cà chua vào đúng cái chảo thôi 🤣 @axisrobotics #dailytask
1
5
38
📢 Attention All Ambassadors! If you’ve been submitting Daily Tasks from Task 58 onwards, make sure your correct social media links are updated on your profile immediately. 🔗✅ The verification system tracks your activity directly through the linked accounts. 👀 Writing ⚠️ Important Reminder If your social media links are: ❌ Missing ❌ Incorrect ❌ Not Updated the system may fail to detect your activity, which could lead to point deductions during evaluation. 📉 Writing 🚨 Don’t Risk Your Ambassador Benefits! Update all active and correct social media accounts on your profile before the deadline to ensure your performance is properly tracked. ✅🔥 ⏰ Deadline: May 17, 2026 #AmbassadorProgram #SocialMediaUpdate #Verification #DailyTask #Community #Web3 #InterLink #UpdateNow #INTERLINK #ITLG #ITL
9
283
I worked every day, I tried! But alas(((( I feel pain and humiliation #Otherside #DanielArsham #NFT #WL @DanielArsham @ApeChainHUB @OthersideMeta #Otherside #DailyTask
5
15
243
ట్విట్టర్ థ్రెడ్: ఇంటర్లింక్ తాజ్ మహల్ టెస్ట్‌నెట్ & మాస్టర్ కార్డ్ 🚀 ​1/6 భవిష్యత్తు నిర్మాణం జరుగుతోంది! 🏗️ కేవలం ఒక అప్‌డేట్ మాత్రమే కాదు, క్రిప్టో ప్రపంచంలో ఒక విప్లవం రాబోతోంది. ఇంటర్లింక్ తాజ్ మహల్ టెస్ట్‌నెట్ (ప్రివ్యూ) ఇప్పుడు అందుబాటులోకి వచ్చింది. మెయిన్‌నెట్ వైపు మన ప్రయాణం మరింత వేగవంతమైంది! 🔥 #Interlink #Web3 #TajMahalTestnet ​2/6 క్రిప్టో ఇప్పుడు మీ జేబులో! 💳 ఇంటర్లింక్ మాస్టర్ కార్డ్ ద్వారా డిజిటల్ అసెట్స్‌ని నిజ జీవితంలో వాడుకోవడం ఇప్పుడు సులభం. ✅ గ్లోబల్ పేమెంట్ సొల్యూషన్స్ ✅ వెబ్3 & రియల్ వరల్డ్ కనెక్షన్ ✅ రోజువారీ ఖర్చుల కోసం సరికొత్త మార్గం! 🔗 #Mastercard #CryptoPayments ​3/6 పరిమితులు లేని ఆర్థిక స్వేచ్ఛ! 💰 ఈ కార్డ్ ద్వారా సుమారు $50,000 వరకు హై-లిమిట్ ట్రాన్సాక్షన్స్ చేసుకునే వీలుంది. ఎక్కడికి వెళ్లినా, ఎంత ఖర్చు చేసినా ఇంటర్లింక్ మీ వెంటే ఉంటుంది. 🌍 #FinancialFreedom #Blockchain ​4/6 మీకు ఇష్టమైన బ్రాండ్స్, ఇప్పుడు ఇంటర్లింక్‌తో! 🛒 Amazon, Uber, PayPal, Shopee, TikTok, మరియు YouTube వంటి గ్లోబల్ ప్లాట్‌ఫామ్స్‌లో మీ కార్డ్‌ని వాడుకోవచ్చు. అంతేకాకుండా Apple Pay & Google Pay సపోర్ట్‌తో స్మార్ట్ పేమెంట్స్ మరింత వేగంగా! ⚡📱 #GlobalShopping #TechInnovation ​5/6 ఇది కేవలం టెక్నాలజీ మాత్రమే కాదు, మేధోమథనం! 🔬 ప్రపంచ స్థాయి ఇంజనీర్లు మరియు శాస్త్రవేత్తల పర్యవేక్షణలో అత్యున్నత ప్రమాణాలతో ఈ ఎకోసిస్టమ్ రూపుదిద్దుకుంటోంది. ఇన్నోవేషన్ ఇక్కడ నిరంతర ప్రక్రియ. 👨‍🔬✨ #Innovation #FutureTech ​6/6 📢 డైలీ టాస్క్ 61: మన ఎకోసిస్టమ్‌లో చురుగ్గా ఉండండి, మీ కంటెంట్‌ను షేర్ చేయండి. వెబ్3 మరియు రియల్ వరల్డ్ ఫైనాన్స్‌ను కలిపే ఈ అద్భుతమైన వారధిని దాటడానికి మీరు సిద్ధంగా ఉన్నారా? 🌉✨ ​మరిన్ని వివరాల కోసం మమ్మల్ని ఫాలో అవ్వండి! #InterlinkFamily #DailyTask #BlockchainRevolution #interlink #ITLG #ITL
1
7
162
We're growing! What does effort mean to you? It means working tirelessly. @ApeChainHUB @CryptoCatsApe @OthersideMeta #Otherside #DailyTask #badges
3
66
that feeling when you reach a new level @ApeChainHUB @CryptoCatsApe @OthersideMeta #Otherside #DailyTask #badges
1
10
84
Apr 16
Gm Gm 💙💙 #Otherside Day 1 — Getting Started (for beginners) 🧵 1/ Kicking off Day 1 today. Yesterday I dropped a video, and as promised—here’s a step-by-step thread on how I started. 2/ First step: Preparation. Made sure everything was ready before jumping in—settings, tools, and a clear plan. 3/ Second step: Understanding the goal. Before doing anything, I took a moment to really understand what needs to be done today. 4/ Third step: Execution. Started slow, focused on doing things right instead of rushing. Consistency > speed.🤳🤳 5/ Completed today’s tasks ✅ Managed to finish all the required objectives for Day 1. 6/ After finishing, I showed you how to get some of the badges 🎯 Walked through a few simple ways to unlock them and what to focus on.👀 More coming soon… stay tuned 🚀 #otherside #dailytask #Web3‌‌ #gaming #game #NFT #ETH #Ape
13
6
56
10,903
We are completing a new task in the swamp @ApeChainHUB @CryptoCatsApe @OthersideMeta #Otherside #DailyTask #badges
1
1
8
217