Entwicklung & Design

Die Grundlagen der Cache-Mechanismen: Caching in Ruby on Rails

Seite 6 / 7

Die Invalidierung wiederum funktioniert genauso wie bei den anderen Cache-Arten – so wie in Listing 9 zu sehen.

RUBY
def update
		[...]
		expire_fragment :controller => 'mein', :action => 'list', :part => 'books'
	[...]
	end

Listing 9

Der aufmerksame Leser wird sich bei dem in Listing 8 angegebenen Code allerdings eine Frage stellen: Woher kommt eigentlich die Liste der Bücher in @books? Die Antwort ist: aus dem Controller, wie üblich. Allerdings ist es nicht sinnvoll, die Liste durch den Controller wahllos aus der Datenbank zu zerren, denn dann wäre das Caching ja vermutlich überflüssig. In der Regel ist schließlich nicht das Rendern der HTML-Seite langsam, sondern die Datenbankabfrage. Es gilt also, eine Methode zu finden, die das Kapseln und die Abfrage nur dann ausführt, wenn man die Daten braucht. Eine oft genannte Variante dazu finden Sie in Listing 10. Dort wird im Controller nachgesehen, ob ein Fragment bereits vorhanden ist und die Abfrage gegebenenfalls unterbunden.

RUBY
def list
		unless read_fragment(:controller => 'meiner', :action => 'list', :part => 'books')
			@books = Book.find(:all)
		end
	end

Listing 10

In 99 Prozent der Fälle wird das Vorgehen funktionieren. Liegt allerdings viel Last auf der Applikation und die Seite wird sehr oft aufgerufen, kommt es unter Umständen zu einer unangenehmen Race Condition: Der Controller hat beschlossen, die Daten für das Fragment nicht zu besorgen, weil ein Fragment vorhanden war. Während anschließend der Rails-Prozess den View rendert, hat ein Administrator auf einem anderen Rails-Prozess beschlossen, ein Buch in der Datenbank zu löschen, was einen Observer anspringen lässt, der das Fragment löscht. Wird jetzt der View-Teil gerendert, der die „cache do…end“-Anweisung enthält, wird der Block ausgeführt und nicht das nicht mehr vorhandene Cache-Fragment ausgeliefert. Nun ist die benötigte @books-Instanzvariabel leer. Bei einem sehr defensiv programmierten View bleibt der Block leer, was (nur) unschön ist, während bei einem „normal“ programmierten View dem Benutzer eine weniger schöne 500er-Fehlermeldung entgegenspringt.

Pragmatismus über Prinzipien

Ganz genau genommen, muss die Abfrage der Daten innerhalb des Cache-Blocks erfolgen, doch heißt das nicht, dass nun ActiveRecord-Methoden im View aufgerufen werden. Einerseits handelt es sich beim Caching um Maßnahmen, auf die nur im Notfall zurückgegriffen wird, und dementsprechend ist Pragmatismus statt Paragraphenreiterei gefragt. Andererseits ist es dennoch sinnvoll, das Holen der Daten wenigstens in einen „Helper“ zu verpacken, wie es Listing 11 und 12 zeigen:

Bitte beachte unsere Community-Richtlinien

Wir freuen uns über kontroverse Diskussionen, die gerne auch mal hitzig geführt werden dürfen. Beleidigende, grob anstößige, rassistische und strafrechtlich relevante Äußerungen und Beiträge tolerieren wir nicht. Bitte achte darauf, dass du keine Texte veröffentlichst, für die du keine ausdrückliche Erlaubnis des Urhebers hast. Ebenfalls nicht erlaubt ist der Missbrauch der Webangebote unter t3n.de als Werbeplattform. Die Nennung von Produktnamen, Herstellern, Dienstleistern und Websites ist nur dann zulässig, wenn damit nicht vorrangig der Zweck der Werbung verfolgt wird. Wir behalten uns vor, Beiträge, die diese Regeln verletzen, zu löschen und Accounts zeitweilig oder auf Dauer zu sperren.

Trotz all dieser notwendigen Regeln: Diskutiere kontrovers, sage anderen deine Meinung, trage mit weiterführenden Informationen zum Wissensaustausch bei, aber bleibe dabei fair und respektiere die Meinung anderer. Wir wünschen Dir viel Spaß mit den Webangeboten von t3n und freuen uns auf spannende Beiträge.

Dein t3n-Team

Schreib den ersten Kommentar!