2020-03-29 05:43:40 -04:00
/* eslint-disable no-continue */
2020-03-23 22:26:06 -04:00
/* eslint-disable no-await-in-loop */
import { Client } from '..' ;
import { RichEmbed } from '../class' ;
2020-05-03 20:00:52 -04:00
import { Tiers } from '../models' ;
2020-03-23 22:26:06 -04:00
const channelID = '691824484230889546' ;
2020-03-28 12:10:58 -04:00
export default function memory ( client : Client ) {
2020-05-03 16:35:47 -04:00
const set = new Set < string > ( ) ;
2020-03-28 12:10:58 -04:00
setInterval ( async ( ) = > {
2020-03-29 05:33:43 -04:00
try {
const accounts = await client . db . Account . find ( ) ;
for ( const acc of accounts ) {
2020-03-29 05:43:40 -04:00
if ( acc . root === true ) continue ;
2020-03-29 05:33:43 -04:00
// memory in bytes
const mem = Number ( await client . util . exec ( ` memory ${ acc . username } ` ) ) * 1000 ;
// memory in megabytes
const memoryConversion = mem / 1024 / 1024 ;
2020-03-29 05:53:15 -04:00
const userLimits : { soft? : number , hard? : number } = { } ;
2020-05-03 21:00:16 -04:00
// @ts-ignore
2020-05-03 20:00:52 -04:00
const tier : Tiers = await client . db . Tier . findOne ( { id : acc.tier } ) . lean ( ) . exec ( ) ;
2020-05-03 18:23:28 -04:00
userLimits . soft = acc . ramLimitNotification ;
2020-05-03 18:59:49 -04:00
userLimits . hard = tier . resourceLimits . ram ;
2020-05-03 19:05:41 -04:00
if ( ( memoryConversion <= userLimits . soft ) && ( acc . ramLimitNotification !== 0 ) ) {
2020-05-03 17:49:50 -04:00
set . delete ( acc . username ) ;
}
2020-03-29 05:33:43 -04:00
/ * i f t h e u s e r h a s e x c e e d e d t h e i r s o f t m e m o r y l i m i t , w h i c h i s t h e o n e d e s c r i b e d i n t h e
resource limit guidelines , we ' ll inform staff .
* /
2020-05-03 16:44:42 -04:00
if ( ( memoryConversion >= userLimits . hard ) && set . has ( acc . username ) ) {
2020-05-03 16:35:47 -04:00
client . signale . info ( ` RAM Hard Limit Reached | ${ acc . username } | ${ memoryConversion } / ${ userLimits . hard } MB ` ) ;
client . util . exec ( ` killall -9 -u ${ acc . username } ` ) ;
const embed = new RichEmbed ( ) ;
embed . setTitle ( 'Resource Enforcement Notification' ) ;
embed . setDescription ( 'Someone has reached the (hard) resource limit for their tier on RAM. The system has automatically killed all of their processes.' ) ;
embed . addField ( 'User' , ` ${ acc . username } | <@ ${ acc . userID } > | ${ acc . userID } ` , true ) ;
embed . addField ( 'Tier' , String ( acc . tier ) , true ) ;
embed . addField ( 'Memory Usage' , ` ${ String ( memoryConversion ) } MB ` , true ) ;
embed . addField ( 'Memory Limit' , ` ${ String ( userLimits . hard ) } MB ` , true ) ;
client . createMessage ( channelID , { embed } ) ;
2020-05-05 19:50:14 -04:00
client . util . createModerationLog ( acc . userID , client . guilds . get ( '446067825673633794' ) . members . get ( client . user . id ) , 1 , ` You have exceeded your resource limit of ' ${ String ( userLimits . hard ) } MB'. Any process running on your user account has been sent a STOP/KILL signal. If you have any questions, please contact a Technician. ` ) ;
2020-05-03 16:35:47 -04:00
client . util . transport . sendMail ( {
to : acc.emailAddress ,
from : 'Library of Code sp-us | Cloud Services <help@libraryofcode.org>' ,
subject : 'Your account has been warned' ,
html : `
< h1 > Library of Code sp - us | Cloud Services < / h1 >
< p > Your account has received an official warning from a Technician . Please get the underlying issue resolved to avoid < i > possible < / i > moderative action . < / p >
2020-05-05 19:50:14 -04:00
< p > < strong > Reason : < / strong > You have exceeded your resource limit of '${String(userLimits.hard)} MB' . Any process running on your user account has been sent a STOP / KILL signal . If you have any questions , please contact a Technician . < / p >
< p > < strong > Moderator : < / strong > SYSTEM < / p >
2020-05-03 16:35:47 -04:00
< b > < i > Library of Code sp - us | Support Team < / i > < / b >
` ,
} ) ;
client . createMessage ( channelID , { embed } ) ;
set . delete ( acc . username ) ;
2020-05-03 16:44:42 -04:00
} else if ( ( memoryConversion >= userLimits . soft ) && ! set . has ( acc . username ) ) {
2020-03-29 05:33:43 -04:00
client . signale . info ( ` RAM Soft Limit Reached | ${ acc . username } | ${ memoryConversion } / ${ userLimits . soft } MB ` ) ;
const embed = new RichEmbed ( ) ;
if ( client . users . get ( acc . userID ) ) embed . setThumbnail ( client . users . get ( acc . userID ) . avatarURL ) ;
2020-05-03 16:35:47 -04:00
embed . setTitle ( 'Resource Limit Notification' ) ;
embed . setDescription ( 'Someone has reached the (soft) resource limit for their tier on RAM.' ) ;
2020-03-29 05:33:43 -04:00
embed . addField ( 'User' , ` ${ acc . username } | <@ ${ acc . userID } > | ${ acc . userID } ` , true ) ;
embed . addField ( 'Tier' , String ( acc . tier ) , true ) ;
embed . addField ( 'Memory Usage' , ` ${ String ( memoryConversion ) } MB ` , true ) ;
2020-05-03 16:35:47 -04:00
embed . addField ( 'Memory Limit' , ` ${ String ( userLimits . hard ) } MB ` , true ) ;
2020-03-29 05:33:43 -04:00
embed . setFooter ( client . user . username , client . user . avatarURL ) ;
embed . setTimestamp ( ) ;
2020-05-03 19:11:23 -04:00
if ( acc . ramLimitNotification !== 0 ) {
await client . createMessage ( channelID , { embed } ) ;
}
2020-05-03 18:59:49 -04:00
if ( ( memoryConversion >= acc . ramLimitNotification ) && ( acc . ramLimitNotification !== 0 ) ) {
2020-05-03 17:49:50 -04:00
const notifyEmbed = new RichEmbed ( )
. setTitle ( 'Cloud Account | Notification' )
2020-05-05 19:41:00 -04:00
. setDescription ( ` You are about to reach your RAM resource limits, you are currently using ' ${ String ( Math . round ( memoryConversion ) ) } MB' and your limit is ' ${ String ( userLimits . hard ) } MB'. Please correct your usage to avoid further action. \ nYou can set your notification preferences by running \` =limits set-ram-notification <preferred ram threshold in MB> \` , you can disable these notifications by running \` =limits set-ram-notification -1 \` . ` )
2020-05-03 17:49:50 -04:00
. addField ( 'User' , ` ${ acc . username } | <@ ${ acc . userID } > ` , true )
. addField ( 'Technician' , 'SYSTEM' , true )
. setFooter ( client . user . username , client . user . avatarURL )
. setTimestamp ( ) ;
client . getDMChannel ( acc . userID ) . then ( ( channel ) = > {
channel . createMessage ( { embed : notifyEmbed } ) ;
} ) ;
client . util . transport . sendMail ( {
to : acc.emailAddress ,
from : 'Library of Code sp-us | Cloud Services <help@libraryofcode.org>' ,
2020-05-05 19:50:14 -04:00
subject : 'Account Notification' ,
2020-05-03 17:49:50 -04:00
html : `
2020-05-03 16:35:47 -04:00
< h1 > Library of Code sp - us | Cloud Services < / h1 >
< p > You are about to reach your RAM resource limits , you are currently using '${String(memoryConversion)} MB' and your limit is '${String(userLimits.hard)} MB' . Please correct your usage to avoid further action . < / p >
< p > < strong > Technician : < / strong > SYSTEM < / p >
< b > < i > Library of Code sp - us | Support Team < / i > < / b >
` ,
2020-05-03 17:49:50 -04:00
} ) ;
2020-05-03 18:31:31 -04:00
client . createMessage ( '580950455581147146' , { embed : notifyEmbed } ) ;
2020-05-03 17:49:50 -04:00
}
2020-05-03 16:35:47 -04:00
set . add ( acc . username ) ;
2020-03-28 12:10:58 -04:00
}
2020-03-23 22:26:06 -04:00
}
2020-03-29 05:33:43 -04:00
} catch ( err ) {
client . util . handleError ( err ) ;
2020-03-23 22:26:06 -04:00
}
2020-03-29 05:53:15 -04:00
} , 60000 ) ;
2020-03-23 22:26:06 -04:00
}