6
6
using Umbraco . Core ;
7
7
using Umbraco . Core . Events ;
8
8
using Umbraco . Core . Logging ;
9
+ using Umbraco . Core . Models ;
10
+ using Umbraco . Core . Services ;
11
+ using Umbraco . Core . Services . Changes ;
9
12
10
13
namespace Umbraco . Web . Cache
11
14
{
@@ -66,10 +69,9 @@ public void HandleEvents(IEnumerable<IEventDefinition> events)
66
69
using ( _umbracoContextFactory . EnsureUmbracoContext ( ) )
67
70
{
68
71
// When it comes to content types types, a change to any single one will trigger a reload of the content and media caches.
69
- // As far as I (AB) can tell, there's no type specific logic here, they all clear caches for all content types, and trigger a reload of all content and media.
70
- // We also have events registered for Changed and Saved, which do the same thing, so really only need one of these.
71
- // Hence if we have more than one document or media types, we can and should only handle one of the events for one, to avoid repeated cache reloads.
72
- foreach ( var e in GetReducedEventList ( events ) )
72
+ // We can reduce the impact of that by grouping the events to invoke just one per type, providing a collection of the individual arguments.
73
+ var groupedEvents = GetGroupedEventList ( events ) ;
74
+ foreach ( var e in groupedEvents )
73
75
{
74
76
var handler = FindHandler ( e ) ;
75
77
if ( handler == null )
@@ -86,47 +88,77 @@ public void HandleEvents(IEnumerable<IEventDefinition> events)
86
88
}
87
89
88
90
// Internal for tests
89
- internal static IEnumerable < IEventDefinition > GetReducedEventList ( IEnumerable < IEventDefinition > events )
91
+ internal static IEnumerable < IEventDefinition > GetGroupedEventList ( IEnumerable < IEventDefinition > events )
90
92
{
91
- var reducedEvents = new List < IEventDefinition > ( ) ;
93
+ var groupedEvents = new List < IEventDefinition > ( ) ;
92
94
93
- var gotDoumentType = false ;
94
- var gotMediaType = false ;
95
- var gotMemberType = false ;
95
+ var grouped = events . GroupBy ( x => x . GetType ( ) ) ;
96
96
97
- foreach ( var evt in events )
97
+ foreach ( var group in grouped )
98
98
{
99
- if ( evt . Sender . ToString ( ) . Contains ( nameof ( Core . Services . Implement . ContentTypeService ) ) )
99
+ if ( group . Key == typeof ( EventDefinition < IContentTypeService , SaveEventArgs < IContentType > > ) )
100
100
{
101
- if ( gotDoumentType == false )
102
- {
103
- reducedEvents . Add ( evt ) ;
104
- gotDoumentType = true ;
105
- }
101
+ GroupSaveEvents < IContentTypeService , IContentType > ( groupedEvents , group ) ;
106
102
}
107
- else if ( evt . Sender . ToString ( ) . Contains ( nameof ( Core . Services . Implement . MediaTypeService ) ) )
103
+ else if ( group . Key == typeof ( EventDefinition < IContentTypeService , ContentTypeChange < IContentType > . EventArgs > ) )
108
104
{
109
- if ( gotMediaType == false )
110
- {
111
- reducedEvents . Add ( evt ) ;
112
- gotMediaType = true ;
113
- }
105
+ GroupChangeEvents < IContentTypeService , IContentType > ( groupedEvents , group ) ;
114
106
}
115
- else if ( evt . Sender . ToString ( ) . Contains ( nameof ( Core . Services . Implement . MemberTypeService ) ) )
107
+ else if ( group . Key == typeof ( EventDefinition < IMediaTypeService , SaveEventArgs < IMediaType > > ) )
116
108
{
117
- if ( gotMemberType == false )
118
- {
119
- reducedEvents . Add ( evt ) ;
120
- gotMemberType = true ;
121
- }
109
+ GroupSaveEvents < IMediaTypeService , IMediaType > ( groupedEvents , group ) ;
110
+ }
111
+ else if ( group . Key == typeof ( EventDefinition < IMediaTypeService , ContentTypeChange < IMediaType > . EventArgs > ) )
112
+ {
113
+ GroupChangeEvents < IMediaTypeService , IMediaType > ( groupedEvents , group ) ;
114
+ }
115
+ else if ( group . Key == typeof ( EventDefinition < IMemberTypeService , SaveEventArgs < IMemberType > > ) )
116
+ {
117
+ GroupSaveEvents < IMemberTypeService , IMemberType > ( groupedEvents , group ) ;
118
+ }
119
+ else if ( group . Key == typeof ( EventDefinition < IMemberTypeService , ContentTypeChange < IMemberType > . EventArgs > ) )
120
+ {
121
+ GroupChangeEvents < IMemberTypeService , IMemberType > ( groupedEvents , group ) ;
122
122
}
123
123
else
124
124
{
125
- reducedEvents . Add ( evt ) ;
125
+ groupedEvents . AddRange ( group ) ;
126
126
}
127
127
}
128
128
129
- return reducedEvents ;
129
+ return groupedEvents ;
130
+ }
131
+
132
+ private static void GroupSaveEvents < TService , TType > ( List < IEventDefinition > groupedEvents , IGrouping < Type , IEventDefinition > group )
133
+ where TService : IContentTypeBaseService
134
+ where TType : IContentTypeBase
135
+ {
136
+ var groupedGroups = group . GroupBy ( x => ( x . EventName , x . Sender ) ) ;
137
+
138
+ foreach ( var groupedGroup in groupedGroups )
139
+ {
140
+ groupedEvents . Add ( new EventDefinition < TService , SaveEventArgs < TType > > (
141
+ null ,
142
+ ( TService ) groupedGroup . Key . Sender ,
143
+ new SaveEventArgs < TType > ( groupedGroup . SelectMany ( x => ( ( SaveEventArgs < TType > ) x . Args ) . SavedEntities ) ) ,
144
+ groupedGroup . Key . EventName ) ) ;
145
+ }
146
+ }
147
+
148
+ private static void GroupChangeEvents < TService , TType > ( List < IEventDefinition > groupedEvents , IGrouping < Type , IEventDefinition > group )
149
+ where TService : IContentTypeBaseService
150
+ where TType : class , IContentTypeComposition
151
+ {
152
+ var groupedGroups = group . GroupBy ( x => ( x . EventName , x . Sender ) ) ;
153
+
154
+ foreach ( var groupedGroup in groupedGroups )
155
+ {
156
+ groupedEvents . Add ( new EventDefinition < TService , ContentTypeChange < TType > . EventArgs > (
157
+ null ,
158
+ ( TService ) groupedGroup . Key . Sender ,
159
+ new ContentTypeChange < TType > . EventArgs ( groupedGroup . SelectMany ( x => ( ( ContentTypeChange < TType > . EventArgs ) x . Args ) . Changes ) ) ,
160
+ groupedGroup . Key . EventName ) ) ;
161
+ }
130
162
}
131
163
}
132
164
}
0 commit comments