Hi, ich bin noch frisch in der Rails-Entwicklung und habe ein paar Fragen, die Google und Co mir noch nicht beantworten konnten. 1. Caching Ich möchte externe Calls (z.B. zu Twitter) reduzieren und sie für n- Minuten vorhalten. In den standard-Rails-Caching-Methoden habe ich hierfür keine Lösung gefunden (Mem-Cache-Lösung ist nicht möglich). Weshalb ich im Moment in der environement.rb eine Ruby-Cache-Instanz erzeuge und als Konstante definiere, die ich dann in allen Controllern benutzen kann. Ich kann mir einfach nicht vorstellen, dass es hierfür nicht eine "Saubere" Lösung gibt. 2. Monkey-Patching Ich möchte der Array-Klasse eine eigene Sortierungs-Funktion verpassen. Wenn ich meine Gepatchte-Klasse ins Lib-Verzeichnis lege, dann ist die Methode nicht aufrufbar. Ich nehme an, dass ich mich dort irgendwie im Rails-Namespace bewege. Wenn ich die Klasse im environment.rb definiere, dann geht es, allerdings erscheint mir auch dies sehr unsauber. 3. Kontext Gibt es einen "globalen" Anwendungs-Kontext in dem ich Werte definieren kann? So dass ich z.b. im Controller so etwas wie context.put aufrufen kann um einen Wert zu schreiben oder einen Counter zu erhöhen? Wäre schön, wenn ihr mir etwas Feedback hierzu geben könntet. Ahoi
on 2009-06-20 11:43
on 2009-06-20 13:27
On Saturday 20 June 2009, peter schröder wrote: > gefunden (Mem-Cache-Lösung ist nicht möglich). Weshalb ich im Moment > in der environement.rb eine Ruby-Cache-Instanz erzeuge und als > Konstante definiere, die ich dann in allen Controllern benutzen kann. Du könntest einfach Rails.cache verwenden. > 2. Monkey-Patching > > Ich möchte der Array-Klasse eine eigene Sortierungs-Funktion > verpassen. Wenn ich meine Gepatchte-Klasse ins Lib-Verzeichnis lege, > dann ist die Methode nicht aufrufbar. Ich nehme an, dass ich mich > dort irgendwie im Rails-Namespace bewege. > Wenn ich die Klasse im environment.rb definiere, dann geht es, > allerdings erscheint mir auch dies sehr unsauber. Ich bin nicht sicher, aber ich glaube, du bist auf dem falschen Weg. Wozu brauchst du eine eigene Sortiermethode? Hast du schon einen Blick auf Array#sort_by geworfen? Geht es darum, Objekte zu sortieren, die aus der Datenbank kommen? Dann ist vermutlich eine :order-Option an "geeigneter" Stelle der richtige Ansatz. In environment.rb solltest du nichts definieren, dafür gibt es Initializer in config/initializers. > 3. Kontext > > Gibt es einen "globalen" Anwendungs-Kontext in dem ich Werte > definieren kann? So dass ich z.b. im Controller so etwas wie > context.put aufrufen kann um einen Wert zu schreiben oder einen > Counter zu erhöhen? Nein, gibt es nicht und kann es, ohne zusätzlichen Aufwand, nicht geben. Die Anwendungsarchitektur (Stichwort: "shared nothing") von Rails sieht vor, dass jeder Request von einem einzelnen Prozess verarbeitet wird und umgekehrt jeder Prozess nur an einem Request zur Zeit arbeitet. Um gleichzeitig mehrere Requests verarbeiten zu können, sind also mehrere Rails-Prozesse nötig, die jeweils gegeneinander isoliert sind. Wenn du nun einen gemeinsamen Kontext brauchst, bedeutet das, dass du eine Ressource in der Architektur etablierst, die von mehreren Rails- Prozessen geteilt wird. Zugriffe auf eine solche Ressource müssen synchronisiert werden und sie ist ein (weiterer, neben der Datenbank) Flaschenhals und Fehlerpunkt. Was natürlich nichts daran ändert, dass die Funktionalität oft trotzdem gebraucht wird. Memcached ist genau dafür ein Beispiel. Michael -- Michael Schuerig mailto:michael@schuerig.de http://www.schuerig.de/michael/
on 2009-06-20 16:03
Am 20.06.2009 um 11:42 schrieb peter schröder: > > 2. Monkey-Patching > > Ich möchte der Array-Klasse eine eigene Sortierungs-Funktion > verpassen. Wenn ich meine Gepatchte-Klasse ins Lib-Verzeichnis lege, > dann ist die Methode nicht aufrufbar. Ich nehme an, dass ich mich > dort irgendwie im Rails-Namespace bewege. > Wenn ich die Klasse im environment.rb definiere, dann geht es, > allerdings erscheint mir auch dies sehr unsauber. wenn du lib/array_monkey.rb hast dann musst du im environment.rb noch require 'array_monkey' machen. Die Dateien und Klassen im lib verzeichnis stehen nicht automatisch zur Verfügung. ciao, tom -- Thomas R. "TomK32" Koll || http://tomk32.de || http://ananasblau.com just a geek trying to change the world Skype: TomK32 || Mail: tomk32@gmx.de http://flickr.com/people/tomk32
on 2009-06-20 17:25
Hi Peter, > Ich kann mir einfach nicht vorstellen, dass es hierfür nicht eine > "Saubere" Lösung gibt. Die anderen Cache-Backends in Rails unterstützen AFAIK tatsächlich keine expiry. Hier ein Backend, dass das könnte (gerade eben schnell gehackt, nur als "proof of concept" gedacht) http://gist.github.com/133179 Um es zu verwenden in environment.rb config.cache_store = :memory_store_with_expiry setzen. Aber ... willst Du die Applikation später deployen und (ein bischen) skalieren? Wenn ja wirst Du einen Cache brauchen auf den von mehreren Prozessen aus zugegriffen werden kann. Egal ob deployment via Mongrel Cluster oder mod_passenger. D.h. MemCache oder FileStore. > 2. Monkey-Patching > > Ich möchte der Array-Klasse eine eigene Sortierungs-Funktion > verpassen. Wenn ich meine Gepatchte-Klasse ins Lib-Verzeichnis lege, > dann ist die Methode nicht aufrufbar. Ich nehme an, dass ich mich > dort irgendwie im Rails-Namespace bewege. Nee, das ist nicht das Problem. > Wenn ich die Klasse im environment.rb definiere, dann geht es, > allerdings erscheint mir auch dies sehr unsauber. Du hast einen Sonderfall erwischt ;-) Der Code in lib wird von Rails nicht sofort geladen, sondern das Verzeichnis wird nur dem load path hinzugefügt. Die Klassen werden also erst geladen, wenn sie das erste mal im Code verwendet werden. Das funktioniert bei noch nicht definierten Klassen wunderbar. Aber nachdem die Array-Klasse schon bekannt ist, schaut Rails nicht in dem Verzeichnis nach und Dein Code wird nicht geladen :-( Das Problem kannst Du z.B. lösen, indem Du den Code in einer Datei array_ext.rb im Verzeichnis config/initializers ablegst. Dann wird er schon beim Start der App geladen. > 3. Kontext > > Gibt es einen "globalen" Anwendungs-Kontext in dem ich Werte > definieren kann? So dass ich z.b. im Controller so etwas wie > context.put aufrufen kann um einen Wert zu schreiben oder einen > Counter zu erhöhen? Was genau sind das für Werte? Globale Konfiguration? Wieder Cache? Wenn sie irgendwie zur Domäne gehören würde ich sie auf bestehenden oder auch neuen Models ablegen. Wenn sie nicht zur Domänge gehören: Eine simple Lösung für einen globalen Store wäre ein OpenStruct zu verwenden. Folgende 2 Zeilen unter lib/context.rb ablegen: require 'ostruct' Context = OpenStruct.new test in script/console: >> Context.foo = 'Bar' => "Bar" >> Context.foo => "Bar" Wenns noch Fragen gibt würdes uns sicher helfen, wenn Du die konkreten Probleme beschreibst ... dann muss man nicht so viel mutmaßen ;-) Hope this helps, Phillip
on 2009-06-22 05:23
Hi, vielen Dank für eure Antworten. Genau diese Informationen haben mir gefehlt! Leider hatte ich die E-Mail-Sammelfunktion der Mailing-List aktiviert, deshalb kann ich nicht auf die einzelnen Antworten zurückschreiben... Für mich wichtige Punkte liste ich hier noch mal auf: > Die Anwendungsarchitektur (Stichwort: "shared nothing") von Rails > sieht > vor, dass jeder Request von einem einzelnen Prozess verarbeitet wird > und > umgekehrt jeder Prozess nur an einem Request zur Zeit arbeitet. Dies wird sicherlich noch eine inressanter Aspekt wenn meine Anwendung unter JRuby in einem Application-Container läuft. > Du hast einen Sonderfall erwischt ;-) Der Code in lib wird von Rails > nicht sofort geladen, sondern das Verzeichnis wird nur dem load path > hinzugefügt. Die Klassen werden also erst geladen, wenn sie das erste > mal im Code verwendet werden. > Das erscheint mir logisch, ich hab allerdings keine Erklärung dafür in der Doku gesehen. > > Das Problem kannst Du z.B. lösen, indem Du den Code in einer Datei > array_ext.rb im Verzeichnis config/initializers ablegst. Dann wird er > schon beim Start der App geladen. Hört sich gut an, werde ich ausprobieren. > Wenn sie nicht zur Domänge gehören: Eine simple Lösung für einen > globalen Store wäre ein OpenStruct zu verwenden. Folgende 2 Zeilen > unter lib/context.rb ablegen: Danke für das Beispiel, soetwas habe ich gesucht, da meine Anwendung komplett ohne DB auskommen soll. Es werden lediglich externe APIs genutzt (Twitter, Google, Amazon). Vielen Dank! Am 21.06.2009 um 12:00 schrieb rubyonrails-ug-request@headflash.com:
on 2009-06-22 06:01
On Jun 21, 2009, at 12:20 PM, peter schröder wrote: > Danke für das Beispiel, soetwas habe ich gesucht, da meine Anwendung > komplett ohne DB auskommen soll. Es werden lediglich externe APIs > genutzt (Twitter, Google, Amazon). … wobei ich mich in diesem Fall fragen würde, ob Rails die richtige Wahl ist und nicht vielleicht z.B. Sinatra eine bessere wäre. Stefan -- Stefan Tilkov, http://www.innoq.com/blog/st/
on 2009-06-22 06:14
wenn man erfahrungen mit rails sammeln will, dann sicherlich nicht. ich weiß, dass rails von grund auf sehr datenbank getrieben ist. trotzdem konnte ich mit meinem kleinen projekt schon sehr viele dinge für mich herausziehen und habe etwas gefühl für die arbeit mit rails bekommen. wenn es jemanden interessiert: http://www.phoet.de/ als nächstes möchte ich mich noch intensiv mit den test-möglichkeiten von rails beschäftigen. in der nächsten iteration will ich dann noch einige teile mit jquery dynamisch laden. in einem letzten schritt dann evtl. noch ein wenig mit models und der anbindung einer datenbank arbeiten. Am 21.06.2009 um 12:57 schrieb Stefan Tilkov:
Please log in before posting. Registration is free and takes only a minute.
Existing account
(Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
Log in with Google account | Log in with Yahoo account
No account? Register here.