Skip to content

Commit

Permalink
simplify plugins
Browse files Browse the repository at this point in the history
  • Loading branch information
joshuawright11 committed Jul 17, 2024
1 parent efc6615 commit ef22b40
Show file tree
Hide file tree
Showing 17 changed files with 66 additions and 106 deletions.
54 changes: 24 additions & 30 deletions Alchemy/Application/Application.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,32 +20,29 @@ public protocol Application: Router {
/// Build the hummingbird server
var server: HTTPServerBuilder { get }

init()

/// Setup your application here. Called after all services are registered.
func boot() throws
/// Optional shutdown logic here.
func shutdown() throws
// MARK: Configurations

// MARK: Default Plugin Configurations

/// This application's HTTP configuration.
var http: HTTPConfiguration { get }
/// This application's filesystems.
var filesystems: Filesystems { get }
/// This application's databases.
var databases: Databases { get }
/// The application's caches.
var caches: Caches { get }
/// The application's job queues.
var queues: Queues { get }
/// The application's custom commands.
var commands: Commands { get }
/// This application's databases.
var databases: Databases { get }
/// This application's filesystems.
var filesystems: Filesystems { get }
/// This application's HTTP configuration.
var http: HTTPConfiguration { get }
/// The application's loggers.
var loggers: Loggers { get }

/// Setup any scheduled tasks in your application here.
func schedule(on schedule: Scheduler)
/// The application's job queues.
var queues: Queues { get }

init()

/// Setup your application here. Called after all services are registered.
func boot() async throws
/// Optional shutdown logic here.
func shutdown() async throws
}

// MARK: Defaults
Expand All @@ -62,9 +59,8 @@ public extension Application {
var queues: Queues { Queues() }
var server: HTTPServerBuilder { .http1() }

func boot() throws {}
func shutdown() throws {}
func schedule(on schedule: Scheduler) {}
func boot() async throws {}
func shutdown() async throws {}
}

// MARK: Running
Expand Down Expand Up @@ -92,22 +88,20 @@ extension Application {
try await commander.run(args: args.isEmpty ? nil : args)
}

/// Stops a currently running application. The `Application` will handle this
/// as though it were sent a `SIGINT`.
public func stop() async {
await lifecycle.stop()
}

/// Sets up the app for running.
public func willRun() async throws {
let lifecycle = Lifecycle(app: self)
try await lifecycle.boot()
(self as? Controller)?.route(self)
try boot()
}

/// Any cleanup after the app finishes running.
public func didRun() async throws {
try shutdown()
try await lifecycle.shutdown()
}

/// Stops a currently running application.
public func stop() async {
await lifecycle.stop()
}
}
13 changes: 7 additions & 6 deletions Alchemy/Application/Lifecycle.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ public final class Lifecycle {
self.app = app
self.plugins = [
Core(),
app.commands,
Schedules(),
EventStreams(),
app.http,
app.commands,
app.filesystems,
app.databases,
app.caches,
Expand Down Expand Up @@ -49,26 +49,27 @@ public final class Lifecycle {
public func boot() async throws {
app.container.register(self).singleton()

for plugin in plugins {
plugin.registerServices(in: app)
}

for plugin in plugins {
try await plugin.boot(app: app)
}

for start in startTasks {
try await start()
}

(app as? Controller)?.route(app)
try await app.boot()
}

public func shutdown() async throws {
try await app.shutdown()

for shutdown in shutdownTasks.reversed() {
try await shutdown()
}

for plugin in plugins.reversed() {
try await plugin.shutdownServices(in: app)
try await plugin.shutdown(app: app)
}
}

Expand Down
15 changes: 5 additions & 10 deletions Alchemy/Application/Plugins/Core.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,19 @@ import NIO

/// Registers core Alchemy services to an application.
struct Core: Plugin {
func registerServices(in app: Application) {

func boot(app: Application) {
// 0. Register Application

app.container.register(app).singleton()
app.container.register(app as Application).singleton()

// 1. Register Environment

app.container.register { Environment.createDefault() }.singleton()

// 2. Register Loggers

app.loggers.registerServices(in: app)
app.loggers.boot(app: app)

// 3. Register NIO services

Expand All @@ -33,11 +32,7 @@ struct Core: Plugin {
}
}

func boot(app: Application) {
app.container.resolve(NIOThreadPool.self)?.start()
}

func shutdownServices(in app: Application) async throws {
func shutdown(app: Application) async throws {
try await app.container.resolve(EventLoopGroup.self)?.shutdownGracefully()
}
}
Expand Down
2 changes: 1 addition & 1 deletion Alchemy/Cache/Caches.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ public struct Caches: Plugin {
self.caches = caches
}

public func registerServices(in app: Application) {
public func boot(app: Application) {
let caches = caches()
for (id, cache) in caches {
app.container.register(cache, id: id).singleton()
Expand Down
4 changes: 1 addition & 3 deletions Alchemy/Command/Plugins/Commands.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,9 @@ public struct Commands: Plugin, ExpressibleByArrayLiteral {
self.commands = elements
}

public func registerServices(in app: Application) {
public func boot(app: Application) {
app.container.register(Commander()).singleton()
}

public func boot(app: Application) {
for command in commands {
app.registerCommand(command)
}
Expand Down
6 changes: 2 additions & 4 deletions Alchemy/Database/Plugins/Databases.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public final class Databases: Plugin {
self.redis = redis
}

public func registerServices(in app: Application) {
public func boot(app: Application) {
_databases = databases()
guard let _databases else { return }

Expand All @@ -44,17 +44,15 @@ public final class Databases: Plugin {
if let _default = defaultRedis ?? redis.keys.first {
app.container.register(Redis(_default)).singleton()
}
}

public func boot(app: Application) {
app.registerCommand(SeedCommand.self)
app.registerCommand(MigrateCommand.self)
app.registerCommand(RollbackMigrationsCommand.self)
app.registerCommand(ResetMigrationsCommand.self)
app.registerCommand(RefreshMigrationsCommand.self)
}

public func shutdownServices(in app: Application) async throws {
public func shutdown(app: Application) async throws {
guard let _databases else { return }
for id in _databases.keys {
try await app.container.resolve(Database.self, id: id)?.shutdown()
Expand Down
2 changes: 1 addition & 1 deletion Alchemy/Events/Plugins/EventStreams.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
struct EventStreams: Plugin {
func registerServices(in app: Application) {
func boot(app: Application) {
app.container.register(EventBus()).singleton()
}
}
2 changes: 1 addition & 1 deletion Alchemy/Filesystem/Plugins/Filesystems.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ public struct Filesystems: Plugin {
self.disks = disks
}

public func registerServices(in app: Application) {
public func boot(app: Application) {
for (id, disk) in disks {
app.container.register(disk, id: id).singleton()
}
Expand Down
4 changes: 2 additions & 2 deletions Alchemy/HTTP/Plugins/HTTPConfiguration.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public struct HTTPConfiguration: Plugin {
self.maxUploadSize = maxUploadSize
}

public func registerServices(in app: Application) {
public func boot(app: Application) {

// 0. Register Router

Expand All @@ -38,7 +38,7 @@ public struct HTTPConfiguration: Plugin {
app.container.register(Hasher(algorithm: defaultHashAlgorithm)).singleton()
}

public func shutdownServices(in app: Application) async throws {
public func shutdown(app: Application) async throws {
try app.container.resolve(Client.self)?.shutdown()
}
}
2 changes: 1 addition & 1 deletion Alchemy/Logging/Loggers.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ public struct Loggers: Plugin {
self.loggers = loggers
}

public func registerServices(in app: Application) {
public func boot(app: Application) {
let logLevel = app.env.logLevel
for (id, logger) in loggers {
var logger = logger
Expand Down
6 changes: 2 additions & 4 deletions Alchemy/Queue/Plugins/Queues.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ public struct Queues: Plugin {
self.jobs = jobs
}

public func registerServices(in app: Application) {
public func boot(app: Application) {
let queues = queues()
for (id, queue) in queues {
app.container.register(queue, id: id).singleton()
Expand All @@ -24,13 +24,11 @@ public struct Queues: Plugin {
for job in jobs {
app.registerJob(job)
}
}

public func boot(app: Application) {
app.registerCommand(WorkCommand.self)
}

public func shutdownServices(in app: Application) async throws {
public func shutdown(app: Application) async throws {
app.container.require(JobRegistry.self).reset()
}
}
Expand Down
12 changes: 5 additions & 7 deletions Alchemy/Scheduler/Plugins/Schedules.swift
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
struct Schedules: Plugin {
func registerServices(in app: Application) {
app.container.register(Scheduler()).singleton()
}
let scheduler = Scheduler()

func boot(app: Application) async throws {
app.schedule(on: Schedule)
func boot(app: Application) {
app.container.register(scheduler).singleton()
app.registerCommand(ScheduleCommand.self)
}

func shutdownServices(in app: Application) async throws {
try await app.container.resolve(Scheduler.self)?.shutdown()
func shutdown(app: Application) async throws {
try await scheduler.shutdown()
}
}
34 changes: 6 additions & 28 deletions Alchemy/Services/Plugin.swift
Original file line number Diff line number Diff line change
@@ -1,34 +1,12 @@
import ServiceLifecycle

/// A Plugin represents a modular component of an Alchemy application. They
/// typically inject services into a container that can be used by other
/// plugins and add functionality to an Application once it is loaded.
/// A Plugin represents a modular component of an Alchemy application.
public protocol Plugin {
/// A label for this plugin, for registration in the app lifecycle.
var label: String { get }

/// Register any services to an Application.
func registerServices(in app: Application)

/// Setup this plugin for the given app.
/// Start this plugin given an app.
func boot(app: Application) async throws

/// Any shutdown logic before services are deallocated from the container.
func shutdownServices(in app: Application) async throws
/// Shutdown the plugin that was booted on the given app.
func shutdown(app: Application) async throws
}

public extension Plugin {
var label: String { name(of: Self.self) }

func registerServices(in app: Application) {
//
}

func boot(app: Application) async throws {
//
}

func shutdownServices(in app: Application) async throws {
//
}
extension Plugin {
public func shutdown(app: Application) async throws {}
}
4 changes: 2 additions & 2 deletions Tests/Cache/CacheTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ final class CacheTests: TestCase<TestApp> {
_testWipe,
]

func testPlugin() {
func testPlugin() async throws {
let config = Caches(caches: [1: .memory, 2: .memory, 3: .memory])
config.registerServices(in: app)
config.boot(app: app)
XCTAssertNotNil(Container.resolve(Cache.self))
XCTAssertNotNil(Container.resolve(Cache.self, id: 1))
XCTAssertNotNil(Container.resolve(Cache.self, id: 2))
Expand Down
4 changes: 2 additions & 2 deletions Tests/Database/DatabaseTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ final class DatabaseTests: TestCase<TestApp> {
1: .testing,
2: .testing
])
plugin.registerServices(in: app)
plugin.boot(app: app)
XCTAssertNotNil(Container.resolve(Database.self))
XCTAssertNotNil(Container.resolve(Database.self, id: 1))
XCTAssertNotNil(Container.resolve(Database.self, id: 2))
Expand All @@ -24,7 +24,7 @@ final class DatabaseTests: TestCase<TestApp> {
XCTAssertNotNil(Container.resolve(RedisClient.self, id: 2))
XCTAssertEqual(DB.migrations.count, 1)
XCTAssertEqual(DB.seeders.count, 1)
try await plugin.shutdownServices(in: app)
try await plugin.shutdown(app: app)
}
}

Expand Down
4 changes: 2 additions & 2 deletions Tests/Filesystem/FilesystemTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ final class FilesystemTests: TestCase<TestApp> {
self.filePath = UUID().uuidString + ".txt"
}

func testPlugin() {
func testPlugin() async throws {
let plugin = Filesystems(default: 1, disks: [1: .local, 2: .local])
plugin.registerServices(in: app)
plugin.boot(app: app)
XCTAssertNotNil(Container.resolve(Filesystem.self))
XCTAssertNotNil(Container.resolve(Filesystem.self, id: 1))
XCTAssertNotNil(Container.resolve(Filesystem.self, id: 2))
Expand Down
Loading

0 comments on commit ef22b40

Please sign in to comment.