mirror of
https://github.com/unraid/api.git
synced 2026-02-19 22:48:31 -06:00
refactor: cleanedup core importing and added better worker crashing
This commit is contained in:
@@ -4,17 +4,15 @@
|
||||
*/
|
||||
|
||||
import get from 'lodash.get';
|
||||
// @ts-ignore
|
||||
// import * as core from '../../../core/src/index';
|
||||
import { v4 as uuid } from 'uuid';
|
||||
import core from '@unraid/core';
|
||||
import * as core from '@unraid/core';
|
||||
import { apiManager, errors, log, states, config, pluginManager, modules } from '@unraid/core';
|
||||
import { makeExecutableSchema, SchemaDirectiveVisitor } from 'graphql-tools'
|
||||
import { mergeTypes } from 'merge-graphql-schemas';
|
||||
import gql from 'graphql-tag';
|
||||
import { typeDefs, resolvers } from './schema';
|
||||
import { wsHasConnected, wsHasDisconnected } from '../ws';
|
||||
|
||||
const { apiManager, errors, log, states, config, pluginManager } = core;
|
||||
const { AppError, FatalAppError, PluginError } = errors;
|
||||
const { usersState } = states;
|
||||
|
||||
@@ -137,11 +135,11 @@ const types = mergeTypes([
|
||||
]);
|
||||
|
||||
const getCoreModule = (moduleName) => {
|
||||
if (!Object.keys(core.modules).includes(moduleName)) {
|
||||
if (!Object.keys(modules).includes(moduleName)) {
|
||||
throw new FatalAppError(`"${moduleName}" is not a valid core module.`);
|
||||
}
|
||||
|
||||
return core.modules[moduleName];
|
||||
return modules[moduleName];
|
||||
};
|
||||
|
||||
const getPluginModule = (pluginName, pluginModuleName) => {
|
||||
@@ -3,9 +3,7 @@
|
||||
* Written by: Alexis Tyler
|
||||
*/
|
||||
|
||||
import core from '@unraid/core';
|
||||
// @ts-ignore
|
||||
// import * as core from '../../../../core/src/index';
|
||||
import { pluginManager, pubsub, utils, bus, errors, states, modules } from '@unraid/core';
|
||||
import dee from '@gridplus/docker-events';
|
||||
import { setIntervalAsync } from 'set-interval-async/dynamic';
|
||||
import GraphQLJSON from 'graphql-type-json';
|
||||
@@ -15,7 +13,6 @@ import { run, publish } from '../../run';
|
||||
import { cache } from '../../cache';
|
||||
import { hasSubscribedToChannel, canPublishToChannel } from '../../ws';
|
||||
|
||||
const { pluginManager, pubsub, utils, log, bus, errors, states } = core;
|
||||
const { ensurePermission } = utils;
|
||||
const { usersState } = states;
|
||||
const { AppError, PluginError } = errors;
|
||||
@@ -26,7 +23,7 @@ bus.on('slots', async () => {
|
||||
const user = usersState.findOne({ name: 'root' });
|
||||
|
||||
await run('array', 'UPDATED', {
|
||||
moduleToRun: core.modules.getArray,
|
||||
moduleToRun: modules.getArray,
|
||||
context: {
|
||||
user
|
||||
}
|
||||
@@ -45,7 +42,7 @@ dee.on('*', async (data) => {
|
||||
return;
|
||||
}
|
||||
|
||||
const { json } = await core.modules.getApps();
|
||||
const { json } = await modules.getApps();
|
||||
publish('info', 'UPDATED', json);
|
||||
});
|
||||
|
||||
@@ -61,7 +58,7 @@ setIntervalAsync(async () => {
|
||||
const user = usersState.findOne({ name: 'root' });
|
||||
|
||||
await run('services', 'UPDATED', {
|
||||
moduleToRun: core.modules.getServices,
|
||||
moduleToRun: modules.getServices,
|
||||
context: {
|
||||
user
|
||||
}
|
||||
@@ -76,7 +73,7 @@ setIntervalAsync(async () => {
|
||||
const createSubscription = (channel, resource?) => ({
|
||||
subscribe(_, __, context) {
|
||||
if (!context.user) {
|
||||
throw new AppError('<ws> No user found in context.');
|
||||
throw new AppError('<ws> No user found in context.', 500);
|
||||
}
|
||||
|
||||
// Check the user has permissison to subscribe to this endpoint
|
||||
@@ -159,11 +156,11 @@ export const resolvers = {
|
||||
|
||||
// Verify plugin is installed and active
|
||||
if (!pluginManager.isInstalled(pluginName, pluginModuleName)) {
|
||||
throw new PluginError('Plugin not installed.');
|
||||
throw new PluginError('Plugin not installed.', 500);
|
||||
}
|
||||
|
||||
if (!pluginManager.isActive(pluginName, pluginModuleName)) {
|
||||
throw new PluginError('Plugin disabled.');
|
||||
throw new PluginError('Plugin disabled.', 500);
|
||||
}
|
||||
|
||||
// It's up to the plugin to publish new data as needed
|
||||
@@ -4,16 +4,16 @@
|
||||
*/
|
||||
|
||||
import am from 'am';
|
||||
import core from '@unraid/core';
|
||||
import { core, loadServer } from '@unraid/core';
|
||||
import { server } from './server';
|
||||
|
||||
// Boot app
|
||||
am(async () => {
|
||||
// Load core
|
||||
await core.core.load();
|
||||
await core.load();
|
||||
|
||||
// Load server
|
||||
await core.loadServer('graphql-api', server);
|
||||
await loadServer('graphql-api', server);
|
||||
}, (error: NodeJS.ErrnoException) => {
|
||||
// We should only end here if core has an issue loading
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import { CoreResult } from '@unraid/core/dist/types';
|
||||
import * as core from '@unraid/core'
|
||||
import { CoreResult } from '@unraid/core/dist/lib/types';
|
||||
import { pubsub, utils, log } from '@unraid/core';
|
||||
import { canPublishToChannel } from './ws';
|
||||
|
||||
const { pubsub, utils, log } = core;
|
||||
const { debugTimer } = utils;
|
||||
|
||||
/**
|
||||
@@ -5,18 +5,17 @@
|
||||
|
||||
import fs from 'fs';
|
||||
import net from 'net';
|
||||
import request = require('request');
|
||||
import request from 'request';
|
||||
import stoppable from 'stoppable';
|
||||
import express from 'express';
|
||||
import http from 'http';
|
||||
import WebSocket from 'ws';
|
||||
import core from '@unraid/core';
|
||||
import { DynamixConfig } from '@unraid/core/dist/types';
|
||||
import { log, config, utils, paths, states } from '@unraid/core';
|
||||
import { DynamixConfig } from '@unraid/core/dist/lib/types';
|
||||
import { createServer } from './patched-install-subscription-handlers';
|
||||
import { graphql } from './graphql';
|
||||
|
||||
const { log, config, utils, paths, states } = core;
|
||||
const { getEndpoints, globalErrorHandler, exitApp, loadState, sleep } = utils;
|
||||
const { getEndpoints, globalErrorHandler, exitApp, loadState } = utils;
|
||||
const { varState } = states;
|
||||
|
||||
/**
|
||||
@@ -1,6 +1,4 @@
|
||||
import core from '@unraid/core';
|
||||
|
||||
const { log } = core;
|
||||
import { log } from '@unraid/core';
|
||||
|
||||
interface subscription {
|
||||
total: number
|
||||
32
index.js
32
index.js
@@ -22,6 +22,12 @@ const onWorkerExit = (_, code) => {
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
// Worker killed itself and doesn't want to be restarted
|
||||
if (code === 130) {
|
||||
log.debug(`Worker killed itself intentially. Exiting.`);
|
||||
process.exit(130);
|
||||
}
|
||||
|
||||
// Reload worker
|
||||
if (code === null || code === 0) {
|
||||
const newWorker = cluster.fork();
|
||||
@@ -88,6 +94,26 @@ if (cluster.isMaster) {
|
||||
if (cluster.isWorker) {
|
||||
log.info(`<worker> pid = ${process.pid}`);
|
||||
|
||||
const isMissingMainFile = (error) => {
|
||||
// Other error
|
||||
if (error.code !== 'MODULE_NOT_FOUND') {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Missing file but it's multiple levels deep
|
||||
// This likely isn't main
|
||||
if (error.requireStack.length >= 2) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// It's a single require but for another file
|
||||
if (error.requireStack[0] !== __filename) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
const package = require('./package.json');
|
||||
const { main } = package;
|
||||
@@ -103,8 +129,10 @@ if (cluster.isWorker) {
|
||||
log.info('<worker> loaded');
|
||||
require(mainPath);
|
||||
} catch (error) {
|
||||
if (isMissingMainFile(error)) {
|
||||
log.error(`<worker> Missing main file "${mainPath}".`);
|
||||
process.exit(130);
|
||||
}
|
||||
log.error(error);
|
||||
log.error(`<worker> Could not load main field "${mainPath}".`);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
938
package-lock.json
generated
938
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -28,7 +28,7 @@
|
||||
],
|
||||
"dependencies": {
|
||||
"@gridplus/docker-events": "github:OmgImAlexis/docker-events",
|
||||
"@unraid/core": "github:unraid/core#master",
|
||||
"@unraid/core": "github:unraid/core",
|
||||
"accesscontrol": "^2.2.1",
|
||||
"am": "^1.0.2",
|
||||
"apollo-server": "2.13.1",
|
||||
@@ -63,6 +63,7 @@
|
||||
"source-map-support": "0.5.19",
|
||||
"standard-version": "^7.1.0",
|
||||
"ts-node": "8.10.1",
|
||||
"tsup": "1.4.12",
|
||||
"typescript": "3.8.3",
|
||||
"xo": "0.30.0"
|
||||
},
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
{
|
||||
"include": [
|
||||
"src/**/*",
|
||||
"index.d.ts"
|
||||
"app/**/*"
|
||||
],
|
||||
"exclude": [
|
||||
"node_modules"
|
||||
],
|
||||
"compilerOptions": {
|
||||
"skipLibCheck": true,
|
||||
"skipLibCheck": true,
|
||||
/* Basic Options */
|
||||
// "incremental": true, /* Enable incremental compilation */
|
||||
"target": "es2015", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */
|
||||
@@ -21,7 +20,7 @@
|
||||
// "sourceMap": true, /* Generates corresponding '.map' file. */
|
||||
// "outFile": "./", /* Concatenate and emit output to single file. */
|
||||
"outDir": "./dist", /* Redirect output structure to the directory. */
|
||||
"rootDir": "./src", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
|
||||
"rootDir": "./app", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
|
||||
// "composite": true, /* Enable project compilation */
|
||||
// "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */
|
||||
// "removeComments": true, /* Do not emit comments to output. */
|
||||
@@ -70,8 +69,5 @@
|
||||
|
||||
/* Advanced Options */
|
||||
"forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */
|
||||
},
|
||||
"typeAcquisition": {
|
||||
"enable": true
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user