Refactor event bus and queue system; detect cycles in DI realization and make
Some checks failed
continuous-integration/drone/push Build is failing

This commit is contained in:
2022-01-26 19:37:54 -06:00
parent 506fb55c74
commit 6d1cf18680
69 changed files with 1673 additions and 720 deletions

View File

@@ -155,6 +155,18 @@ export abstract class Canonical<T> extends Unit {
return `${this.canonicalItem}s`
}
/** Get a canonical item by key, throwing an error if it could not be found. */
public getOrFail(key: string): T {
const result = this.get(key)
if ( !result ) {
throw new ErrorWithContext(`Unable to resolve Canonical key: ${key}`, {
key,
})
}
return result
}
/** Get a canonical item by key. */
public get(key: string): T | undefined {
if ( key.startsWith('@') ) {
@@ -221,24 +233,26 @@ export abstract class Canonical<T> extends Unit {
}
public async up(): Promise<void> {
for await ( const entry of this.path.walk() ) {
if ( !entry.endsWith(this.suffix) ) {
this.logging.debug(`Skipping file with invalid suffix: ${entry}`)
continue
if ( await this.path.exists() ) {
for await ( const entry of this.path.walk() ) {
if ( !entry.endsWith(this.suffix) ) {
this.logging.debug(`Skipping file with invalid suffix: ${entry}`)
continue
}
const definition = await this.buildCanonicalDefinition(entry)
this.logging.verbose(`Registering canonical ${this.canonicalItem} "${definition.canonicalName}" from ${entry}`)
const resolvedItem = await this.initCanonicalItem(definition)
if ( isCanonicalReceiver(resolvedItem) ) {
resolvedItem.setCanonicalResolver(
`${this.canonicalItems}::${definition.canonicalName}`,
definition.canonicalName,
)
}
this.loadedItems[definition.canonicalName] = resolvedItem
}
const definition = await this.buildCanonicalDefinition(entry)
this.logging.verbose(`Registering canonical ${this.canonicalItem} "${definition.canonicalName}" from ${entry}`)
const resolvedItem = await this.initCanonicalItem(definition)
if ( isCanonicalReceiver(resolvedItem) ) {
resolvedItem.setCanonicalResolver(
`${this.canonicalItems}::${definition.canonicalName}`,
definition.canonicalName,
)
}
this.loadedItems[definition.canonicalName] = resolvedItem
}
this.canon.registerCanonical(this)

View File

@@ -18,8 +18,8 @@ import {ParseIncomingBodyHTTPModule} from '../http/kernel/module/ParseIncomingBo
import {Config} from './Config'
import {InjectRequestEventBusHTTPModule} from '../http/kernel/module/InjectRequestEventBusHTTPModule'
import {Routing} from './Routing'
import {EventBus} from '../event/EventBus'
import {RequestLocalStorage} from '../http/RequestLocalStorage'
import {Bus} from '../support/bus'
/**
* Application unit that starts the HTTP/S server, creates Request and Response objects
@@ -40,7 +40,7 @@ export class HTTPServer extends Unit {
protected readonly routing!: Routing
@Inject()
protected readonly bus!: EventBus
protected readonly bus!: Bus
@Inject()
protected readonly requestLocalStorage!: RequestLocalStorage

View File

@@ -1,25 +1,15 @@
import {CanonicalStatic} from './CanonicalStatic'
import {Singleton, Instantiable, StaticClass} from '../di'
import {CanonicalDefinition} from './Canonical'
import {Queueable} from '../support/queue/Queue'
import {Singleton, Instantiable} from '../di'
import {Queueable} from '../support/bus'
/**
* A canonical unit that resolves Queueable classes from `app/queueables`.
* A canonical unit that resolves Queueable classes from `app/jobs`.
*/
@Singleton()
export class Queueables extends CanonicalStatic<Queueable, Instantiable<Queueable>> {
export class Queueables extends CanonicalStatic<Queueables, Instantiable<Queueable>> {
protected appPath = ['jobs']
protected canonicalItem = 'job'
protected suffix = '.job.js'
public async initCanonicalItem(definition: CanonicalDefinition): Promise<StaticClass<Queueable, Instantiable<Queueable>>> {
const item = await super.initCanonicalItem(definition)
if ( !(item.prototype instanceof Queueable) ) {
throw new TypeError(`Invalid middleware definition: ${definition.originalName}. Controllers must extend from @extollo/lib.Queueable.`)
}
return item
}
}

View File

@@ -8,9 +8,9 @@ import {ViewEngineFactory} from '../views/ViewEngineFactory'
import {ViewEngine} from '../views/ViewEngine'
import {lib} from '../lib'
import {Config} from './Config'
import {EventBus} from '../event/EventBus'
import {PackageDiscovered} from '../support/PackageDiscovered'
import {staticServer} from '../http/servers/static'
import {Bus} from '../support/bus'
/**
* Application unit that loads the various route files from `app/http/routes` and pre-compiles the route handlers.
@@ -24,7 +24,7 @@ export class Routing extends Unit {
protected readonly config!: Config
@Inject()
protected readonly bus!: EventBus
protected readonly bus!: Bus
protected compiledRoutes: Collection<Route<unknown, unknown[]>> = new Collection<Route<unknown, unknown[]>>()
@@ -54,7 +54,7 @@ export class Routing extends Unit {
this.logging.verbose(`${route}`)
})
this.bus.subscribe(PackageDiscovered, async (event: PackageDiscovered) => {
await this.bus.subscribe(PackageDiscovered, async (event: PackageDiscovered) => {
const loadFrom = event.packageConfig?.extollo?.routes?.loadFrom
if ( Array.isArray(loadFrom) ) {
for ( const path of loadFrom ) {