Skip Menu |

Preferred bug tracker

Please visit the preferred bug tracker to report your issue.

This queue is for tickets about the Log-Dispatch CPAN distribution.

Report information
The Basics
Id: 103392
Status: resolved
Priority: 0/
Queue: Log-Dispatch

People
Owner: Nobody in particular
Requestors: KENTNL [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in: 2.42
Fixed in: 2.45



Subject: Should not depend on threads.pm

Relay from: https://bugs.gentoo.org/show_bug.cgi?id=545998

The addition of threads.pm as a dependency indicates to downstreams that threads.pm is required for this module to function.

Which in turn indicates to downstreams that they need a perl built with threads.

Given most code does not require this behaviour, its safe to suggest `threads` as a dependency is misleading, and should be a suggestion if anything.

The question is how to expose things that depend on this behaviour of Log::Dispatch such that it can be clear an individual needs threads that work for their package to function.

My suggestion is that things would possibly be simpler if ::Syslog was an independent package, and at least that way, things that depended on ::Syslog would pave a clearer path to "possibly needs threads", but I'm wary of suggesting splits due to the headaches it gives downstream. =)

Another option would be to tease out the "lock" feature into its own package somehow that mandatorily used threads, and getting people to use that instead.

Again, obviously this is not a problem for CPAN auto-things-install, but its a visibility problem for statically (manually) analysing what things need threads and what don't.

On 2015-04-08 13:54:52, KENTNL wrote: Show quoted text
> Relay from: https://bugs.gentoo.org/show_bug.cgi?id=545998 > > The addition of threads.pm as a dependency indicates to downstreams > that > threads.pm is required for this module to function.
I don't follow. threads.pm still installs on non-threaded perls... I just reinstalled it on my non-threaded perlbrewed 5.21.10. $Config{usethreads} or $Config{useithreads} is the correct way to check for threaded support. (Perhaps LD should change its Makefile.PL to only depend on a particular version of threads.pm if the perl was built with threaded support, but I still don't see how gentoo packaging is concluding that threading is required.)

In this case, it *does* indicate that you need thread.

 

Because using that feature invokes `require threads`.

 

And `require threads` on a perl without threads causes a fatal exception. ( Which is uncaught )

Thus, the presence of a `threads` in the dependency list is an indication that it will fatally die if your perl lacks threads.

Thus, it indicates that the code requires a perl with threads.

And it is factual that this feature *does* require threads.

perl -MLog::Dispatch::Syslog -E"Log::Dispatch::Syslog->new( min_level => 1,   lock => 1 )"
This Perl not built to support threads
Compilation failed in require at /home/kent/perl5/perlbrew/perls/5.21.8-c/lib/site_perl/5.21.9/Log/Dispatch/Syslog.pm line 62.

But the rest of it does not. Which is where it gets sticky.

Thus, whether or not it requires threads is conditional on usage.

But when it does require threads, it *also* requires a threaded perl.

And the prevalence of this is sufficient to make that inference in general.

 

But the problem is for downstream, there's no opaque way to tell if a dist actually need threads or not. Which is why the dependence on threads.pm , given the above behaviour, is a proxy for "needs a threaded perl". And this is mostly reliable.
 

And by proxy, any module that uses this feature inherently requires a threaded perl.

And this is *also* an invisible mechanism which is not visible anywhere other than the declared chain of dependencies.

So given that X requires threads, and that threads.pm requires a threaded perl, and that Y requires X, by inference, to provide X, we must provide a threaded perl for module Y.

We can of course bodge around it downstream, but we can't do better in initial packaging than to assume that "requires threads" is sufficient cause to force a threaded perl being available.

