Модераторы: korob2001, ginnie
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> mod_perl, странное поведение use [LIB] 
:(
    Опции темы
salexx
Дата 22.8.2007, 14:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 3
Регистрация: 22.8.2007

Репутация: нет
Всего: нет



Здравствуйте!

Есть сервер, на нем стоит Apache/2.0.55, mod_perl 1.99.
Есть библиотека условно LIB.pm. Так как работа над ней ведется,
что называется, без отрыва от производства, то необходимо иметь стабильную и рабочую (тестовую) версии библиотеки.
Я решил это следующим способом: положил библиотеку в 2 папки /lib1/LIB.pm и /lib2/LIB.pm.
Так как mod_perl загружает скрипт и зацикливает его, то для использования отдельно двух версий
библиотеки сделал 2 скрипта:

script1.cgi:

#!/usr/bin/perl

use lib qw( /lib1/ );
use LIB;

...


и

script2.cgi:

#!/usr/bin/perl

use lib qw( /lib2/ );
use LIB;

...


Я расчитывал на то что mod_perl загрузит и зациклит каждый скрипт с отдельной библиотекой.
Но получается так, что в script1.cgi может оказаться загружена библиотека из /lib2/, хотя переменная @INC при этом
не сожержит путь /lib2/.

Может быть есть способ исправить такое поведение mod_perl или какие есть еще способы организации работы,
чтобы была стабильная версия библиотек для работы текущих сервисов и экспериментальная, которая тестируется
перед копированием на место основной?

PM MAIL   Вверх
Nab
Дата 22.8.2007, 15:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 582
Регистрация: 25.3.2006
Где: Kiev

Репутация: 26
Всего: 37



Цитата(salexx @  22.8.2007,  14:32 Найти цитируемый пост)
Но получается так, что в script1.cgi может оказаться загружена библиотека из /lib2/, хотя переменная @INC при этомне сожержит путь /lib2/.

Вы это утверждение проверяли? Или так, абы сказать...
Я не проверял ибо не имею mod_perl, но даже если и так, то @INC содержит всего лишь пути поиска библиотек. А загружена она или нет перлом проверяеться в путях в последнюю очередь.. Сначала проверяеться %INC, содержащий список загруженных модулей.

И ваш модуль будучи загруженным должен быть сначала выгружен.

короче, это должно быть приблизительно вот так:

Код

script1.cgi:

#!/usr/bin/perl

# выгружаем библиотеку
no use LIB;
# удаляем путь поиска
no use lib qw( /lib2/ );
use lib qw( /lib1/ );
use LIB;

...


и

script2.cgi:

#!/usr/bin/perl

# выгружаем библиотеку
no use LIB;
# удаляем путь поиска
no use lib qw( /lib1/ );
use lib qw( /lib2/ );
use LIB;

...


no use lib qw( /lib1/ );
делать можно по разному, можно вручную манипулировать порядком следования путей поиска в массиве @INC,
но лучше как я указал.

Добавлено через 4 минуты и 33 секунды
Да я вот что еще хотел сказать, производить тестирование на продакшен сервере по минимуму не здоровое решение :( 
Сделайте себе для тестирования отдельное окружение....


--------------------
 Чтобы правильно задать вопрос нужно знать больше половины ответа...
Perl Community 
FREESCO in Ukraine 
PM MAIL   Вверх
salexx
Дата 22.8.2007, 18:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 3
Регистрация: 22.8.2007

Репутация: нет
Всего: нет



Цитата(Nab @  22.8.2007,  15:10 Найти цитируемый пост)
Вы это утверждение проверяли? Или так, абы сказать...

Да, проверял. Я не ожидал такой реакции от системы, поэтому все перепроверил 10 раз.
В script1.cgi выводил @INC - путь /lib2/ отсутствует, и выводил $INC{"LIB.pm"} = "/lib2/LIB.pm"
Делал no use LIB; не помогало не пробывал только no use lib qw( /lib1/ );
Манипулировал @INC - бесполезно, так как с этим массивом все в порядке. Пришел к такому выводу что mod_perl не только зацикливает скрипт, но и не загружает в новый скрипт библиотеку по другому пути, если библиотека с таким именем уже была загружена в память.

Цитата(Nab @  22.8.2007,  15:10 Найти цитируемый пост)
Да я вот что еще хотел сказать, производить тестирование на продакшен сервере по минимуму не здоровое решение :( 

Да, вы правы на 100%.
PM MAIL   Вверх
Nab
Дата 22.8.2007, 19:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 582
Регистрация: 25.3.2006
Где: Kiev

Репутация: 26
Всего: 37



no use LIB: вы не делали, ибо такая конструкция ошибочна в принципе smile
так как я писал прямо в форум, то мне такая описка простительна, а вам в тестировании нет smile
манипулирование @INC не бесполезно, потому как именно это мы делаем когда говорим... use lib qw(...) или no lib qw(...);
это влияет на порядок поиска модулей. И вообще:
Код

perldoc lib


use выполняеться при компиляции, думаю для вашего случая наилучшим вариантом будет такая организация скрипта:

Код

#!/usr/bin/perl

use lib qw( /lib1/ );
# загружаем во время выполнения
eval "use LIB;";
die $@ if $@;

#сам скрипт
... 

# выгружаем библиотеку
no LIB;
# удаляем путь поиска
no lib qw( /lib1/ );


для обоих скриптов.

Возможно я гдето ошибась, нужно проверять...


Это сообщение отредактировал(а) Nab - 22.8.2007, 20:01


--------------------
 Чтобы правильно задать вопрос нужно знать больше половины ответа...
Perl Community 
FREESCO in Ukraine 
PM MAIL   Вверх
Ramirez
Дата 23.8.2007, 11:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 305
Регистрация: 18.1.2005
Где: Moscow, ExUSSR

Репутация: 4
Всего: 5



мод перл, насколько мне известно, компилирует либу 1 раз (на каждый процесс апача). поэтому, не исключено, что когда вы 1 раз обратились из скрипта к LIB.pm он ее подгрузил, а потом из второго скрипта снова вызвали LIB.pm, но он не полез ее искать в путях, т.к. она уже в памяти есть (ищет-то оне ее по имени, а не пути). Все это происходит в рамках одного дочернего процесса апача, который обслуживает данное подключение.

Я бы проверил это так:
1.запускаем апач, обращаемся к скрипту любому, смотрим откуда либа берется.
2.перезапускаем апач (или ждем пока чилд по таймауту не помрет, либо с другого компа заходим). повторяем с другим скриптом.
3.снова смотрим пути

Есть подозрение, что все зависист к какому скрипту первому обратиться, та либа в памяти и останется.
Это при условии что в директиве PerlRequire  эта либа не фигурирует, иначе она вообще компилируется 1 раз при старте апача и общая на всех детей.

еще можно в апаче добавить:
Код

<Location /perl-status>                                                                                                             
    SetHandler modperl                                                                                                              
    PerlOptions +GlobalRequest                                                                                                      
    PerlResponseHandler Apache2::Status                                                                                             
</Location>


потом зайти http://<domain>/perl-status

будет куча инфы. какие модули загружены, кем, откуда итд....

причем, если я не ошибаюсь, все это применительно к текущему контексту.

PS: так и есть, проверил. Причем либа остается скомпиленной в том чилде, который обслуживал запрос к скрипу, вызывающему эту либу. Причем прикол в том, что когда этот чилд потом пойдет других клиентов обслуживать, эти либы в нем так висеть и останутся.

это видно в том-же перл-статусе: он в шапке показывает pid чилда апача, который данный запрос обработал (перл-статус). а так ка они чередуются (они = чилды. если конечно KeepAlive не очень большой стоит, т.к. после запроса текущий чилд ждет KeepAlive-секунд повторного запроса от текущего клиента, и только потом уходит обрабатывать других клиентов), то пощелкав кнопкой F5 (но не чаще чем 1 раз в KeepAlive-секунд) можно дождаться когда тебя обработает именно тот чилд, из которого ты скрипт с либой вызывал. Так вот, в нем либы будут видны smile

В твоем случае, я думаю, получается, что у каждого чилда апача (который хоть раз обслуживал обращение к скрипту 1 или 2) своя либа внутри загружена. Причем откуда эта либа загружена зависит от того к какому скрипту обратились первый раз (с момента рождения чилда).
После этого либа всегда берется из памяти. Так этот чилд и остается жить с этой либой внутри, пока не обслужит MaxRequestsPerChild-запросов и не помрет. Или пока весь апач не перезагрузят.

PPS: путей к модулям perl-статус не показывает, но различать либы с одинаковы ми именами можно по версиям.
Добавь в каждую либу 
Код

our $VERSION = "x.x.x";


извиняюсь за сумбурное изложение =)

Это сообщение отредактировал(а) Ramirez - 23.8.2007, 12:36
PM ICQ   Вверх
salexx
Дата 23.8.2007, 13:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 3
Регистрация: 22.8.2007

Репутация: нет
Всего: нет



Всем спасибо, я понял что побороть такое поведение не получится. Будем разделять рабочие и тестовые сервера.
PM MAIL   Вверх
Ramirez
Дата 23.8.2007, 13:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 305
Регистрация: 18.1.2005
Где: Moscow, ExUSSR

Репутация: 4
Всего: 5



почему невозможно, возможно:

http://perl.apache.org/docs/2.0/api/ModPer...unload_package_

производительность, конечно снизится (насколько, зависит от размеров модуля), если на каждом запросе выгружать и загружать заново бибилиотеку. Хотя, если в отладочных целях, и для одной конкретной библиотеки, то вполне можно.

Это сообщение отредактировал(а) Ramirez - 23.8.2007, 13:10
PM ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Perl"
korob2001
sharq
  • В этом разделе обсуждаются общие вопросы по языку Perl
  • Если ваш вопрос относится к системному программированию, задавайте его здесь
  • Если ваш вопрос относится к CGI программированию, задавайте его здесь
  • Интерпретатор Perl можно скачать здесь ActiveState, O'REILLY, The source for Perl
  • Справочное руководство "Установка perl-модулей", можно скачать здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, korob2001, sharq.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Perl: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0458 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.