2
2
using System . ComponentModel ;
3
3
using System . Threading ;
4
4
using System . Threading . Tasks ;
5
+ using Microsoft . Extensions . DependencyInjection ;
6
+ using Microsoft . Extensions . Hosting ;
5
7
using Microsoft . Extensions . Logging ;
6
8
using Umbraco . Cms . Core ;
7
9
using Umbraco . Cms . Core . Configuration ;
16
18
using Umbraco . Cms . Web . Common . DependencyInjection ;
17
19
using Umbraco . Extensions ;
18
20
using ComponentCollection = Umbraco . Cms . Core . Composing . ComponentCollection ;
21
+ using IHostingEnvironment = Umbraco . Cms . Core . Hosting . IHostingEnvironment ;
19
22
20
23
namespace Umbraco . Cms . Infrastructure . Runtime
21
24
{
25
+ /// <inheritdoc />
22
26
public class CoreRuntime : IRuntime
23
27
{
24
- private readonly ILogger < CoreRuntime > _logger ;
25
28
private readonly ILoggerFactory _loggerFactory ;
26
29
private readonly ComponentCollection _components ;
27
30
private readonly IApplicationShutdownRegistry _applicationShutdownRegistry ;
@@ -32,14 +35,16 @@ public class CoreRuntime : IRuntime
32
35
private readonly IHostingEnvironment _hostingEnvironment ;
33
36
private readonly IUmbracoVersion _umbracoVersion ;
34
37
private readonly IServiceProvider _serviceProvider ;
38
+ private readonly IHostApplicationLifetime _hostApplicationLifetime ;
39
+ private readonly ILogger < CoreRuntime > _logger ;
35
40
private CancellationToken _cancellationToken ;
36
41
37
42
/// <summary>
38
- /// Initializes a new instance of the <see cref="CoreRuntime"/> class.
43
+ /// Initializes a new instance of the <see cref="CoreRuntime" /> class.
39
44
/// </summary>
40
45
public CoreRuntime (
41
- ILoggerFactory loggerFactory ,
42
46
IRuntimeState state ,
47
+ ILoggerFactory loggerFactory ,
43
48
ComponentCollection components ,
44
49
IApplicationShutdownRegistry applicationShutdownRegistry ,
45
50
IProfilingLogger profilingLogger ,
@@ -48,9 +53,11 @@ public CoreRuntime(
48
53
IEventAggregator eventAggregator ,
49
54
IHostingEnvironment hostingEnvironment ,
50
55
IUmbracoVersion umbracoVersion ,
51
- IServiceProvider serviceProvider )
56
+ IServiceProvider serviceProvider ,
57
+ IHostApplicationLifetime hostApplicationLifetime )
52
58
{
53
59
State = state ;
60
+
54
61
_loggerFactory = loggerFactory ;
55
62
_components = components ;
56
63
_applicationShutdownRegistry = applicationShutdownRegistry ;
@@ -61,6 +68,7 @@ public CoreRuntime(
61
68
_hostingEnvironment = hostingEnvironment ;
62
69
_umbracoVersion = umbracoVersion ;
63
70
_serviceProvider = serviceProvider ;
71
+ _hostApplicationLifetime = hostApplicationLifetime ;
64
72
_logger = _loggerFactory . CreateLogger < CoreRuntime > ( ) ;
65
73
}
66
74
@@ -76,23 +84,49 @@ public CoreRuntime(
76
84
IUmbracoDatabaseFactory databaseFactory ,
77
85
IEventAggregator eventAggregator ,
78
86
IHostingEnvironment hostingEnvironment ,
79
- IUmbracoVersion umbracoVersion
80
- ) : this (
81
- loggerFactory ,
82
- state ,
83
- components ,
84
- applicationShutdownRegistry ,
85
- profilingLogger ,
86
- mainDom ,
87
- databaseFactory ,
88
- eventAggregator ,
89
- hostingEnvironment ,
90
- umbracoVersion ,
91
- null
92
- )
93
- {
87
+ IUmbracoVersion umbracoVersion ,
88
+ IServiceProvider serviceProvider )
89
+ : this (
90
+ state ,
91
+ loggerFactory ,
92
+ components ,
93
+ applicationShutdownRegistry ,
94
+ profilingLogger ,
95
+ mainDom ,
96
+ databaseFactory ,
97
+ eventAggregator ,
98
+ hostingEnvironment ,
99
+ umbracoVersion ,
100
+ serviceProvider ,
101
+ serviceProvider ? . GetRequiredService < IHostApplicationLifetime > ( ) )
102
+ { }
94
103
95
- }
104
+ [ EditorBrowsable ( EditorBrowsableState . Never ) ]
105
+ [ Obsolete ]
106
+ public CoreRuntime (
107
+ ILoggerFactory loggerFactory ,
108
+ IRuntimeState state ,
109
+ ComponentCollection components ,
110
+ IApplicationShutdownRegistry applicationShutdownRegistry ,
111
+ IProfilingLogger profilingLogger ,
112
+ IMainDom mainDom ,
113
+ IUmbracoDatabaseFactory databaseFactory ,
114
+ IEventAggregator eventAggregator ,
115
+ IHostingEnvironment hostingEnvironment ,
116
+ IUmbracoVersion umbracoVersion )
117
+ : this (
118
+ loggerFactory ,
119
+ state ,
120
+ components ,
121
+ applicationShutdownRegistry ,
122
+ profilingLogger ,
123
+ mainDom ,
124
+ databaseFactory ,
125
+ eventAggregator ,
126
+ hostingEnvironment ,
127
+ umbracoVersion ,
128
+ null )
129
+ { }
96
130
97
131
/// <summary>
98
132
/// Gets the state of the Umbraco runtime.
@@ -103,13 +137,17 @@ IUmbracoVersion umbracoVersion
103
137
public async Task RestartAsync ( )
104
138
{
105
139
await StopAsync ( _cancellationToken ) ;
140
+ await _eventAggregator . PublishAsync ( new UmbracoApplicationStoppedNotification ( ) , _cancellationToken ) ;
106
141
await StartAsync ( _cancellationToken ) ;
142
+ await _eventAggregator . PublishAsync ( new UmbracoApplicationStartedNotification ( ) , _cancellationToken ) ;
107
143
}
108
144
109
145
/// <inheritdoc/>
110
146
public async Task StartAsync ( CancellationToken cancellationToken )
111
147
{
148
+ // Store token, so we can re-use this during restart
112
149
_cancellationToken = cancellationToken ;
150
+
113
151
StaticApplicationLogging . Initialize ( _loggerFactory ) ;
114
152
StaticServiceProvider . Instance = _serviceProvider ;
115
153
@@ -130,14 +168,21 @@ public async Task StartAsync(CancellationToken cancellationToken)
130
168
_logger . LogError ( exception , msg ) ;
131
169
} ;
132
170
171
+ // Add application started and stopped notifications (only on initial startup, not restarts)
172
+ if ( _hostApplicationLifetime . ApplicationStarted . IsCancellationRequested == false )
173
+ {
174
+ _hostApplicationLifetime . ApplicationStarted . Register ( ( ) => _eventAggregator . Publish ( new UmbracoApplicationStartedNotification ( ) ) ) ;
175
+ _hostApplicationLifetime . ApplicationStopped . Register ( ( ) => _eventAggregator . Publish ( new UmbracoApplicationStoppedNotification ( ) ) ) ;
176
+ }
177
+
133
178
// acquire the main domain - if this fails then anything that should be registered with MainDom will not operate
134
179
AcquireMainDom ( ) ;
135
180
136
181
// TODO (V10): Remove this obsoleted notification publish.
137
182
await _eventAggregator . PublishAsync ( new UmbracoApplicationMainDomAcquiredNotification ( ) , cancellationToken ) ;
138
183
139
184
// notify for unattended install
140
- await _eventAggregator . PublishAsync ( new RuntimeUnattendedInstallNotification ( ) ) ;
185
+ await _eventAggregator . PublishAsync ( new RuntimeUnattendedInstallNotification ( ) , cancellationToken ) ;
141
186
DetermineRuntimeLevel ( ) ;
142
187
143
188
if ( ! State . UmbracoCanBoot ( ) )
@@ -153,14 +198,15 @@ public async Task StartAsync(CancellationToken cancellationToken)
153
198
154
199
// if level is Run and reason is UpgradeMigrations, that means we need to perform an unattended upgrade
155
200
var unattendedUpgradeNotification = new RuntimeUnattendedUpgradeNotification ( ) ;
156
- await _eventAggregator . PublishAsync ( unattendedUpgradeNotification ) ;
201
+ await _eventAggregator . PublishAsync ( unattendedUpgradeNotification , cancellationToken ) ;
157
202
switch ( unattendedUpgradeNotification . UnattendedUpgradeResult )
158
203
{
159
204
case RuntimeUnattendedUpgradeNotification . UpgradeResult . HasErrors :
160
205
if ( State . BootFailedException == null )
161
206
{
162
207
throw new InvalidOperationException ( $ "Unattended upgrade result was { RuntimeUnattendedUpgradeNotification . UpgradeResult . HasErrors } but no { nameof ( BootFailedException ) } was registered") ;
163
208
}
209
+
164
210
// we cannot continue here, the exception will be rethrown by BootFailedMiddelware
165
211
return ;
166
212
case RuntimeUnattendedUpgradeNotification . UpgradeResult . CoreUpgradeComplete :
0 commit comments