feat: improve settings

This commit is contained in:
Ricardo Arturo Cabral Mejia 2022-09-20 05:07:27 +00:00
parent 17227107cb
commit 687a896d9e
No known key found for this signature in database
GPG Key ID: 5931EBF43A650245
3 changed files with 68 additions and 27 deletions

@ -10,10 +10,11 @@ interface Info {
}
interface EventIdLimits {
minimumZeroBits?: number
minLeadingZeroBits?: number
}
interface PubkeyLimits {
minLeadingZeroBits: number
whitelist?: Pubkey[]
blacklist?: Pubkey[]
}
@ -27,11 +28,11 @@ interface CreatedAtLimits {
/**
* Maximum number of seconds allowed before the current unix timestamp
*/
maximumNegativeDelta?: number
maxNegativeDelta?: number
/**
* Maximum number of seconds allowed after the current unix timestamp
*/
maximumPositiveDelta?: number
maxPositiveDelta?: number
}
interface EventLimits {
@ -42,8 +43,8 @@ interface EventLimits {
}
interface ClientSubscriptionLimits {
maximumCount?: number
maximumFilters?: number
maxSubscriptions?: number
maxFilters?: number
}
interface ClientLimits {

@ -6,6 +6,7 @@ import { WebSocketServer } from 'ws'
import { EventRepository } from './repositories/event-repository'
import { getDbClient } from './database/client'
import { saveSettingsOnExit } from './utils/settings'
import { webSocketAdapterFactory } from './factories/websocket-adapter-factory'
import { WebSocketServerAdapter } from './adapters/web-socket-server-adapter'
@ -24,7 +25,7 @@ if (cluster.isPrimary) {
cluster.on('exit', (deadWorker, code, signal) => {
console.log(`worker ${deadWorker.process.pid} - exiting`)
if (signal === 'SIGINT') {
if (code === 0 || signal === 'SIGINT') {
return
}
const worker = newWorker()
@ -36,9 +37,16 @@ if (cluster.isPrimary) {
console.log('worker ' + newPID + ' born.')
})
process.on('exit', () => {
const exitHandler = () => {
console.log('Primary exiting')
})
saveSettingsOnExit()
process.exit(0)
}
process.on('SIGINT', exitHandler)
process.on('uncaughtException', exitHandler)
} else if (cluster.isWorker) {
const port = Number(process.env.SERVER_PORT) || 8008
@ -55,7 +63,7 @@ if (cluster.isPrimary) {
adapter.listen(port)
process.on('SIGINT', () => {
const exitHandler = () => {
wss.close(() => {
server.close(() => {
dbClient.destroy(() => {
@ -63,7 +71,10 @@ if (cluster.isPrimary) {
})
})
})
})
}
process.on('SIGINT', exitHandler)
process.on('uncaughtException', exitHandler)
console.log(`worker ${process.pid} - listening on port ${port}`)
}

@ -1,11 +1,17 @@
import { copyFileSync, readFileSync, unlinkSync, writeFileSync } from 'fs'
import cluster from 'cluster'
import { homedir } from 'os'
import { join } from 'path'
import { mergeDeepRight } from 'ramda'
import { readFileSync } from 'fs'
import { ISettings } from '../@types/settings'
import packageJson from '../../package.json'
const getSettingsFilePath = (filename = 'settings.json') => join(
process.env.NOSTR_CONFIG_DIR ?? join(homedir(), '.nostr'),
filename,
)
let _settings: ISettings
const getDefaultSettings = (): ISettings => ({
@ -19,54 +25,77 @@ const getDefaultSettings = (): ISettings => ({
limits: {
event: {
eventId: {
minimumZeroBits: 0,
minLeadingZeroBits: 0,
},
kind: {
whitelist: [],
blacklist: [],
},
pubkey: {
minLeadingZeroBits: 0,
whitelist: [],
blacklist: [],
},
},
client: {
subscription: {
maximumCount: 10,
maximumFilters: 5,
maxSubscriptions: 10,
maxFilters: 10,
},
},
},
})
const createSettingsFromFile = (defaults: ISettings) => {
const contents = JSON.parse(
const loadSettings = (path: string) => {
console.log('loading settings', path)
return JSON.parse(
readFileSync(
join(
process.env.NOSTR_CONFIG_DIR ?? join(homedir(), '.nostr'),
'settings.json',
),
path,
{ encoding: 'utf8' },
),
)
return mergeDeepRight(defaults, contents)
}
const createSettings = (): ISettings => {
const path = getSettingsFilePath()
const defaults = getDefaultSettings()
try {
if (_settings) {
return _settings
}
_settings = createSettingsFromFile(getDefaultSettings())
_settings = mergeDeepRight(defaults, loadSettings(path))
return _settings
} catch (err) {
console.error('Unable to read config file. Reason: %s', err.message)
} catch (error) {
console.error('Unable to read config file. Reason: %s', error.message)
return getDefaultSettings()
return defaults
}
}
export const saveSettings = (path: string, settings: ISettings) => {
console.log('saving settings')
return writeFileSync(
path,
JSON.stringify(settings, null, 2),
{ encoding: 'utf-8' }
)
}
export const Settings = createSettings()
export const saveSettingsOnExit = () => {
if (cluster.isWorker) {
return
}
const path = getSettingsFilePath()
const backupPath = getSettingsFilePath(`settings-${Date.now()}.json`)
try {
copyFileSync(path, backupPath)
saveSettings(path, Settings)
unlinkSync(backupPath)
} catch (error) {
console.error('Unable to write config file. Reason: %s', error.message)
}
}