Hi,

I have module that imports data from json file to hash. Json file is pretty big so I don't want loading to take place on every request because it takes some time. It would be best to do this just on server start. I have a class variable in module called "data" which I'd like to set only on server start and then I can access to it on every request with SomeModule.data (I use mattr_accessor). I tried to import data in application config.after_initlize method but id doesnt work - data persists only on first request and on second request data is nil.

Is there any way to do this beside session, and can you give little explanation on this. I know I can save this data in session but I'd like to do this other way.

Thanks in advance

Dani AI

Generated

As noted, the goal is to parse a large JSON once and keep it available across requests. The behavior you described — data present on one request and nil on the next — most often comes from two sources: (1) Rails' code reloading in development (cache_classes = false) which unloads/reloads module/constants between requests, and (2) multi-process server semantics (each worker process has its own memory). is right that an initializer runs at boot, but that alone doesn't solve the development-reload or cross-process problems; 's point about persistent storage is also a valid tradeoff.

Practical options (with minimal examples)

  • Per-process, boot-time load (works well in production where classes are cached):

    # config/initializers/load_big_json.rb
    require 'json'
    SomeModule.data = JSON.parse(File.read(Rails.root.join('lib','data','big.json')))

    Note: the correct callback name is after_initialize (not after_initlize). Initializer code runs at boot; in production this typically loads once per process.

  • Shared cache (best for reliability across processes):

    def self.data
    Rails.cache.fetch('some_module:data', expires_in: 12.hours) do
      JSON.parse(File.read(Rails.root.join('lib','data','big.json')))
    end
    end

    Use a shared cache store (Memcached or Redis) so all workers share the same parsed object and you avoid repeated parsing.

Tips and cautions

  • In development, either disable class reloading or rely on a cache/store that survives code reloads. to_prepare runs every request in dev, so it’s not a good place to “boot once.”
  • If memory use is large, be careful with per-process caches — multiple workers multiply RAM usage.
  • Provide a clear reload path (e.g. SomeModule.reload_data! or Rails.cache.delete('some_module:data')) when the file changes.

Recommendation: for robustness and minimal surprises, store the parsed data in a shared cache (Redis/Memcached) or database; use a boot initializer only if you accept per-process memory and understand Rails’ development reloading and your app server’s forking behavior.

Recommended Answers

All 2 Replies

I do not understand why you attempt to store data in the server memory which should rather be stored in database. Anyway, someone has given some ideas here.

Don't you want to put your code inside the initializer? Codes inside the initializer folder only run once whenever the application starts.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.