feat(server): seperate server part and ability to run server without electron
This commit is contained in:
180
src/background/sphinx.js
Normal file
180
src/background/sphinx.js
Normal file
@ -0,0 +1,180 @@
|
||||
const path = require("path");
|
||||
let env
|
||||
try{
|
||||
env = require("env");
|
||||
} catch(e){}
|
||||
const appPath = require('./electronAppPath')
|
||||
const fs = require('fs')
|
||||
const iconv = require('iconv-lite')
|
||||
const { spawn, exec } = require('child_process')
|
||||
const appConfig = require('./config')
|
||||
|
||||
const writeSphinxConfig = (path, dbPath) => {
|
||||
let config = `
|
||||
index torrents
|
||||
{
|
||||
type = rt
|
||||
path = ${dbPath}/database/torrents
|
||||
|
||||
rt_attr_string = hash
|
||||
rt_attr_string = name
|
||||
rt_field = nameIndex
|
||||
rt_attr_bigint = size
|
||||
rt_attr_uint = files
|
||||
rt_attr_uint = piecelength
|
||||
rt_attr_timestamp = added
|
||||
rt_attr_string = ipv4
|
||||
rt_attr_uint = port
|
||||
rt_attr_string = contentType
|
||||
rt_attr_string = contentCategory
|
||||
rt_attr_uint = seeders
|
||||
rt_attr_uint = leechers
|
||||
rt_attr_uint = completed
|
||||
rt_attr_timestamp = trackersChecked
|
||||
rt_attr_uint = good
|
||||
rt_attr_uint = bad
|
||||
}
|
||||
|
||||
index files
|
||||
{
|
||||
type = rt
|
||||
path = ${dbPath}/database/files
|
||||
|
||||
rt_attr_string = path
|
||||
rt_field = pathIndex
|
||||
rt_attr_string = hash
|
||||
rt_attr_bigint = size
|
||||
}
|
||||
|
||||
index version
|
||||
{
|
||||
type = rt
|
||||
path = ${dbPath}/database/version
|
||||
|
||||
rt_attr_uint = version
|
||||
rt_field = versionIndex
|
||||
}
|
||||
|
||||
searchd
|
||||
{
|
||||
listen = 9312
|
||||
listen = 9306:mysql41
|
||||
read_timeout = 5
|
||||
max_children = 30
|
||||
seamless_rotate = 1
|
||||
preopen_indexes = 1
|
||||
unlink_old = 1
|
||||
workers = threads # for RT to work
|
||||
pid_file = ${path}/searchd.pid
|
||||
log = ${path}/searchd.log
|
||||
query_log = ${path}/query.log
|
||||
binlog_path = ${path}
|
||||
}
|
||||
`;
|
||||
|
||||
// clear dir in test env
|
||||
if(env && env.name === 'test')
|
||||
{
|
||||
if (fs.existsSync(`${dbPath}/database`)) {
|
||||
fs.readdirSync(`${dbPath}/database`).forEach(function(file, index){
|
||||
const curPath = `${dbPath}/database` + "/" + file;
|
||||
if (!fs.lstatSync(curPath).isDirectory()) {
|
||||
fs.unlinkSync(curPath);
|
||||
}
|
||||
});
|
||||
|
||||
fs.readdirSync(path).forEach(function(file, index){
|
||||
if(!file.startsWith('binlog'))
|
||||
return;
|
||||
const curPath = path + "/" + file;
|
||||
if (!fs.lstatSync(curPath).isDirectory()) {
|
||||
fs.unlinkSync(curPath);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
let isInitDb = false
|
||||
|
||||
if (!fs.existsSync(`${dbPath}/database`)){
|
||||
fs.mkdirSync(`${dbPath}/database`);
|
||||
isInitDb = true
|
||||
}
|
||||
|
||||
if(/^win/.test(process.platform))
|
||||
config = iconv.encode(config, 'win1251')
|
||||
|
||||
fs.writeFileSync(`${path}/sphinx.conf`, config)
|
||||
console.log(`writed sphinx config to ${path}`)
|
||||
console.log('db path:', dbPath)
|
||||
|
||||
return {isInitDb}
|
||||
}
|
||||
|
||||
module.exports = (callback, dataDirectory, onClose) => {
|
||||
const sphinxPath = path.resolve(appPath('searchd'))
|
||||
console.log('Sphinx Path:', sphinxPath)
|
||||
|
||||
const sphinxConfigDirectory = dataDirectory
|
||||
appConfig['dbPath'] = appConfig.dbPath && appConfig.dbPath.length > 0 ? appConfig.dbPath : sphinxConfigDirectory;
|
||||
// on portable dir can move database directory
|
||||
if(!fs.existsSync(appConfig.dbPath) && fs.existsSync(sphinxConfigDirectory))
|
||||
{
|
||||
appConfig['dbPath'] = sphinxConfigDirectory
|
||||
}
|
||||
|
||||
const { isInitDb } = writeSphinxConfig(sphinxConfigDirectory, appConfig.dbPath)
|
||||
|
||||
const config = `${sphinxConfigDirectory}/sphinx.conf`
|
||||
const options = ['--config', config]
|
||||
if(!(/^win/.test(process.platform)))
|
||||
{
|
||||
options.push('--nodetach')
|
||||
}
|
||||
const sphinx = spawn(sphinxPath, options)
|
||||
// remeber initizalizing of db
|
||||
sphinx.isInitDb = isInitDb
|
||||
sphinx.directoryPath = appConfig.dbPath
|
||||
sphinx.directoryPathDb = appConfig.dbPath + '/database'
|
||||
|
||||
const optimizeResolvers = {}
|
||||
|
||||
sphinx.stdout.on('data', (data) => {
|
||||
console.log(`sphinx: ${data}`)
|
||||
if (data.includes('accepting connections')) {
|
||||
console.log('catched sphinx start')
|
||||
if(callback)
|
||||
callback()
|
||||
}
|
||||
|
||||
const checkOptimized = String(data).match(/index ([\w]+): optimized/)
|
||||
if(checkOptimized)
|
||||
{
|
||||
if(optimizeResolvers[checkOptimized[1]])
|
||||
{
|
||||
console.log('resolve optimizer', checkOptimized[1])
|
||||
optimizeResolvers[checkOptimized[1]]()
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
sphinx.on('close', (code, signal) => {
|
||||
console.log(`sphinx closed with code ${code} and signal ${signal}`)
|
||||
if(onClose)
|
||||
onClose()
|
||||
})
|
||||
|
||||
sphinx.stop = () => {
|
||||
console.log('sphinx closing...')
|
||||
exec(`"${sphinxPath}" --config "${config}" --stopwait`)
|
||||
}
|
||||
|
||||
sphinx.waitOptimized = (table) => new Promise((resolve) => {
|
||||
optimizeResolvers[table] = () => {
|
||||
delete optimizeResolvers[table];
|
||||
resolve()
|
||||
}
|
||||
})
|
||||
|
||||
return sphinx
|
||||
}
|
||||
Reference in New Issue
Block a user