后端:游玩计数排序移出互斥锁
- game_play_counter.rs:drain 只负责在锁内取走增量,新增 sort_deltas 在释放锁后排序,避免 O(n log n) 排序阻塞并发 record
This commit is contained in:
@@ -157,13 +157,17 @@ impl GamePlayCounter {
|
||||
return None;
|
||||
}
|
||||
state.last_flush_at = now;
|
||||
Some(drain_pending(&mut state.pending))
|
||||
let deltas = drain_pending(&mut state.pending);
|
||||
drop(state);
|
||||
Some(sort_deltas(deltas))
|
||||
}
|
||||
|
||||
/// 无条件取走全部增量,供关停 flush 使用。
|
||||
pub fn take_pending(&self) -> Vec<GamePlayCountDelta> {
|
||||
let mut state = self.lock();
|
||||
drain_pending(&mut state.pending)
|
||||
let deltas = drain_pending(&mut state.pending);
|
||||
drop(state);
|
||||
sort_deltas(deltas)
|
||||
}
|
||||
|
||||
/// 写库失败时把增量放回,等待下一次 flush。
|
||||
@@ -207,11 +211,14 @@ impl GamePlayCounter {
|
||||
}
|
||||
|
||||
fn drain_pending(pending: &mut HashMap<String, u64>) -> Vec<GamePlayCountDelta> {
|
||||
let mut deltas = pending
|
||||
pending
|
||||
.drain()
|
||||
.filter_map(|(game_id, delta)| (delta > 0).then_some(GamePlayCountDelta { game_id, delta }))
|
||||
.collect::<Vec<_>>();
|
||||
// 稳定批次顺序,便于测试与日志比对。
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// 稳定批次顺序,便于测试与日志比对;调用方已释放计数锁,排序不阻塞并发 `record`。
|
||||
fn sort_deltas(mut deltas: Vec<GamePlayCountDelta>) -> Vec<GamePlayCountDelta> {
|
||||
deltas.sort_by(|left, right| left.game_id.cmp(&right.game_id));
|
||||
deltas
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user