Skip to content

Add IAsyncComponent to allow async initialize/terminate#16536

Merged
bergmania merged 4 commits intov15/devfrom
v14/feature/asynccomposer
Sep 23, 2024
Merged

Add IAsyncComponent to allow async initialize/terminate#16536
bergmania merged 4 commits intov15/devfrom
v14/feature/asynccomposer

Conversation

@ronaldbarendse
Copy link
Copy Markdown
Contributor

Prerequisites

  • I have added steps to test this contribution in the description below

Description

As mentioned in #16430 (comment), it's currently not possible to (correctly) use async methods in components. This adds IAsyncComponent and refactors the code to call the InitializeAsync()/TerminateAsync() methods instead, which does mean a breaking change in the ComponentCollection (the item type and methods have changed). I did make IComponent inherit from IAsyncComponent and added default interface methods, so any existing (synchronous) components are still backwards compatible.

I've also added 2 base classes to make usage easier:

  • AsyncComponentBase - this only initializes/terminates when the application isn't restarting (aka the actual start/stop of the application) and implements a no-op TerminateAsync() method (as most implementations only require initialization);
  • RuntimeAsyncComponentBase - inheriting from AsyncComponentBase and also takes the runtime level into account, so it only initializes/terminates when the application is running normally.

I'll add some example components to help test later...

@ronaldbarendse ronaldbarendse changed the base branch from contrib to v15/dev September 9, 2024 11:28
@ronaldbarendse ronaldbarendse added category/breaking status/needs-docs Requires new or updated documentation labels Sep 9, 2024
@bergmania
Copy link
Copy Markdown
Member

Hi @ronaldbarendse..

Why use components at all? IMO it is a legacy thing, that we should instead obsolete, instead of make more of.

I guess you can archive the same with (async) notification handlers of :

  • UmbracoApplicationStartingNotification (executes same time as component.Initialize())
  • UmbracoApplicationStoppingNotification (executes same time as components.Terminate())

@ronaldbarendse
Copy link
Copy Markdown
Contributor Author

Why use components at all? IMO it is a legacy thing, that we should instead obsolete, instead of make more of.

I guess you can archive the same with (async) notification handlers of :

  • UmbracoApplicationStartingNotification (executes same time as component.Initialize())
  • UmbracoApplicationStoppingNotification (executes same time as components.Terminate())

There are some minor, but very specific things that components allow that can't be (easily) replicated with notifications:

  • Components are explicitly registered in an ordered collection, so you can ensure certain logic is done before/after another component or easily replace existing component registrations (which can be further influenced by ordering the composers);
  • The order of initialization and termination is also always deterministic (termination is done in reverse order of initialization);
  • Components are initialized once at startup, so they can store state between initialization and termination. Notification handlers are initialized each time a notification is published and therefore don't allow storing state between notifications (even if you implement multiple notification handlers on the same type);
  • Components can implement IDisposable (and/or IAsyncDisposable), which is currently also manually called when restarting, but will be automatically called when the application stops.

@bergmania bergmania merged commit cf6137d into v15/dev Sep 23, 2024
@bergmania bergmania deleted the v14/feature/asynccomposer branch September 23, 2024 07:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

category/breaking release/15.0.0 status/needs-docs Requires new or updated documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants