Skip Menu |

This queue is for tickets about the Media-Type-Simple CPAN distribution.

Report information
The Basics
Id: 46474
Status: resolved
Worked: 1 hour (60 min)
Priority: 0/
Queue: Media-Type-Simple

People
Owner: rrwo [...] cpan.org
Requestors: kane [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: Critical
Broken in: (no value)
Fixed in: (no value)



Subject: Module doesn't work when process forks
Greetings, consider this sample script: use strict; use Media::Type::Simple qw[type_from_ext]; for( 1..2 ) { if( my $pid = fork() ) { print "$pid: ". type_from_ext( 'jpg' ) . $/; } } When run, it dies as follows: $ perl tmp/z.pl 5826: image/jpeg Unknown extension: jpg at tmp/z.pl line 5 The reason is that you are using the data filehandle, which needs to be seek'd back to it's original position when done. The attached patch fixes this. Please be so kind to apply & release a new version, so we don't have to keep a locally patched copy in svn. Thank you,
Subject: mts.patch
--- a/Media/Type/Simple.pm (revision 1418) +++ b/Media/Type/Simple.pm (working copy) @@ -55,11 +55,11 @@ =head1 VERSION -Version 0.02 +Version 0.02_01+HC =cut -our $VERSION = '0.02'; +our $VERSION = '0.02_01+HC'; =head1 SYNOPSIS @@ -134,7 +134,14 @@ } else { unless (defined $Default) { + + # Have to reset the seek() position to make this work while + # forking. find out the current position and put it back when + # we are done reading --kane + my $offset = tell DATA; $Default = $self->add_types_from_file( \*DATA ); + + seek DATA, $offset, 0; } return clone $Default; }
From: pause [...] nodekit.org
I ran in to this problem also-- fix would be great.
RT-Send-CC: pause [...] nodekit.org
Robert has given me maintenance privs and I'm trying to get this fixed so I can use this module in one of my other modules and I'm running into an issue. I should first disclaim that forking is complicated to me, so please bear with me. I tried to create a test script based on the sample code you provided (attached 02-forked_process.t) and this is the output I receive: $ perl -I../lib ./02-forked_process.t not ok 1 - type_from_ext() didn't fail Unknown extension: jpg at ./02- forked_process.t line 13 # # Failed test 'type_from_ext() didn't fail Unknown extension: jpg at ./02-forked_process.t line 13 # ' # at ./02-forked_process.t line 16. not ok 2 - got image/jpeg # Failed test 'got image/jpeg' # at ./02-forked_process.t line 17. # got: undef # expected: 'image/jpeg' ok 1 - type_from_ext() didn't fail ok 2 - got image/jpeg ok 3 - type_from_ext() didn't fail ok 4 - got image/jpeg 1..4 When I put your patch in place, I get the same thing. If I take out the test code and just run w/ the print statement (uncomment line 10 and comment lines 11-17), I get this before the patch: $ perl -I../lib ./02-forked_process.t 23765: image/jpeg 23767: image/jpeg # No tests run! Unknown extension: jpg at ./02-forked_process.t line 9 Then applying your patch, I get the same thing: $ perl -I../lib ./02-forked_process.t Unknown extension: jpg at ./02-forked_process.t line 9 23783: image/jpeg 23785: image/jpeg # No tests run!
Subject: 02-forked_process.t
use strict; $|++; use Test::More qw/ no_plan /; use Media::Type::Simple qw[type_from_ext]; for( 1..2 ) { if( my $pid = fork() ) { #print "$pid: ". type_from_ext( 'jpg' ) . $/; my $mime; eval { $mime = type_from_ext( 'jpg' ); }; my $err = $@; ok( ! $err, "type_from_ext() didn't fail $err" ); is( $mime, 'image/jpeg', 'got image/jpeg' ); } } __END__ This test case came from Jos Boumans via RT ticket # 46474: https://rt.cpan.org/Ticket/Display.html?id=46474
On Thu Mar 25 11:01:58 2010, PURDY wrote: Show quoted text
> Robert has given me maintenance privs and I'm trying to get this fixed > so I can use this module in one of my other modules and I'm running into > an issue. I should first disclaim that forking is complicated to me, so > please bear with me. > > I tried to create a test script based on the sample code you provided > (attached 02-forked_process.t) and this is the output I receive: > > $ perl -I../lib ./02-forked_process.t > not ok 1 - type_from_ext() didn't fail Unknown extension: jpg at ./02- > forked_process.t line 13 > # > # Failed test 'type_from_ext() didn't fail Unknown extension: jpg at > ./02-forked_process.t line 13 > # ' > # at ./02-forked_process.t line 16. > not ok 2 - got image/jpeg > # Failed test 'got image/jpeg' > # at ./02-forked_process.t line 17. > # got: undef > # expected: 'image/jpeg' > ok 1 - type_from_ext() didn't fail > ok 2 - got image/jpeg > ok 3 - type_from_ext() didn't fail > ok 4 - got image/jpeg > 1..4
This confuses me; you get both 'not ok 1' and 'ok 1' from the same script? what's going on here? Show quoted text
> When I put your patch in place, I get the same thing. If I take out the > test code and just run w/ the print statement (uncomment line 10 and > comment lines 11-17), I get this before the patch: > > $ perl -I../lib ./02-forked_process.t > 23765: image/jpeg > 23767: image/jpeg > # No tests run! > Unknown extension: jpg at ./02-forked_process.t line 9
^ this last line is the indication that something went horribly wrong ie, the key 'jpg' wasn't in the lookup table. Show quoted text
> Then applying your patch, I get the same thing:
That means the problem's still there, just that my patch didn't work. Show quoted text
> > $ perl -I../lib ./02-forked_process.t > Unknown extension: jpg at ./02-forked_process.t line 9 > 23783: image/jpeg > 23785: image/jpeg > # No tests run!
A bit off fiddling with the code and when/where to reset the handle may be needed OR simply putting the code in a string/ data structure and avoiding the whole problem. Itll cost a tad more RAM, but at least it'd work when used in say a webserver. Cheers, --Jos
RT-Send-CC: pause [...] nodekit.org
I've been banging my head on this for a while and I have some up with a workaround and it may just be a limitation with the way M:T:S is designed. There's some black magic going on behind the scenes with 'self' and Storable freeze/thaw in its internal clone() method, which I'm very hesitant to mess with. Anyway, here's a workaround, using the object-oriented method: use strict; $|++; use Media::Type::Simple; my $o = Media::Type::Simple->new; for( 1..2 ) { if( my $pid = fork() ) { print "$pid: ". $o->type_from_ext( 'jpg' ) . $/; } } Does that work for you ... for now?
BTW, I also tried altering add_types_from_file() to use IO::File and explicitly set the position to 0 and that didn't seem to do it, either. sub add_types_from_file { my ($fh) = args; #while (my $line = <$fh>) { use Data::Dumper; print Dumper( $fh ); #my $io = IO::All->new(\*DATA); my $io = new IO::File; $io->fdopen( fileno( $fh ), 'r' ); $io->setpos(0); # this didn't seem to work $io->seek(0,0); print "current cursor pos: " . $io->tell . "\n"; #print "IO dump: \n\n" . $io->name; #$io->autoclose(1); while( my $line = $io->getline ) { $line =~ s/^\s+//; $line =~ s/\#.*$//; $line =~ s/\s+$//; if ($line) { self->add_type(split /\s+/, $line); } } $io->close; undef $io; return self; }
Resolved in v0.30.2.