You can use
RAILS_DEFAULT_LOGGER.log "foobar" # or Rails.logger.log "blah"
outside a controller for logging.
You can use
RAILS_DEFAULT_LOGGER.log "foobar" # or Rails.logger.log "blah"
outside a controller for logging.
The last Passenger update brought some good explanation off the problems regarding Passenger and memcache-client (see here).
Smart spawning of Passenger processes creates shared file descriptors. As the connections to memcached are sockets they are shared as well so data on them gets corrupted which is explained very nicely in the Passenger documentation: Example 1: Memcached connection sharing (harmful).
The solution presented there works like a charm. The reestablish_connection_to_memcached line is actually not more than CACHE.reset where CACHE is the reference to the memcache connection.
After that change, spawning methods smart-lv2 and smart will work in connection with environment.rb configured memcache connections.
Edit: As requested in the comments, a little example:
memcache_options = { :c_threshold => 10000, :compression => true, :debug => false, :namespace => 'some_ns', :readonly => false, :urlencode => false } CACHE = MemCache.new memcache_options CACHE.servers = '127.0.0.1:11211' begin PhusionPassenger.on_event(:starting_worker_process) do |forked| if forked # We're in smart spawning mode, so... # Close duplicated memcached connections - they will open themselves CACHE.reset end end # In case you're not running under Passenger (i.e. devmode with mongrel) rescue NameError => error end
In this case, CACHE is the global constant that i use to access my memcache-client.
I guess you’ll need to do the same with the global Rails.cache object, but i’m not sure. Anyway, the above solution works for me.
I recently switch from a mod_proxy / thin setup to Phusion Passenger and my application started to do the funniest things and the production.log was full with errors related to memcached.
It seems, that passengers spawn method “smart” isn’t compatible with memcached. Within seconds on a lightly loaded server the cache gets corrupted big time.
I got better results with a newer memcache client (the ruby gem actually), but for that i need to remove the client from the rails vendor lib. Furthermore, under higher load there still where errors.
Only solution is to set the spawn method to conservative like so
RailsSpawnMethod conservative
Problem seems to be known in the Phusion and Rails teams.
What can cause this snippet to fail:
<% if !@day.user.is_rateable? # Workaround für Darstellungsfehler mit Tabellen ohne Bodies im Safari %> <!-- blah --> <% end %>
This little snippet fell apart today. I don’t know if it is passenger, a newer ruby version, RubyInline. All i know is that i am so totally pissed of this incredible amount of incompatible versions of just 3 modules that i literally feel like puking. What a hell of a day.
By the way, the thing that broke was the one-line comment right after the if.
Ruby on Rails I18n infrastructure did a great job to internationalization in Rails applications. Most things work right out of the box.
Daily Fratze is fully internationalized and i wanted to use ordinal day numbers in the English version. Pity, there is no template for strftime that works that way.
As i already hat monkey patched a “t” method to all date and time related classes, i came up with the following solution:
Parallel to “en.yml” i now have “en.rb” in my locales folder which gets loaded in environment.rb via
config.i18n.load_path += Dir[File.join(RAILS_ROOT, 'app', 'locales', '*.{yml,rb}')]
The en.rb files defines some procs as translation values like so:
{ :'en' => { :date => { :formats => { :dmy_with_long_month => lambda { |date| "%B #{date.day.ordinalize}, %Y" }, } }, :time => { :formats => { :dmy_with_long_month => lambda { |date| "%B #{date.day.ordinalize}, %Y" }, :dmy_with_full_day_and_long_month_and_time => lambda { |date| "%A, %B #{date.day.ordinalize}, %Y at %H:%M" } } } } }
Used with the standard I18n tools you’ll end up with the string representation of the proc object. Useless
So time for monkeypatching like so:
module DateTimeSupport def t(format = nil) type = self.respond_to?(:sec) ? 'time' : 'date' formats = I18n.translate(:"#{type}.formats") format = formats[format.to_sym] if formats && formats[format.to_sym] I18n.localize(self, :format => format.respond_to?(:call) ? format.call(self) : format) end end class Time include DateTimeSupport end class Date include DateTimeSupport end class DateTime include DateTimeSupport end class ActiveSupport::TimeWithZone include DateTimeSupport end
Code resides in a file in config/initializers and gets loaded automatically. It adds a t method to all date and time related classes. The method tries to look up the translation of format just like I18n/Simple does.
If it is proc, it gets called and then passed to I18n, otherwise it the original parameter is used.
That way the t method can use “dmy_with_long_month”, :dmy_with_long_month and any other arbitrary format like “%B %Y” that is not defined in any language file.