Brad Fitzpatrick (bradfitz) wrote in lj_dev,
Brad Fitzpatrick
lj_dev is stupid.

An exchange between avva and me, ending in the decision that is stupid and should die, to be replaced by

Brad writes:
I recently changed's header from:

 require "$ENV{'LJHOME'}/cgi-bin/";
 require "$ENV{'LJHOME'}/cgi-bin/";


# determine how we're going to send mail
    do "$ENV{'LJHOME'}/cgi-bin/";
    do "$ENV{'LJHOME'}/cgi-bin/";

    $LJ::OPTMOD_NETSMTP = eval "use Net::SMTP (); 1;";
    if ($LJ::SMTP_SERVER) {
        die "Net::SMTP not installed\n" unless $LJ::OPTMOD_NETSMTP;
        MIME::Lite->send('smtp', $LJ::SMTP_SERVER, Timeout => 10);
    } else {
        MIME::Lite->send('sendmail', $LJ::SENDMAIL);

but now, hooks are loaded in a web context (from BML, etc), but not from
command line programs which just source, like synsuck, so synsuck
is segfaulting on synsuck, just like deadjournal.

do I not understand perl's BEGIN blocks and do statements?

what's invalidating %LJ::HOOKS?  :-/

Avva replies:
I toyed around with this a bit... seems LJ::HOOKS is never filled in.
When you "do" in BEGIN, eventually
it gets to and its code. gets compiled fine, but its
execution (all its initialisation statements) fails, so it never gets
to define the hooks. The reason they fail is that ljlib's BEGIN is
executed before the rest of is even parsed, much less
compiled. Inside that BEGIN, all LJ:: functions haven't been defined
yet. The rest of the stuff works because and
are just a bunch of assignments, they don't use LJ:: functions.

Why this works in web context? More complicated. The difference is
that in web context, everything begins with (require'd in Then it goes>>>> ,
and the whole of is compiled (while its invokation of in BEGIN doesn't get to the second time
because require's are forced by Perl to be non-reentrant, and while doesn't require, it do'es it,
require's ); after that execution continues in and everything goes through because has been

So it only works by accident, because of this incidental>> connection. It's pretty silly that on
ljcom installations, require'ing pulls in, but
on livejournal installations, that's not the case. This probably bits
people on their asses every now and then.

And then he replies again later....
Really, when you think about it, is not the right place to
pull in and other site-specific libraries. Rather, this
should be done in a new (and we don't need at all then, since is supposed to be
customised directly anyway). Here's how it should be working, I think:

a) no . This means that require'ing
doesn't execute anything heavy (as it does now), but only defines
lots of constants from and .

b) comes from ljcom CVS, require's . Perhaps
it should also require separately, rather than from, not sure if it matters.

c) Now you can "do", in in a BEGIN
block without problems.

d) in at the beginning, you require if there
is one; or if you prefer, you "do" it in a BEGIN block, but put it at
the end of, that'll work too because LJ:: functions have been
compiled by then and ljcom's initialisation will work.


  • Post a new comment


    Anonymous comments are disabled in this journal

    default userpic

    Your reply will be screened

    Your IP address will be recorded 

  • 1 comment