Как часть моего приложения направляющих, я записал немного средства импорта, которое впитывает данные из нашей системы LDAP и переполняет его в таблицу User. К сожалению, LDAP-связанный код пропускает огромные объемы памяти при итерации по нашим 32K пользователям, и я не смог выяснить, как устранить проблему.
Проблема, кажется, связана с библиотекой LDAP в некотором роде, как тогда, когда я удаляю вызовы к материалу LDAP, использование памяти стабилизировалось приятно. Далее, объекты, которые распространяются, являются Сетевыми:: BER:: BerIdentifiedString и Сеть:: 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 форуме поддержки также, но не получил полезных указателей там.