On Sun, Jan 12, 2020, at 6:45 PM, Mike Schinkel wrote:
> > On Jan 12, 2020, at 1:57 PM, Larry Garfield <la...@garfieldtech.com> wrote:
> > 
> > Most notably, *not all code will be run in a preload context*.  
> 
> Can you give some concrete examples here?
> 
> > Language features that only sometimes work scare me greatly.  
> 
> Do you have some examples of  language features, from PHP or another 
> language, that only work sometimes and that are known to be 
> problematic. and why they are problematic?

To use the example from the OP:

static_run {
    $link = mysqli_connect("127.0.0.1", "my_user", "my_password", "my_db");
    $res = mysqli_query ($link, 'select * from sometable');

    $array = [];
    while($row = mysqli_fetch_assoc($res)) {
        $array[]= $row;
    }

    define('CONST_ARRAY' = $array);
}

I can see the use of that, sure.  Now, what happens when the code is not 
preloaded?  Does that block not get run, and thus CONST_ARRAY is not defined?  
Does it run on all requests if not preloaded?  How does that interact with a 
file that gets read multiple times?

What happens if the code does more than set a constant?  Can it define new 
functions?  What happens to those functions in a non-preload situation?

To use the other example:

static_run {
    on_file_load(function($file_ast){

        // Do something with the ast of the file

        return $file_ast;
    });
}

AST manipulation from user-space opens up a lot of possibilities for 
optimization.  However, it's also a huge foot-gun.  When you start messing with 
the AST I can't imagine it's hard to end up introducing subtle behavioral 
changes without intending to.  Or, maybe you are intending to.  So then what 
happens if the code runs in a context when that doesn't happen?  Does the AST 
then get re-manipulated on every request instead?  What's the performance 
impact of that?  Net negative?

I don't have answers to these questions.  It's possible that we could come up 
with a set of answers that would address the core issue, but I am skeptical.

My core point here is that I am fully in favor of leveraging preloading to 
improve performance, BUT ensuring that there is zero behavioral difference 
between preloaded and non-preloaded code, only performance differences, is 
paramount, and IMO is more important than any flexibility, power, or 
performance benefits it could offer.  We should consider exposing that to user 
space *only* if we can be pretty damned sure that it's not going to introduce 
weird-and-subtle behavioral bugs that end up making preloaded and non-preloaded 
code behave differently.

As an example, preloading seems like a great place to do something like tail 
recursion flattening.  That's a logically safe thing to do, as long as the call 
is properly tail-recursive, and would make writing tail-recursive algorithms 
more practical.  (They're often easier to read and maintain but performance 
makes them less practical.)

However!  Doing so means the preloaded version doesn't have an issue with 
blowing out the stack.  The non-preload version does.  That means the 
non-preload version has a built in limit on how long of a list it can operate 
on (100 by default, minus however many stack calls have already been made) 
while the preloaded version doesn't.  That can have ugly implications if you're 
running code that was working in preload in a non-preload context, and suddenly 
your 105 element array is causing a fatal error when it didn't before.

That's the sort of subtlety that, frankly, I am a lot more confident in Engine 
developers remembering to think about than user-land developers.  Myself 
included.  Not because they're less capable developers but because 99% of the 
time PHP doesn't force you to think about such questions, so most developers 
won't think to think about them.  And 99% of the time that's a good thing.  
This is the other 1%. :-)

What I very much want to avoid, for as long as possible at least, is "this 
library only works if preloaded" type situations.  That's how we end up with a 
division in the language; not just between people who own their own servers and 
those that don't, but it ties the hands of admins and framework authors in 
deciding what to preload.  What a "good" preload strategy is depends on 
context, and we've only had a month or two experience with it to even know what 
to recommend to people.

And that's in addition to the development challenges of developing such code in 
the first place:

> > "I changed one character and now I have to restart my webserver to see if 
> > it did anything" is a bad place for PHP to be.
> 
> As I envision it preloaded code of this nature would not be handled on 
> server reboot, but when the files have had their time stamps updated. 
> If I am not mistaken, PHP already does this (but I could be mistaken as 
> I don't have expertise in PHP OpCodes.) 

The opcache does that, yes.  The preloader, however, is a one-shot deal and 
requires restarting FPM to have it re-run.



Thinking about it, I suspect there would be far more benefit in practice not 
from allowing AST manipulation but being able to "Checkpoint" a running script; 
that is, allow it to not just pre-load code (which we can do now in 7.4) but 
set up variables that are already initialized from one request to the next.  
I'm thinking here of things like bootstrapping a dependency injection 
container, declaring closed functions, and other semi-global stuff that right 
now makes a PHP application's bootstrap process more expensive than most other 
languages.  (In the area of milliseconds, sure, but still slower.)  Allowing 
that sort of execution to happen once and get persisted would reduce the need 
to do all the precompiling and such that many frameworks do today, at the cost 
of a great deal of complexity.

That may be as much of a pipedream to do safely, I don't know, but in practice 
that seems like a more promising direction for userland developers to leverage 
themselves.

--Larry Garfield

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to