enhance(backend): チャートの処理を一つずつ行うことでDBの同時接続とタイムアウトを削減 (#15239)
* sync charts one-at-a-time to reduce database contention and timeouts * fix merge resolve failure * Update Changelog * update changelog * add comments --------- Co-authored-by: Hazelnoot <acomputerdog@gmail.com>
This commit is contained in:
		
							parent
							
								
									13439e04c4
								
							
						
					
					
						commit
						c4192e81ed
					
				|  | @ -25,6 +25,8 @@ | |||
| 
 | ||||
| ### Server | ||||
| - Enhance: pg_bigmが利用できるよう、ノートの検索をILIKE演算子でなくLIKE演算子でLOWER()をかけたテキストに対して行うように | ||||
| - Enhance: チャート更新時にDBに同時接続しないように   | ||||
|   (Cherry-picked from https://activitypub.software/TransFem-org/Sharkey/-/merge_requests/830) | ||||
| - Fix: ユーザーのプロフィール画面をアドレス入力などで直接表示した際に概要タブの描画に失敗する問題の修正( #15032 ) | ||||
| - Fix: 起動前の疎通チェックが機能しなくなっていた問題を修正   | ||||
|   (Cherry-picked from https://activitypub.software/TransFem-org/Sharkey/-/merge_requests/737) | ||||
|  |  | |||
|  | @ -58,9 +58,9 @@ export class ChartManagementService implements OnApplicationShutdown { | |||
| 	@bindThis | ||||
| 	public async start() { | ||||
| 		// 20分おきにメモリ情報をDBに書き込み
 | ||||
| 		this.saveIntervalId = setInterval(() => { | ||||
| 		this.saveIntervalId = setInterval(async () => { | ||||
| 			for (const chart of this.charts) { | ||||
| 				chart.save(); | ||||
| 				await chart.save(); | ||||
| 			} | ||||
| 		}, 1000 * 60 * 20); | ||||
| 	} | ||||
|  | @ -69,9 +69,9 @@ export class ChartManagementService implements OnApplicationShutdown { | |||
| 	public async dispose(): Promise<void> { | ||||
| 		clearInterval(this.saveIntervalId); | ||||
| 		if (process.env.NODE_ENV !== 'test') { | ||||
| 			await Promise.all( | ||||
| 				this.charts.map(chart => chart.save()), | ||||
| 			); | ||||
| 			for (const chart of this.charts) { | ||||
| 				await chart.save(); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
|  |  | |||
|  | @ -48,20 +48,19 @@ export class CleanChartsProcessorService { | |||
| 	public async process(): Promise<void> { | ||||
| 		this.logger.info('Clean charts...'); | ||||
| 
 | ||||
| 		await Promise.all([ | ||||
| 			this.federationChart.clean(), | ||||
| 			this.notesChart.clean(), | ||||
| 			this.usersChart.clean(), | ||||
| 			this.activeUsersChart.clean(), | ||||
| 			this.instanceChart.clean(), | ||||
| 			this.perUserNotesChart.clean(), | ||||
| 			this.perUserPvChart.clean(), | ||||
| 			this.driveChart.clean(), | ||||
| 			this.perUserReactionsChart.clean(), | ||||
| 			this.perUserFollowingChart.clean(), | ||||
| 			this.perUserDriveChart.clean(), | ||||
| 			this.apRequestChart.clean(), | ||||
| 		]); | ||||
| 		// DBへの同時接続を避けるためにPromise.allを使わずひとつずつ実行する
 | ||||
| 		await this.federationChart.clean(); | ||||
| 		await this.notesChart.clean(); | ||||
| 		await this.usersChart.clean(); | ||||
| 		await this.activeUsersChart.clean(); | ||||
| 		await this.instanceChart.clean(); | ||||
| 		await this.perUserNotesChart.clean(); | ||||
| 		await this.perUserPvChart.clean(); | ||||
| 		await this.driveChart.clean(); | ||||
| 		await this.perUserReactionsChart.clean(); | ||||
| 		await this.perUserFollowingChart.clean(); | ||||
| 		await this.perUserDriveChart.clean(); | ||||
| 		await this.apRequestChart.clean(); | ||||
| 
 | ||||
| 		this.logger.succ('All charts successfully cleaned.'); | ||||
| 	} | ||||
|  |  | |||
|  | @ -29,13 +29,12 @@ export class ResyncChartsProcessorService { | |||
| 	public async process(): Promise<void> { | ||||
| 		this.logger.info('Resync charts...'); | ||||
| 
 | ||||
| 		// DBへの同時接続を避けるためにPromise.allを使わずひとつずつ実行する
 | ||||
| 		// TODO: ユーザーごとのチャートも更新する
 | ||||
| 		// TODO: インスタンスごとのチャートも更新する
 | ||||
| 		await Promise.all([ | ||||
| 			this.driveChart.resync(), | ||||
| 			this.notesChart.resync(), | ||||
| 			this.usersChart.resync(), | ||||
| 		]); | ||||
| 		await this.driveChart.resync(); | ||||
| 		await this.notesChart.resync(); | ||||
| 		await this.usersChart.resync(); | ||||
| 
 | ||||
| 		this.logger.succ('All charts successfully resynced.'); | ||||
| 	} | ||||
|  |  | |||
|  | @ -48,20 +48,19 @@ export class TickChartsProcessorService { | |||
| 	public async process(): Promise<void> { | ||||
| 		this.logger.info('Tick charts...'); | ||||
| 
 | ||||
| 		await Promise.all([ | ||||
| 			this.federationChart.tick(false), | ||||
| 			this.notesChart.tick(false), | ||||
| 			this.usersChart.tick(false), | ||||
| 			this.activeUsersChart.tick(false), | ||||
| 			this.instanceChart.tick(false), | ||||
| 			this.perUserNotesChart.tick(false), | ||||
| 			this.perUserPvChart.tick(false), | ||||
| 			this.driveChart.tick(false), | ||||
| 			this.perUserReactionsChart.tick(false), | ||||
| 			this.perUserFollowingChart.tick(false), | ||||
| 			this.perUserDriveChart.tick(false), | ||||
| 			this.apRequestChart.tick(false), | ||||
| 		]); | ||||
| 		// DBへの同時接続を避けるためにPromise.allを使わずひとつずつ実行する
 | ||||
| 		await this.federationChart.tick(false); | ||||
| 		await this.notesChart.tick(false); | ||||
| 		await this.usersChart.tick(false); | ||||
| 		await this.activeUsersChart.tick(false); | ||||
| 		await this.instanceChart.tick(false); | ||||
| 		await this.perUserNotesChart.tick(false); | ||||
| 		await this.perUserPvChart.tick(false); | ||||
| 		await this.driveChart.tick(false); | ||||
| 		await this.perUserReactionsChart.tick(false); | ||||
| 		await this.perUserFollowingChart.tick(false); | ||||
| 		await this.perUserDriveChart.tick(false); | ||||
| 		await this.apRequestChart.tick(false); | ||||
| 
 | ||||
| 		this.logger.succ('All charts successfully ticked.'); | ||||
| 	} | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue