wip
This commit is contained in:
		
							parent
							
								
									e70fb71a04
								
							
						
					
					
						commit
						dc3c80e3ce
					
				
					 8 changed files with 140 additions and 7 deletions
				
			
		
							
								
								
									
										60
									
								
								src/daemons/hashtags-stats-child.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								src/daemons/hashtags-stats-child.ts
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,60 @@
 | 
				
			||||||
 | 
					import Note from '../models/note';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 10分
 | 
				
			||||||
 | 
					const interval = 1000 * 60 * 10;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					async function tick() {
 | 
				
			||||||
 | 
						const res = await Note.aggregate([{
 | 
				
			||||||
 | 
							$match: {
 | 
				
			||||||
 | 
								createdAt: {
 | 
				
			||||||
 | 
									$gt: new Date(Date.now() - interval)
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								tags: {
 | 
				
			||||||
 | 
									$exists: true,
 | 
				
			||||||
 | 
									$ne: []
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}, {
 | 
				
			||||||
 | 
							$unwind: '$tags'
 | 
				
			||||||
 | 
						}, {
 | 
				
			||||||
 | 
							$group: {
 | 
				
			||||||
 | 
								_id: '$tags',
 | 
				
			||||||
 | 
								count: {
 | 
				
			||||||
 | 
									$sum: 1
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}, {
 | 
				
			||||||
 | 
							$group: {
 | 
				
			||||||
 | 
								_id: null,
 | 
				
			||||||
 | 
								tags: {
 | 
				
			||||||
 | 
									$push: {
 | 
				
			||||||
 | 
										tag: '$_id',
 | 
				
			||||||
 | 
										count: '$count'
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}, {
 | 
				
			||||||
 | 
							$project: {
 | 
				
			||||||
 | 
								_id: false,
 | 
				
			||||||
 | 
								tags: true
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}]) as {
 | 
				
			||||||
 | 
							tags: Array<{
 | 
				
			||||||
 | 
								tag: string;
 | 
				
			||||||
 | 
								count: number;
 | 
				
			||||||
 | 
							}>
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						const stats = res.tags
 | 
				
			||||||
 | 
							.sort((a, b) => a.count - b.count)
 | 
				
			||||||
 | 
							.map(tag => [tag.tag, tag.count])
 | 
				
			||||||
 | 
							.slice(0, 10);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						console.log(stats);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						process.send(stats);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					tick();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					setInterval(tick, interval);
 | 
				
			||||||
							
								
								
									
										20
									
								
								src/daemons/hashtags-stats.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								src/daemons/hashtags-stats.ts
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,20 @@
 | 
				
			||||||
 | 
					import * as childProcess from 'child_process';
 | 
				
			||||||
 | 
					import Xev from 'xev';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const ev = new Xev();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default function() {
 | 
				
			||||||
 | 
						const log = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						const p = childProcess.fork(__dirname + '/hashtags-stats-child.js');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						p.on('message', stats => {
 | 
				
			||||||
 | 
							ev.emit('hashtagsStats', stats);
 | 
				
			||||||
 | 
							log.push(stats);
 | 
				
			||||||
 | 
							if (log.length > 30) log.shift();
 | 
				
			||||||
 | 
						});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ev.on('requestHashTagsStatsLog', id => {
 | 
				
			||||||
 | 
							ev.emit('hashtagsStatsLog:' + id, log);
 | 
				
			||||||
 | 
						});
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -1,8 +1,8 @@
 | 
				
			||||||
import Note from './models/note';
 | 
					import Note from '../models/note';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const interval = 5000;
 | 
					const interval = 5000;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
setInterval(async () => {
 | 
					async function tick() {
 | 
				
			||||||
	const [all, local] = await Promise.all([Note.count({
 | 
						const [all, local] = await Promise.all([Note.count({
 | 
				
			||||||
		createdAt: {
 | 
							createdAt: {
 | 
				
			||||||
			$gte: new Date(Date.now() - interval)
 | 
								$gte: new Date(Date.now() - interval)
 | 
				
			||||||
| 
						 | 
					@ -19,4 +19,8 @@ setInterval(async () => {
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	process.send(stats);
 | 
						process.send(stats);
 | 
				
			||||||
}, interval);
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					tick();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					setInterval(tick, interval);
 | 
				
			||||||
| 
						 | 
					@ -5,6 +5,8 @@ import Xev from 'xev';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const ev = new Xev();
 | 
					const ev = new Xev();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const interval = 1000;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Report server stats regularly
 | 
					 * Report server stats regularly
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
| 
						 | 
					@ -15,7 +17,7 @@ export default function() {
 | 
				
			||||||
		ev.emit('serverStatsLog:' + id, log);
 | 
							ev.emit('serverStatsLog:' + id, log);
 | 
				
			||||||
	});
 | 
						});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	setInterval(() => {
 | 
						async function tick() {
 | 
				
			||||||
		osUtils.cpuUsage(cpuUsage => {
 | 
							osUtils.cpuUsage(cpuUsage => {
 | 
				
			||||||
			const disk = diskusage.checkSync(os.platform() == 'win32' ? 'c:' : '/');
 | 
								const disk = diskusage.checkSync(os.platform() == 'win32' ? 'c:' : '/');
 | 
				
			||||||
			const stats = {
 | 
								const stats = {
 | 
				
			||||||
| 
						 | 
					@ -32,5 +34,9 @@ export default function() {
 | 
				
			||||||
			log.push(stats);
 | 
								log.push(stats);
 | 
				
			||||||
			if (log.length > 50) log.shift();
 | 
								if (log.length > 50) log.shift();
 | 
				
			||||||
		});
 | 
							});
 | 
				
			||||||
	}, 1000);
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tick();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						setInterval(tick, interval);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -17,8 +17,9 @@ import ProgressBar from './utils/cli/progressbar';
 | 
				
			||||||
import EnvironmentInfo from './utils/environmentInfo';
 | 
					import EnvironmentInfo from './utils/environmentInfo';
 | 
				
			||||||
import MachineInfo from './utils/machineInfo';
 | 
					import MachineInfo from './utils/machineInfo';
 | 
				
			||||||
import DependencyInfo from './utils/dependencyInfo';
 | 
					import DependencyInfo from './utils/dependencyInfo';
 | 
				
			||||||
import serverStats from './server-stats';
 | 
					import serverStats from './daemons/server-stats';
 | 
				
			||||||
import notesStats from './notes-stats';
 | 
					import notesStats from './daemons/notes-stats';
 | 
				
			||||||
 | 
					import hashtagsStats from './daemons/hashtags-stats';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import loadConfig from './config/load';
 | 
					import loadConfig from './config/load';
 | 
				
			||||||
import { Config } from './config/types';
 | 
					import { Config } from './config/types';
 | 
				
			||||||
| 
						 | 
					@ -52,6 +53,7 @@ function main() {
 | 
				
			||||||
		ev.mount();
 | 
							ev.mount();
 | 
				
			||||||
		serverStats();
 | 
							serverStats();
 | 
				
			||||||
		notesStats();
 | 
							notesStats();
 | 
				
			||||||
 | 
							hashtagsStats();
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		workerMain(opt);
 | 
							workerMain(opt);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										35
									
								
								src/server/api/stream/hashtags-stats.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								src/server/api/stream/hashtags-stats.ts
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,35 @@
 | 
				
			||||||
 | 
					import * as websocket from 'websocket';
 | 
				
			||||||
 | 
					import Xev from 'xev';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const ev = new Xev();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default function(request: websocket.request, connection: websocket.connection): void {
 | 
				
			||||||
 | 
						const onStats = stats => {
 | 
				
			||||||
 | 
							connection.send(JSON.stringify({
 | 
				
			||||||
 | 
								type: 'stats',
 | 
				
			||||||
 | 
								body: stats
 | 
				
			||||||
 | 
							}));
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						connection.on('message', async data => {
 | 
				
			||||||
 | 
							const msg = JSON.parse(data.utf8Data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							switch (msg.type) {
 | 
				
			||||||
 | 
								case 'requestLog':
 | 
				
			||||||
 | 
									ev.once('hashtagsStatsLog:' + msg.id, statsLog => {
 | 
				
			||||||
 | 
										connection.send(JSON.stringify({
 | 
				
			||||||
 | 
											type: 'statsLog',
 | 
				
			||||||
 | 
											body: statsLog
 | 
				
			||||||
 | 
										}));
 | 
				
			||||||
 | 
									});
 | 
				
			||||||
 | 
									ev.emit('requestHashtagsStatsLog', msg.id);
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ev.addListener('hashtagsStats', onStats);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						connection.on('close', () => {
 | 
				
			||||||
 | 
							ev.removeListener('hashtagsStats', onStats);
 | 
				
			||||||
 | 
						});
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -14,6 +14,7 @@ import othelloGameStream from './stream/othello-game';
 | 
				
			||||||
import othelloStream from './stream/othello';
 | 
					import othelloStream from './stream/othello';
 | 
				
			||||||
import serverStatsStream from './stream/server-stats';
 | 
					import serverStatsStream from './stream/server-stats';
 | 
				
			||||||
import notesStatsStream from './stream/notes-stats';
 | 
					import notesStatsStream from './stream/notes-stats';
 | 
				
			||||||
 | 
					import hashtagsStatsStream from './stream/hashtags-stats';
 | 
				
			||||||
import requestsStream from './stream/requests';
 | 
					import requestsStream from './stream/requests';
 | 
				
			||||||
import { ParsedUrlQuery } from 'querystring';
 | 
					import { ParsedUrlQuery } from 'querystring';
 | 
				
			||||||
import authenticate from './authenticate';
 | 
					import authenticate from './authenticate';
 | 
				
			||||||
| 
						 | 
					@ -39,6 +40,11 @@ module.exports = (server: http.Server) => {
 | 
				
			||||||
			return;
 | 
								return;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (request.resourceURL.pathname === '/hashtags-stats') {
 | 
				
			||||||
 | 
								hashtagsStatsStream(request, connection);
 | 
				
			||||||
 | 
								return;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (request.resourceURL.pathname === '/requests') {
 | 
							if (request.resourceURL.pathname === '/requests') {
 | 
				
			||||||
			requestsStream(request, connection);
 | 
								requestsStream(request, connection);
 | 
				
			||||||
			return;
 | 
								return;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue