Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use ComponentLifecycle in HBApplication #142

Merged
merged 3 commits into from
Oct 1, 2022
Merged

Use ComponentLifecycle in HBApplication #142

merged 3 commits into from
Oct 1, 2022

Conversation

slashmo
Copy link
Contributor

@slashmo slashmo commented Sep 27, 2022

In my server applications I usually have two servers running, one for the public API of a service and one for the admin API (e.g. to expose a /metrics route), but I still want them to run in the same process/container. I'd like to be able to use ServiceLifecycle to pull them all together but that's currently not possible since HBApplication creates its own top-level lifecycle. If we were to use ComponentLifecycle instead, an HBApplication and all its lifecycle tasks could be registered as a subcomponent of a larger lifecycle, which could look like this:

let lifecycle = ServiceLifecycle()

let eventLoopGroup = MultiThreadedEventLoopGroup(numberOfThreads: System.coreCount)
lifecycle.registerShutdown(label: "event-loop-group", .async(eventLoopGroup.shutdownGracefully))

let publicApp = HBApplication(
    configuration: .init(
        address: .hostname(options.host, port: Int(options.publicPort)),
        serverName: "Example API",
        logLevel: options.logLevel
    ),
    eventLoopGroupProvider: .shared(eventLoopGroup)
)
lifecycle.register(publicApp.lifecycle)

let adminApp = HBApplication(
    configuration: .init(
        address: .hostname(options.host, port: Int(options.adminPort)),
        serverName: "Example API [Admin]",
        logLevel: options.logLevel
    ),
    eventLoopGroupProvider: .shared(eventLoopGroup)
)
lifecycle.register(adminApp.lifecycle)

try lifecycle.startAndWait()

@codecov
Copy link

codecov bot commented Sep 27, 2022

Codecov Report

Base: 78.15% // Head: 78.15% // No change to project coverage 👍

Coverage data is based on head (092cd48) compared to base (8a117a1).
Patch coverage: 100.00% of modified lines in pull request are covered.

❗ Current head 092cd48 differs from pull request most recent head e93340d. Consider uploading reports for the commit e93340d to get more accurate results

Additional details and impacted files
@@           Coverage Diff           @@
##             main     #142   +/-   ##
=======================================
  Coverage   78.15%   78.15%           
=======================================
  Files          72       72           
  Lines        3094     3094           
=======================================
  Hits         2418     2418           
  Misses        676      676           
Impacted Files Coverage Δ
Sources/Hummingbird/Application.swift 98.30% <100.00%> (ø)

Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.

☔ View full report at Codecov.
📢 Do you have feedback about the report comment? Let us know in this issue.

@adam-fowler
Copy link
Member

LGTM
It is API breaking but I've not committed to a v1.0 yet so not too fussed about that

@adam-fowler
Copy link
Member

One issue, which is an issue with service lifecycle to some degree. ComponentLifecycle on its own does not catch interrupts like Ctrl+C.

@slashmo
Copy link
Contributor Author

slashmo commented Sep 27, 2022

ComponentLifecycle on its own does not catch interrupts like Ctrl+C.
@adam-fowler

Oh, I hadn't realized that. Maybe we could fix it by adding something like a ServiceLifecycleProvider (inspired by NIOEventLoopGroupProvider) which defaults to .createNew, keeping the same behavior as before of creating a full ServiceLifecycle, but has another case .embedded(lifecycle: ServiceLifecycle) which would create a component life cycle and add itself to the given ServiceLifecycle. This could potentially also solve the API breakage if we choose to expose the full lifecycle either way. What do you think?

@adam-fowler
Copy link
Member

Oh, I hadn't realized that. Maybe we could fix it by adding something like a ServiceLifecycleProvider

Yeah that would work. Might as well keep the same terminology as EventLoopGroupProvider which is createNew and shared.

@slashmo
Copy link
Contributor Author

slashmo commented Sep 27, 2022

Agreed, I'll update the PR later today.

Copy link
Member

@adam-fowler adam-fowler left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good.
A couple of minor nits

Sources/Hummingbird/Application.swift Outdated Show resolved Hide resolved
Co-authored-by: Adam Fowler <adamfowler71@gmail.com>
@adam-fowler adam-fowler merged commit fbc2788 into hummingbird-project:main Oct 1, 2022
@slashmo slashmo deleted the feature/component-lifecycle branch October 1, 2022 09:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants