From 4e00d046271411c6ceac61f5e2e399a3f00ba026 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sat, 1 May 2021 23:01:39 -0500 Subject: [PATCH] Convert Seeker to use the Microservice package --- services/seeker/package.json | 1 + services/seeker/src/Application.ts | 89 +------------------ services/seeker/src/index.ts | 2 +- services/seeker/src/services/Database.ts | 10 +-- services/seeker/src/services/IpcInterface.ts | 13 ++- services/seeker/src/services/MovieSearch.ts | 13 ++- .../services/PostProcessor/PostProcessor.ts | 23 ++--- services/seeker/src/services/Service.ts | 58 ------------ services/seeker/src/services/Supervisor.ts | 17 ++-- .../TorrentManager/TorrentClientIpc.ts | 8 +- .../services/TorrentManager/TorrentManager.ts | 12 ++- 11 files changed, 55 insertions(+), 191 deletions(-) delete mode 100644 services/seeker/src/services/Service.ts diff --git a/services/seeker/package.json b/services/seeker/package.json index b430287..d49fe7a 100644 --- a/services/seeker/package.json +++ b/services/seeker/package.json @@ -22,6 +22,7 @@ }, "dependencies": { "@autoplex/database": "^0.0.0", + "@autoplex/microservice": "^0.0.0", "@autoplex/utils": "^0.0.0", "cheerio": "^1.0.0-rc.6", "diskusage": "^1.1.3", diff --git a/services/seeker/src/Application.ts b/services/seeker/src/Application.ts index 3fd7a76..ef88a10 100644 --- a/services/seeker/src/Application.ts +++ b/services/seeker/src/Application.ts @@ -1,104 +1,23 @@ import services from "./services"; -import Service from "./services/Service"; -import assert from "assert"; - -interface ServiceMap { - [name: string]: Service -} +import { Microservice } from "@autoplex/microservice"; /** * The main application class */ -export default class Application +export default class Application extends Microservice { - private static __instance: Application; - - /** - * All available services - */ - protected services: ServiceMap = {}; - /** * Return the current application instance */ - public static instance() { - return this.__instance; - } + public static instance() { return super.instance() } /** * Create a new application instance */ public constructor() { - Application.__instance = this; + super(); for (let ServiceClass of Object.values(services)) { this.installService(ServiceClass); } } - - /** - * Install a service into the application - */ - protected installService(ServiceClass: new (app: Application) => Service) { - let service = new ServiceClass(this); - this.services[service.name] = service; - } - - /** - * Boot the application and all of the services - */ - protected async boot() { - let services = Object.values(this.services); - return Promise.all(services.map(service => service.boot())); - } - - /** - * Initialize the application if necessary - */ - protected async initialize() { - - } - - /** - * Shutdown the application - */ - protected shutdown() { - let services = Object.values(this.services); - return Promise.all(services.map(service => service.shutdown())); - } - - /** - * Start the application - */ - public async start() { - await this.boot(); - await this.initialize(); - for (let service of Object.values(this.services)) { - service.start(); - } - } - - /** - * Quit the application - */ - public async quit(code: number = 0) { - await this.shutdown(); - process.exit(code); - } - - // Access -------------------------------------------------------------------------------------- - - /** - * Get all available services - */ - public serviceList() { - return Object.keys(this.services); - } - - /** - * Get an application service instance - */ - public service(serviceName: string) { - assert(serviceName in this.services, `Could not find service: ${serviceName}`); - return this.services[serviceName]; - } } diff --git a/services/seeker/src/index.ts b/services/seeker/src/index.ts index d5d625d..49185c5 100644 --- a/services/seeker/src/index.ts +++ b/services/seeker/src/index.ts @@ -4,4 +4,4 @@ import Application from "./Application"; let app = new Application(); // Start the application -app.start(); +app.exec(); diff --git a/services/seeker/src/services/Database.ts b/services/seeker/src/services/Database.ts index ae49365..eafb4fd 100644 --- a/services/seeker/src/services/Database.ts +++ b/services/seeker/src/services/Database.ts @@ -1,10 +1,10 @@ import { Connection } from "typeorm"; import connectToDatabase from "@autoplex/database"; import { env, secret } from "@autoplex/utils"; -import Service from "./Service"; +import { InternalService } from "@autoplex/microservice"; import Application from "../Application"; -export default class Database extends Service +export default class Database extends InternalService { /** * The active database connection @@ -12,10 +12,10 @@ export default class Database extends Service protected connection!: Connection; /** - * Create a new database instance + * The service name */ - public constructor(app: Application) { - super("Database", app); + public get name() { + return "Database"; } /** diff --git a/services/seeker/src/services/IpcInterface.ts b/services/seeker/src/services/IpcInterface.ts index b0c0490..ee72356 100644 --- a/services/seeker/src/services/IpcInterface.ts +++ b/services/seeker/src/services/IpcInterface.ts @@ -2,12 +2,12 @@ import { IPC } from "node-ipc"; import { Socket } from "net"; import { mkdir } from "fs/promises"; import { dirname } from "path"; -import Service from "./Service"; +import { InternalService } from "@autoplex/microservice"; import Application from "../Application"; import Supervisor from "./Supervisor"; import { MovieTicket } from "@autoplex/database"; -export default class IpcInterface extends Service +export default class IpcInterface extends InternalService { /** * The IPC instance @@ -18,13 +18,20 @@ export default class IpcInterface extends Service * Create a new IPC interface */ public constructor(app: Application) { - super("IPC", app); + super(app); this.__ipc = new IPC(); this.__ipc.config.id = "seeker"; this.__ipc.config.retry = 1500; this.__ipc.config.silent = true; } + /** + * The service name + */ + public get name() { + return "IPC" + } + /** * Boot the IPC interface */ diff --git a/services/seeker/src/services/MovieSearch.ts b/services/seeker/src/services/MovieSearch.ts index 0c32114..6a02b07 100644 --- a/services/seeker/src/services/MovieSearch.ts +++ b/services/seeker/src/services/MovieSearch.ts @@ -4,10 +4,10 @@ import * as providerClasses from "../torrents"; import Provider, { MediaType } from "../torrents/providers/Provider"; import Torrent from "../torrents/Torrent"; import { rankTorrents } from "../torrents/ranking"; -import Service from "./Service"; +import { InternalService } from "@autoplex/microservice"; import Supervisor from "./Supervisor"; -export default class MovieSearch extends Service +export default class MovieSearch extends InternalService { /** * The queue of current movie tickts requiring torrents @@ -33,11 +33,18 @@ export default class MovieSearch extends Service * Create a new instance of the movie search service */ public constructor(app: Application) { - super("Movie Search", app); + super(app); this.movieQueue = []; this.isSearchingForMovies = false; } + /** + * The service name + */ + public get name() { + return "Movie Search"; + } + /** * Boot the movie search service */ diff --git a/services/seeker/src/services/PostProcessor/PostProcessor.ts b/services/seeker/src/services/PostProcessor/PostProcessor.ts index ba1a7d8..e536df9 100644 --- a/services/seeker/src/services/PostProcessor/PostProcessor.ts +++ b/services/seeker/src/services/PostProcessor/PostProcessor.ts @@ -2,10 +2,10 @@ import { link, mkdir } from "fs/promises"; import { dirname, extname } from "path"; import Application from "../../Application"; import { MovieTicket, MovieTorrent } from "@autoplex/database"; -import Service from "../Service"; import { ISerializedTorrent } from "../TorrentManager/TorrentClientIpc"; import { safeTitleFileName } from "../../utils"; import Supervisor from "../Supervisor"; +import { InternalService } from "@autoplex/microservice"; /** * Common video file extensions @@ -23,39 +23,32 @@ interface IPendingMovieTorrent { ticket : MovieTicket } -export default class PostProcessor extends Service +export default class PostProcessor extends InternalService { /** * The queue of movies to process */ - protected pendingMovies: IPendingMovieTorrent[]; + protected pendingMovies: IPendingMovieTorrent[] = []; /** * Indicate if movies are currently being processed */ - protected isProcessingMovies: boolean; + protected isProcessingMovies: boolean = false; /** * Create a new instance of the post processor */ public constructor(app: Application) { - super("Post Processor", app); + super(app); this.pendingMovies = []; this.isProcessingMovies = false; } /** - * Boot the post-processor service + * The service name */ - public async boot() { - - } - - /** - * Shutdown the post-processor service - */ - public async shutdown() { - + public get name() { + return "Post Processor"; } // Methods ------------------------------------------------------------------------------------- diff --git a/services/seeker/src/services/Service.ts b/services/seeker/src/services/Service.ts deleted file mode 100644 index 61c0d2a..0000000 --- a/services/seeker/src/services/Service.ts +++ /dev/null @@ -1,58 +0,0 @@ -import Application from "../Application"; - -export default abstract class Service -{ - /** - * The name of the service - */ - public readonly name: string; - - /** - * The application instance - */ - protected readonly app: Application; - - /** - * Enable/disable logging for this service - */ - public logging: boolean = true; - - /** - * Create a new service - */ - public constructor(name: string, app: Application) { - this.app = app; - this.name = name; - } - - // Required Service Implementation ------------------------------------------------------------- - - /** - * Boot the service - */ - public abstract boot(): Promise; - - /** - * Shut the application down - */ - public abstract shutdown(): Promise; - - // Miscellaneous ------------------------------------------------------------------------------ - - /** - * Indicate the application is ready - */ - public start() { - // no-op - }; - - /** - * Service-specific logging - */ - public log(...args: any[]) { - if (!this.logging) { - return; - } - console.log(`[${this.name}]:`, ...args); - } -} diff --git a/services/seeker/src/services/Supervisor.ts b/services/seeker/src/services/Supervisor.ts index 29371aa..f33b8d8 100644 --- a/services/seeker/src/services/Supervisor.ts +++ b/services/seeker/src/services/Supervisor.ts @@ -2,11 +2,11 @@ import Application from "../Application"; import { MovieTicket, MovieTorrent } from "@autoplex/database"; import MovieSearch from "./MovieSearch"; import PostProcessor from "./PostProcessor"; -import Service from "./Service"; +import { InternalService } from "@autoplex/microservice"; import TorrentManager from "./TorrentManager"; import { ISerializedTorrent } from "./TorrentManager/TorrentClientIpc"; -export default class Supervisor extends Service +export default class Supervisor extends InternalService { /** @@ -28,13 +28,15 @@ export default class Supervisor extends Service * Create a new supervisor service instance */ public constructor(app: Application) { - super("Supervisor", app); + super(app); } /** - * Boot the supervisor service + * The service name */ - public async boot() {} + public get name() { + return "Supervisor"; + } /** * All services are booted and ready @@ -46,11 +48,6 @@ export default class Supervisor extends Service this.searchMovies(); } - /** - * Shutdown the supervisor service - */ - public async shutdown() {} - // Request Flow -------------------------------------------------------------------------------- /** diff --git a/services/seeker/src/services/TorrentManager/TorrentClientIpc.ts b/services/seeker/src/services/TorrentManager/TorrentClientIpc.ts index 651ee36..4c57733 100644 --- a/services/seeker/src/services/TorrentManager/TorrentClientIpc.ts +++ b/services/seeker/src/services/TorrentManager/TorrentClientIpc.ts @@ -1,7 +1,7 @@ import { Socket } from "net"; import Application from "../../Application"; -import Service from "../Service"; import ipc = require("node-ipc"); +import { InternalService } from "@autoplex/microservice"; interface IResponse { response?: any, @@ -58,7 +58,7 @@ export class TorrentClientConnectionError extends Error { /** * The torrent client IPC service */ -export default class TorrentClientIpc extends Service +export default abstract class TorrentClientIpc extends InternalService { /** * Indicate if there is an active connection to the IPC @@ -78,8 +78,8 @@ export default class TorrentClientIpc extends Service /** * Create a new IPC client for the torrent client */ - constructor(name: string, app: Application) { - super(name, app); + constructor(app: Application) { + super(app); this.__ipc.config.id = "seeker"; this.__ipc.config.retry = 1500; this.__ipc.config.silent = true; diff --git a/services/seeker/src/services/TorrentManager/TorrentManager.ts b/services/seeker/src/services/TorrentManager/TorrentManager.ts index d66afb0..4b88072 100644 --- a/services/seeker/src/services/TorrentManager/TorrentManager.ts +++ b/services/seeker/src/services/TorrentManager/TorrentManager.ts @@ -23,12 +23,12 @@ export default class TorrentManager extends TorrentClientIpc /** * The queue of movies to add to the client */ - protected pendingMovies: IPendingMovieTorrent[]; + protected pendingMovies: IPendingMovieTorrent[] = []; /** * Indicate if the service is currently adding movies to the torrent client */ - protected isAddingMovies: boolean; + protected isAddingMovies: boolean = false; /** * Available movie disk names @@ -36,12 +36,10 @@ export default class TorrentManager extends TorrentClientIpc protected disks!: IDiskMap; /** - * Create a new torrent manager instance + * The service name */ - public constructor(app: Application) { - super("Torrent Manager", app); - this.pendingMovies = []; - this.isAddingMovies = false; + public get name() { + return "Torrent Manager"; } /**