Umbraco ma w sobie system cachowania contentu. Co jednak,
gdybyśmy chcieli pójść o krok dalej i zrobili cachowanie jeszcze wcześniej? Po
co w ogóle się tym przejmować? O tym w dzisiejszym poście.
Sprawdźmy więc definicję. Czym właściwie jest Cache?
„Pamięć podręczna (ang. cache) – mechanizm, w którym część
spośród danych zgromadzonych w źródłach o długim czasie dostępu i niższej
przepustowości jest dodatkowo przechowywana w pamięci o lepszych parametrach.
Ma to na celu poprawę szybkości dostępu do tych informacji, które
przypuszczalnie będą potrzebne w najbliższej przyszłości.”
Źródło Wikipedia
W stronach takich jak WebDotNet, czy innych, w których
content nie zmienia się dynamicznie, warto zastanowić się nad cachowaniem
wyników, całych requestów. Zdecydowałem
się na zastosowanie „Donut Output Cache”, który jest inspirowany standardowym w
MVC Output Cachem. Oto krótki poradnik jak możesz zastosować go w swoim
projekcie MVC/Umbraco.
Instalujemy nuget package „MvcDonutCaching”. Cachowanie za
pomocą tej biblioteki polega na zapisywaniu w pamięci całych zwrotów z metod
Controllerów. W aplikacji WebDotNet mam
jak na razie dwa Controllery. Pierwszy odpowiedzialny za requesty o posty, a
drugi o „normalne” strony z sekcjami. Aby dodać akcję do cachowania, należy
dodać atrybut do metody. Przy zwykłym projekcie MVC możemy pokusić się o coś
bardzo prostego jak np.:
[DonutOutputCache(Duration = "300")]
Wartość zwracana zostanie w tym przypadku zapisana w pamięci
na 300 sekund. Jeżeli w przeciągu tego czasu ktoś ponownie odpyta tę metodę, zwrócona
zostanie wartość z pamięci, a kod z metody zostanie pominięty. W ten sposób
możemy zaoszczędzić sporo czasu gdy np. nasza metoda odpytuje dodatkowo bazę
danych i wykorzystuje jakiś algorytm do wyliczenia danych, które zwraca.
W moim przypadku musiałem pójść o krok dalej, jako że metoda
Index jest wykonywana przy renderowaniu każdej strony na platformie. Musiałem
więc wykorzystać dostosowany do moich potrzeb profil cachowania. Atrybut przy
takim podejściu wygląda tak:
[DonutOutputCache(CacheProfile = "Page.Cache")]
Profil jest zdefiniowany w Web.configu aplikacji:
Definiujemy tu nasz profil, czas przechowywania w pamięci
oraz opcjonalną (a w moim przypadku wymaganą) dedykowaną klasę, która zajmie
się kreacją kluczy do cacha. Zdecydowałem się, że kluczem dla moich elementów w
pamięci będzie URL strony, gdyż jest to wartość unikalna.
public class WebdotnetApplication : UmbracoApplication { public override string GetVaryByCustomString(HttpContext context, string custom) { if (custom.Equals("Page.Cache")) { return context.Request.Url.AbsoluteUri; } return base.GetVaryByCustomString(context, custom); } }
Aby dedykowany kreator kluczy działał, musimy zrobić jeszcze
jedną rzecz. Sprawić, by dziedziczył po naszej startowej klasie, która jest
zdefiniowana w Global.asax. Przeciążyć metodę
„GetVaryByCustomString” i w pliku Global zmienić bieżącą klasę na naszą
klasę dziedziczącą po poprzedniej, aby zachować ówczesną funkcjonalność.
<%@ Application Inherits="Webdotnet.Custom.Core.WebdotnetApplication" Language="C#" %>
To by było na tyle, jeżeli chodzi o dodawanie elementów.
Używając Umbraco chcemy jednak, by przy wszelkich zmianach w contencie pamięć
podręczna została wyczyszczona (a przynajmniej pozycja pod zmienianym kluczem
została usunięta). Pozostało nam jeszcze podpięcie się pod Eventy umbraco. Aby
to zrobić, należy stworzyć klasę, która dziedziczy po „ApplicationEventHandler”
i nadpisać metodę „ApplicationStarted”. W ciele tej metody należy podpiąć się
pod eventy zmiany/dodawania/usuwania itp. i dodać metody modyfikujące zawartość
cacha, w moim przypadku usuwające jego zawartość.
public class UmbracoEventHandler : ApplicationEventHandler { protected override void ApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext) { ContentService.Published += UmbracoContentChangeHandler.OnPublished; ContentService.Created += UmbracoContentChangeHandler.OnCreated; ContentService.Saved += UmbracoContentChangeHandler.OnSaved; ContentService.Published += UmbracoContentChangeHandler.OnPublished; ContentService.UnPublished += UmbracoContentChangeHandler.OnUnpublished; ContentService.Moved += UmbracoContentChangeHandler.OnMoved; ContentService.Trashed += UmbracoContentChangeHandler.OnTrashed; ContentService.Deleted += UmbracoContentChangeHandler.OnDeleted; } }
W każdej z tych metod wywołuję usuwanie elementów z cacha,
kod tej metody wygląda następująco:
private static void RemoveItemsFromCache() { var cacheManager = new OutputCacheManager(); cacheManager.RemoveItems(); }
I to by było wszystko. W tym momencie będziemy już mieli
działającego cacha wraz z usuwaniem jego elementów przy zmianach w contencie
aplikacji.
To już wszystko na dziś, pozdrawiam Kamil.
Brak komentarzy:
Prześlij komentarz