Как часть моего приложения на Rails, я написал небольшой импортер, который всасывает данные из нашей системы LDAP и встраивает их в таблицу User. К сожалению, код, связанный с LDAP, теряет огромные объемы памяти при переборе наших 32-килобайтных пользователей, и я не смог выяснить, как решить эту проблему.
Эта проблема, похоже, как-то связана с библиотекой LDAP, поскольку, когда я удаляю вызовы LDAP-содержимого, использование памяти стабилизируется. Кроме того, распространяются следующие объекты: Net :: BER :: BerIdentifiedString и Net :: BER :: BerIdentifiedArray , обе являются частью библиотеки LDAP.
Когда я запускаю импорт, использование памяти в итоге достигает максимума более 1 ГБ. Мне нужно найти способ исправить мой код, если проблема есть, или обойти проблемы с памятью LDAP, если именно в этом проблема. (Или, если есть лучшая библиотека LDAP для больших импортов для Ruby, я тоже открыт для этого.)
Вот соответствующий бит нашего кода:
require 'net/ldap'
require 'pp'
class User < ActiveRecord::Base
validates_presence_of :name, :login, :email
# This method is resonsible for populating the User table with the
# login, name, and email of anybody who might be using the system.
def self.import_all
# initialization stuff. set bind_dn, bind_pass, ldap_host, base_dn and filter
ldap = Net::LDAP.new
ldap.host = ldap_host
ldap.auth bind_dn, bind_pass
ldap.bind
begin
# Build the list
records = records_updated = new_records = 0
ldap.search(:base => base_dn, :filter => filter ) do |entry|
name = entry.givenName.to_s.strip + " " + entry.sn.to_s.strip
login = entry.name.to_s.strip
email = login + "@txstate.edu"
user = User.find_or_initialize_by_login :name => name, :login => login, :email => email
if user.name != name
user.name = name
user.save
logger.info( "Updated: " + email )
records_updated = records_updated + 1
elsif user.new_record?
user.save
new_records = new_records + 1
else
# update timestamp so that we can delete old records later
user.touch
end
records = records + 1
end
# delete records that haven't been updated for 7 days
records_deleted = User.destroy_all( ["updated_at < ?", Date.today - 7 ] ).size
logger.info( "LDAP Import Complete: " + Time.now.to_s )
logger.info( "Total Records Processed: " + records.to_s )
logger.info( "New Records: " + new_records.to_s )
logger.info( "Updated Records: " + records_updated.to_s )
logger.info( "Deleted Records: " + records_deleted.to_s )
end
end
end
Заранее спасибо за любую помощь / указатели!
Кстати, я спрашивал об этом и на форуме поддержки net / ldap, но там не было никаких полезных указателей.