On 2015-04-08 15:12:29, KENTNL wrote: Show quoted text
> In this case, it *does* indicate that you need thread. > Because using that feature invokes `require threads`.
I suspect this is a byproduct of [AutoPrereqs] being used to extract all 'use' lines in the code and tests (in this case, a bit of code that isn't always run.) Show quoted text
> And `require threads` on a perl without threads causes a fatal > exception. ( > Which is uncaught )
Indeed. (IMO it's fine that the exception is uncaught, since the feature in question is clearly documented as requiring threads.) Show quoted text
> Thus, the presence of a `threads` in the dependency list is an > indication that > it will fatally die if your perl lacks threads.
No, this isn't correct. I can still satisfy the dependency on threads.pm on an unthreaded perl -- this module is still installed, even if loading it results in an exception. CPAN clients can find the module and confirm that it is installed, and MM->parse_version, Module::Metadata etc can statically extract its $VERSION. Show quoted text
> Thus, it indicates that the code requires a perl with threads.
No. %Config should be checked in Makefile.PL if threads are required, and exit or die otherwise. It is incorrect for this distribution to be depending on threads.pm when it isn't used by a core piece of functionality, but I think the gentoo packager is also in error for not being able to transcribe these dependencies into something that works in a non-threaded perl.

On 2015-04-09 10:28:25, ETHER wrote:
> No. %Config should be checked in Makefile.PL if threads are required,
> and exit or die otherwise.
>

That would make sense if the whole module required it, instead of just a feature... but its murkier with optional features ( And optional features that are determined at runtime are all kinds of hell for downstream, because it basically means there are side effects that can be indicated by things outside their vendor dependency spec set )

> It is incorrect for this distribution to be depending on threads.pm
> when it isn't used by a core piece of functionality, but I think the
> gentoo packager is also in error for not being able to transcribe
> these dependencies into something that works in a non-threaded perl.

It is a transcription problem, but its the sort of thing that you can only realize is wrong after the fact.

Because it /is/ very much the case that we try to transcribe upstream dependencies directly to downstream dependencies where possible, and that we report dependencies being inaccurate upstream when we encounter them downstream. ( I'll come back to that later )

And because of the nature of threads.pm, where one _cannot_ *use* it without a threaded perl. Yes, EUMM and MM and friends can all do static analysis of it, but for all points and purposes in the context of downstream dependencies, what *actually* happens at *runtime* is important.

For instance, if there is an arbitrary module named "A" and it requires arbitrary module "B", it doesn't matter that A is on your system and can have its version statically parsed with EUMM, it is considered *broken* from a runtime perspective if `use A` cannot be expected to work at all.

( And we do frequently have this problem when upstream splits a package and so the module is secretly gone in a subsequent release, and nobody noticed, and so there is now things that depend on that that have to be fixed. )

Thus, we deem "threads" to be "unusable" in runtime without a perl with threads enabled ( despite being available )

And so by proxy, any mapping of an upstream to dependency to "threads" maps to the downstream dependency "virtual/perl-threads".

And _that_ dependency is tasked with making sure threads.pm is `use` able. And so it naturally requests the user provide `dev-lang/perl[ithreads]` to guarantee a perl with thread support.

This is indeed a problem of various many faceted joys of mapping several incompatible systems of dependency mappings and the contrasting axioms of  "Just-works" logic against a stricter "It must work as soon as its installed or make it clear it wont work before the code even runs" system.

But that is why the intent of dependencies in *.json and *.PL need to be clear.

Because we have to map upstream dependencies verbatim in initial packaging passes, and hope we did our best. Because its simply not viable to perfectly assess very far beyond that.

Often upstream will depend on stuff and it won't be obvious why or how, and it will only be discovered later. So its better to over-specify and have the dependency resolver go "Welp, I cant be satisfied, need a different perl" than to under-specify and have a machine somewhere randomly not work later in the installation cycle.

Sometimes upstream under-specify, and that's not something we really are likely to notice so readily, and those cases until somebody files a bug, and then we file a bug upstream to make the missing conditional dependency visible in some manner.

 

 




 

(side note: the added dependency on threads and threads::shared was added in 2.42, released 2014-08-12.)
Reading L::D::Syslog after checking Changes and think 1) why using "require" when runtime-dependencies list Module::Runtime? 2) why are threads mandatory in non-threaded Perl? ~ $ perl -Mthreads -e 1 This Perl not built to support threads Compilation failed in require.