From 601a0f8a766e8a02a48a743346a4f3b44b7019c6 Mon Sep 17 00:00:00 2001 From: Mazen Khalil Date: Wed, 23 Oct 2024 09:18:30 +0300 Subject: [PATCH] fix: ip-lookup database lazy loading for all environments (#8052) The current task for loading `GeoLite2-City.mmdb` doesn't work for all build types. This PR addresses this and move the task to initializer to ensure consistency across environments. --------- Co-authored-by: Sojan Jose Co-authored-by: Sojan Jose --- app/services/geocoder/setup_service.rb | 49 ++++++++++++++++++++++++++ config/initializers/geocoder.rb | 4 +++ lib/tasks/ip_lookup.rake | 31 +--------------- 3 files changed, 54 insertions(+), 30 deletions(-) create mode 100644 app/services/geocoder/setup_service.rb diff --git a/app/services/geocoder/setup_service.rb b/app/services/geocoder/setup_service.rb new file mode 100644 index 000000000..0b71c6740 --- /dev/null +++ b/app/services/geocoder/setup_service.rb @@ -0,0 +1,49 @@ +require 'rubygems/package' + +class Geocoder::SetupService + def perform + return if File.exist?(GeocoderConfiguration::LOOK_UP_DB) + + ip_lookup_api_key = ENV.fetch('IP_LOOKUP_API_KEY', nil) + if ip_lookup_api_key.blank? + log_info('IP_LOOKUP_API_KEY empty. Skipping geoip database setup') + return + end + + log_info('Fetch GeoLite2-City database') + fetch_and_extract_database(ip_lookup_api_key) + end + + private + + def fetch_and_extract_database(api_key) + base_url = ENV.fetch('IP_LOOKUP_BASE_URL', 'https://download.maxmind.com/app/geoip_download') + source_file = Down.download("#{base_url}?edition_id=GeoLite2-City&suffix=tar.gz&license_key=#{api_key}") + + extract_tar_file(source_file) + log_info('Fetch complete') + rescue StandardError => e + log_error(e.message) + end + + def extract_tar_file(source_file) + tar_extract = Gem::Package::TarReader.new(Zlib::GzipReader.open(source_file)) + tar_extract.rewind + + tar_extract.each do |entry| + next unless entry.full_name.include?('GeoLite2-City.mmdb') && entry.file? + + File.open GeocoderConfiguration::LOOK_UP_DB, 'wb' do |f| + f.print entry.read + end + end + end + + def log_info(message) + Rails.logger.info "[rake ip_lookup:setup] #{message}" + end + + def log_error(message) + Rails.logger.error "[rake ip_lookup:setup] #{message}" + end +end diff --git a/config/initializers/geocoder.rb b/config/initializers/geocoder.rb index 9c53a1635..e1c7de695 100644 --- a/config/initializers/geocoder.rb +++ b/config/initializers/geocoder.rb @@ -24,3 +24,7 @@ module GeocoderConfiguration end Geocoder.configure(ip_lookup: :geoip2, geoip2: { file: GeocoderConfiguration::LOOK_UP_DB }) if ENV['IP_LOOKUP_API_KEY'].present? + +Rails.application.config.after_initialize do + Geocoder::SetupService.new.perform +end diff --git a/lib/tasks/ip_lookup.rake b/lib/tasks/ip_lookup.rake index 3225caffa..644a5c825 100644 --- a/lib/tasks/ip_lookup.rake +++ b/lib/tasks/ip_lookup.rake @@ -2,35 +2,6 @@ require 'rubygems/package' namespace :ip_lookup do task setup: :environment do - next if File.exist?(GeocoderConfiguration::LOOK_UP_DB) - - ip_lookup_api_key = ENV.fetch('IP_LOOKUP_API_KEY', nil) - if ip_lookup_api_key.blank? - Rails.logger.info '[rake ip_lookup:setup] IP_LOOKUP_API_KEY empty. Skipping geoip database setup' - next - end - - Rails.logger.info '[rake ip_lookup:setup] Fetch GeoLite2-City database' - - begin - base_url = ENV.fetch('IP_LOOKUP_BASE_URL', 'https://download.maxmind.com/app/geoip_download') - source_file = Down.download( - "#{base_url}?edition_id=GeoLite2-City&suffix=tar.gz&license_key=#{ip_lookup_api_key}" - ) - - tar_extract = Gem::Package::TarReader.new(Zlib::GzipReader.open(source_file)) - tar_extract.rewind - - tar_extract.each do |entry| - next unless entry.full_name.include?('GeoLite2-City.mmdb') && entry.file? - - File.open GeocoderConfiguration::LOOK_UP_DB, 'wb' do |f| - f.print entry.read - end - end - Rails.logger.info '[rake ip_lookup:setup] Fetch complete' - rescue StandardError => e - Rails.logger.error "[rake ip_lookup:setup] #{e.message}" - end + Geocoder::SetupService.new.perform end end