welcome to the list :)
On 26.08.2009, at 18:33, dylanz wrote:
> 1. If I had to lookup :"number.format", I wouldn't necessarily know
> that it requires a Hash as a return value, unless I had some sort of
> tree in the database, where all the children of "number.format" had
> entries that "number.format" was their parent.
IIRC the shipped AR backend does that without an explicit tree/
hierarchie db model:
It basically joins the key to "foo.bar.baz" and then looks for records
that either have exactly that key or start with that key with the
separator following.
Then you can look at the result set and either returns a single value
or Hash from it.
> So... would backends
> need to adhere to a fall-through of supporting YAML/File if their
> backend didn't return the correct value...
That's an option. You could use the Chain backend to put an AR backend
in front of the default Simple backend. The Simple backend could
provide all the default Rails translations, while your translators
could work on the app translations using the AR backend.
> or, (I'm assuming) would
> backends need to support tree/hierarchy lookups like this?
I'm not sure you need that. Maybe we're still missing something with
the shipped implementation (there hasn't been much feedback). But in
theory it should do what you need.
> 2. I noticed the "active_record" and "active_record2" branches.
> -> What are the differences between the two?
Interesting question :) Looking at the commit history there might not
be any difference. Maybe I just forgot to delete active_record2
> -> Are either in use in any production environments?
I don't know of any.
> -> How are they going to limit the database lookups on heavily
> translated pages?
You can put the Cache module in front of it. It uses
ActiveSupport::Cache, so it gives you a bunch of options.
Beware that the Cache module does not (yet) take care of any cache
expiration that probably will be necessary for your use case. Please
let me know if there are any issues with this.
Thanks :)
Sven
http://github.com/svenfuchs/i18n/blob/df498763cd1968c58900d66a322325d9db8b0d06/lib/i18n/backend/active_record/translation.rb#L18In regard to that Hash/Key lookup, that's a great idea, but I don't think it would work very well if you wanted to put a Cache store in front... as you would be doing wildcard lookups.
So without the Cache in front, I think the ActiveRecord Backend would be pretty expensive, in terms of IO/CPU. For example, on an initial request to our application (without a warm cache store), it fires off 100's of database requests to get the translation records, and set them in the cache.
Granted they are all pretty quick requests, it's still a pretty hefty hit to the database, and I don't think anything you'd want to do on a heavily trafficked site, on every request. (I think that Globalize2 uses an in-memory Cache as a intermediate layer, but I think you'd still run into consistency issues if you were using an array of machines.) Throwing a distributed Cache layer like Memcached in between is great, as even thought you're still doing 100's of cache requests per request, they are much, much cheaper.
On 26.08.2009, at 21:35, dylanz wrote:
>> It basically joins the key to "foo.bar.baz" and then looks for
>> records
>> that either have exactly that key or start with that key with the
>> separator following.
>> http://github.com/svenfuchs/i18n/blob/df498763cd1968c58900d66a322325d9db8b0d06/lib/i18n/backend/active_record/translation.rb#L18
>
> In regard to that Hash/Key lookup, that's a great idea, but I don't
> think it would work very well if you wanted to put a Cache store in
> front... as you would be doing wildcard lookups. For what it's worth,
> those are extremely slow in Memcached, and Memcached doesn't support
> delete's via wildcard, so that operation would be much, much slower.
Maybe I'm missing something but I don't see a problem here. The Cache
just assumes that the backend is idempotent in that sense that for a
given set of arguments it always returns the same value. The arguments
can then be used as a cache key. When the backend returns a Hash of
translations for a given key then the Cache caches that. Same when the
backend just returns a single translation. Also, the Cache is done so
that when the backend raises an (e.g. translation missing) exception
for a given key, then the Cache will do the same.
> Cool, and no problem! Since they are simple translations, we don't
> really want to expire them. We can just remove the I18n.t() tag from
> the text if we don't need the text translated, delete the key, or,
> just update the value if the translation value needs to change. This
> way, we don't need to worry about cache expiration at all.
Not sure I follow. But it sounds great. :)
> In our implementation, I did use the ActiveSupport::Cache, so you can
> declare something like this (I18n.backend.cache_store
> = :memory_store), and it will use whatever you provide. Of course, it
> would be wise to use something distributed like Memcached or Ehcache
> (plug: http://github.com/dylanz/ehcache/), so you don't have
> inconsistent translations in local memory across your array.
I'll have to have a look at ehcache. Yeah, the Cache module uses
ActiveSupport::Cache, too.
> So without the Cache in front, I think the ActiveRecord Backend would
> be pretty expensive, in terms of IO/CPU.
I guess no matter how an AR backend is implemented, it always should
have some kind of cache in front of it.
> For example, on an initial
> request to our application (without a warm cache store), it fires off
> 100's of database requests to get the translation records, and set
> them in the cache. Granted they are all pretty quick requests, it's
> still a pretty hefty hit to the database, and I don't think anything
> you'd want to do on a heavily trafficked site, on every request.
On every request? Certainly not.
> Throwing a distributed Cache layer like
> Memcached in between is great, as even thought you're still doing
> 100's of cache requests per request, they are much, much cheaper.
Also, a cache warmup task could be an interesting idea.
> What do you think? I'm all ears, as I'd love to help get a scalable
> backend in place :)
Great! Any help is highly appreciated. Could you give the backend in
i18n/active_record a try in any of your apps?
Thanks
Sven