Spreadsheet:: ParseExcel:: Поток, теряющий свой парсер
У меня есть таблица Excel 18M для синтаксического анализа, а Spreadsheet::ParseExcel
потребляет столько памяти, что мне пришлось переключиться на Spreadsheet::ParseExcel::Stream, Он отлично работает на моей виртуальной машине, он отлично работает на нашем промежуточном сервере, но на нашем производственном сервере (настроен таким же образом) я получаю эту ошибку:
Can't call method "transfer" on an undefined value at \
lib/Spreadsheet/ParseExcel/Stream/XLS.pm line 31.
Это происходит из следующего кода:
my ($wb, $idx, $row, $col, $cell);
my $tmp = my $handler = sub {
($wb, $idx, $row, $col, $cell) = @_;
$parser->transfer($main); XXX here where we die
};
my $tmp_p = $parser = Coro::State->new(sub {
$xls->Parse($file);
# Flag the generator that we're done
undef $xls;
# If we don't transfer back when done parsing,
# it an implicit program exit (oops!)
$parser->transfer($main)
});
weaken($parser);
weaken
выглядел подозрительным, поэтому я не оспаривал, если пересчет не был больше 1, но та же проблема возникает. Я измерил код для получения stacktrace и получил следующее:
parser is undefined at lib/Spreadsheet/ParseExcel/Stream/XLS.pm line 29.
Spreadsheet::ParseExcel::Stream::XLS::__ANON__ \
('Spreadsheet::ParseExcel::Workbook=HASH(0x6cd4a08)', 0, 2, 1, \
'Spreadsheet::ParseExcel::Cell=HASH(0x1387ce78)') called at \
/usr/share/perl5/Spreadsheet/ParseExcel.pm line 2152
Spreadsheet::ParseExcel::_NewCell( \
'Spreadsheet::ParseExcel::Workbook=HASH(0x6cd4a08)', 2, 1, \
'Kind', 'PackedIdx', 'Val', 'Dean', 'FormatNo', 25, ...) \
called at /usr/share/perl5/Spreadsheet/ParseExcel.pm line 896
Spreadsheet::ParseExcel::_subLabelSST( \
'Spreadsheet::ParseExcel::Workbook=HASH(0x6cd4a08)', 253, 10, \
'\x{2}\x{0}\x{1}\x{0}\x{19}\x{0}2\x{0}\x{0}\x{0}') \
called at /usr/share/perl5/Spreadsheet/ParseExcel.pm line 292
Spreadsheet::ParseExcel::parse( \
'Spreadsheet::ParseExcel=HASH(0x6cd1810)', '2013-09-13.xls') \
called at lib/Spreadsheet/ParseExcel/Stream/XLS.pm line 35
Spreadsheet::ParseExcel::Stream::XLS::__ANON__ \
called at new_importer.pl line 0
Это говорит мне, что анализатор читает первую и вторую строки, но по какой-то причине он умирает в третьей строке.
Я пробовал перестроить Spreadsheet::ParseExcel::Stream
, и у него нет никаких ошибок (все тесты проходят). Я также перекомпилировал Coro
(тот же результат).
Я озадачен. У кого-нибудь есть идеи?
Ответы
Ответ 1
Проблема оказалась довольно странной и выглядела как этот код psuedo:
stream1 = open first excel stream
sheet1 = stream1.sheet // get spreadsheet ready for reading
if in verbose mode:
stream2 = open second excel stream
sheet2 = stream2.sheet
count++ while sheet2.get_row
say "We have $count records"
Мы обнаружили, что если и только если бы мы находились в подробном режиме, эта проблема проявилась бы. Имея два потока, указывающих на один и тот же документ, наш производственный код завершится неудачно, хотя это отлично работает на других ящиках. Считая количество строк и закрывая этот поток, прежде чем открывать обычный поток для чтения документа, мы решили проблему.