Browse Source

Implement Microservice package into torrent client

dev
David Ludwig 4 years ago
parent
commit
4f137f6793
8 changed files with 100 additions and 67 deletions
  1. +2
    -0
      services/torrent-client/package.json
  2. +0
    -49
      services/torrent-client/src/Application.ts
  3. +9
    -8
      services/torrent-client/src/database/index.ts
  4. +7
    -3
      services/torrent-client/src/index.ts
  5. +38
    -0
      services/torrent-client/src/services/Database.ts
  6. +15
    -4
      services/torrent-client/src/services/IpcInterface.ts
  7. +20
    -3
      services/torrent-client/src/services/TorrentClient.ts
  8. +9
    -0
      services/torrent-client/src/services/index.ts

+ 2
- 0
services/torrent-client/package.json View File

@ -26,6 +26,8 @@
"typescript": "^4.2.3"
},
"dependencies": {
"@autoplex/microservice": "^0.0.0",
"@autoplex/utils": "^0.0.0",
"bitfield": "^4.0.0",
"mysql": "^2.18.1",
"node-ipc": "^9.1.4",


+ 0
- 49
services/torrent-client/src/Application.ts View File

@ -1,49 +0,0 @@
import { Equal } from "typeorm";
import connectToDatabase from "./database";
import IpcInterface from "./services/IpcInterface";
import TorrentClient from "./services/TorrentClient";
export default class Application
{
/**
* The torrent client instance
*/
private __client: TorrentClient;
/**
* The IPC interface for the torrent client
*/
private __ipcInterface: IpcInterface;
/**
* Create the application
*/
public constructor() {
this.__client = new TorrentClient();
this.__ipcInterface = new IpcInterface(this.__client);
}
/**
* Boot the application services
*/
private async boot() {
await connectToDatabase();
await this.__client.boot();
await this.__ipcInterface.boot();
}
/**
* Start and run the application
*/
public async exec() {
await this.boot();
console.log("Torrent client ready");
}
/**
* Get the torrent client instance
*/
public get torrentClient() {
return this.__client;
}
}

+ 9
- 8
services/torrent-client/src/database/index.ts View File

@ -1,15 +1,16 @@
import { readFileSync } from "fs";
import { createConnection } from "typeorm";
import entities from "./entities";
export default async function connectToDatabase() {
export default async function connectToDatabase(host: string, port: number, username: string,
password: string, database: string)
{
return createConnection({
type : <"mysql" | "mariadb">process.env["DB_TYPE"],
host : process.env["DB_HOST"],
port : parseInt(<string>process.env["DB_PORT"]),
username : process.env["DB_USER"],
password : readFileSync(<string>process.env["DB_PASSWORD_FILE"]).toString().trim(),
database : process.env["DB_DATABASE"],
type: "mysql",
host,
port,
username,
password,
database,
synchronize: true,
entities,
migrations: ["src/migrations/*.ts"]


+ 7
- 3
services/torrent-client/src/index.ts View File

@ -1,7 +1,11 @@
import Application from "./Application";
import { Microservice } from "@autoplex/microservice";
import * as services from "./services";
// Create the application
let app = new Application();
let app = new Microservice();
// Install the services
app.installServices(Object.values(services));
// Execute the app
app.exec();
app.exec().then(process.exit);

+ 38
- 0
services/torrent-client/src/services/Database.ts View File

@ -0,0 +1,38 @@
import { Connection } from "typeorm";
import connectToDatabase from "../database";
import { env, secret } from "@autoplex/utils";
import { InternalService } from "@autoplex/microservice";
export default class Database extends InternalService
{
/**
* The active database connection
*/
public connection!: Connection;
/**
* The service name
*/
public get name() {
return "Database";
}
/**
* Boot the database service
*/
public async boot() {
let host = env("DB_HOST");
let port = parseInt(env("DB_PORT"));
let username = env("DB_USER");
let password = await secret(env("DB_PASSWORD_FILE"));
let database = env("DB_DATABASE");
this.connection = await connectToDatabase(host, port, username, password, database);
}
/**
* Shutdown the database service
*/
public async shutdown() {
await this.connection.close();
}
}

+ 15
- 4
services/torrent-client/src/services/IpcInterface.ts View File

@ -6,18 +6,19 @@ import { Socket } from "net";
import assert from "assert";
import WebTorrent from "webtorrent-hybrid";
import TorrentClient from "./TorrentClient";
import { InternalService, Microservice } from "@autoplex/microservice";
type IAddTorrent = string | {
type: "Buffer",
data: number[]
}
export default class IpcInterface
export default class IpcInterface extends InternalService
{
/**
* The torrent client instance
*/
protected torrentClient: TorrentClient;
protected torrentClient!: TorrentClient;
/**
* Quick reference to the IPC server
@ -27,18 +28,28 @@ export default class IpcInterface
/**
* Create a new IPC interface
*/
public constructor(client: TorrentClient) {
public constructor(app: Microservice) {
super(app);
ipc.config.id = "torrent-client";
ipc.config.retry = 1500;
ipc.config.silent = true;
}
this.torrentClient = client;
/**
* The service name
*/
public get name() {
return "IPC";
}
/**
* Boot the IPC interface
*/
public boot() {
// Store a reference to the torrent client
this.torrentClient = this.app.service<TorrentClient>("Torrent Client");
// Boot the IPC socket
return new Promise<void>(async (resolve, reject) => {
console.log("Serving:", process.env["IPC_SOCKET_PATH"]);
await mkdir(dirname(<string>process.env["IPC_SOCKET_PATH"]), { recursive: true });


+ 20
- 3
services/torrent-client/src/services/TorrentClient.ts View File

@ -1,3 +1,4 @@
import { InternalService } from "@autoplex/microservice";
import assert from "assert";
import MagnetUri from "magnet-uri";
import WebTorrent from "webtorrent-hybrid";
@ -6,7 +7,7 @@ import { extname, join, sep } from "path";
import Torrent from "../database/entities/Torrent";
import rimraf from "rimraf";
import { ISerializedTorrent, TorrentState } from "../common";
import { EventEmitter } from "events";
import { Database } from ".";
interface IAddOptions {
downloadPath?: string;
@ -32,7 +33,7 @@ export declare interface TorrentClient {
): this;
}
export class TorrentClient extends EventEmitter
export class TorrentClient extends InternalService
{
/**
* The current WebTorrent instance (available after boot)
@ -41,6 +42,16 @@ export class TorrentClient extends EventEmitter
// ---------------------------------------------------------------------------------------------
/**
* The service name
*/
public get name() {
return "Torrent Client"
}
/**
* Boot the service
*/
public async boot() {
this.__webtorrent = new WebTorrent();
@ -53,8 +64,14 @@ export class TorrentClient extends EventEmitter
torrent.on("noPeers", (...args) => this.onTorrentNoPeers(torrent, ...args));
torrent.on("wire", (...args) => this.onTorrentWire(torrent, ...args));
});
}
await this.loadTorrents();
/**
* @TODO really this is kinda bad putting this here...
* Start the torrent client
*/
public start() {
this.loadTorrents();
}
// Event Handling ------------------------------------------------------------------------------


+ 9
- 0
services/torrent-client/src/services/index.ts View File

@ -0,0 +1,9 @@
import Database from "./Database";
import IpcInterface from "./IpcInterface";
import TorrentClient from "./TorrentClient";
export {
Database,
IpcInterface,
TorrentClient
}

Loading…
Cancel
Save