Re: [RFC] Extension Prepend Files
| From: | Pierre Joye | Date: | Tue, 06 Jan 2015 06:48:40 +0000 |
| Subject: | Re: [RFC] Extension Prepend Files | ||
| References: | 1 2 3 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-80221@lists.php.net to get a copy of this message | ||
hi,
On Mon, Jan 5, 2015 at 8:21 PM, François Laupretre <francois@tekwire.net> wrote:
>> -----Message d'origine-----
>> De : php@golemon.com [mailto:php@golemon.com] De la part de Sara Golemon
>>
>> So, I've been meaning to propose something *like* this, but with a few
>> key implementation detail differences:
>>
>> 1) Create the notion of "Persistent User Functions/Classes/Constants/etc
>>
>> 2) Embedded text sections
>
> First, persistent PHP code or data (NOT reloading code for each request) is a huge can of
> worms. If Sara decides to re-launch the idea, that will be great but the subject is probably out of
> scope here.
>
> IMHO, what we need here is a generic mechanism to embed PHP code in C extensions and, then,
> execute it. It should define a way to embed PHP scripts as C strings at compile time, how to make
> these scripts known and accessible from the PHP core, and how to execute them when needed.
>
> Instead of including the runtime code in every extensions, as it is done in ext-embed, I would
> prefer an extension which would provide this service to other 'client' extensions. It
> would define a stream wrapper to access the registered PHP scripts. Script registration would be
> registered in persistent memory during MINIT. The registration would return an ID for each
> registered script. These IDs would be stored by the client extension and would be used to derive a
> stream-wrapped path when the client decides to execute a registered script. These paths would
> uniquely reference the scripts, which would allow to opcode-cache them.
>
> As a specific case, if an extension wants to execute some PHP code at the beginning of each
> request, it can execute its script(s) during RINIT, but it is just a use case of a more general
> mechanism. RINIT execution order can be resolved using module dependencies.
>
> Extending the mechanism to userspace 'plain file' scripts could be provided by a
> 'bridge'. The user could register a plain file script, whose content would be stored in
> persistent memory, with a flag that would cause the script to be loaded during every RINIT.
>
> One more word about executing scripts during every RINIT : even with opcode caches, as Sara
> notes, the performance hit is not negligible. The question is always the same : What is the
> percentage of requests that will really use the classes/functions we define there ? Remember that
> the list of scripts is hardcoded in an extension. If the extension wants to allow conditional
> loading for different features, it needs to define appropriate ini settings. Choosing the list of
> scripts at compile time is another option but would make the distribution of precompiled binaries
> complex.
>
> I personally favor another approach. I still use the PHK extension as an example of this
> 'intermediate' approach. This extension defines C-levels front-end classes. These classes
> contain the 'fast' code. When this code needs to access 'slow' PHP code, it
> executes the PHP scripts it needs, then calls the just-defined PHP classes. This way, we preserve
> the possibility to code a big part of the extension in PHP, without the overhead of loading the PHP
> code at the beginning of each request.
>
> Thanks for your attention :)
It looks to me that it is going slightly too far, or I totally miss
why it is such a critical feature.
As a developer of (too) many extensions, I can only agree with other
developers saying that many times, writing some glue code in PHP is
way easier than doing it in C using the PHP internals APIs. This is a
one of the biggest problem PHP internals have. Sara and many other
pointed out this problem numerous times in the past. PHP 7 is an
unique opportunity to provide easier APIs to develop extensions even
if we keep the existing ones for obvious reasons.
For example HHVM provides a neat one, which is simply PHP for simple
cases. Complex cases allow advanced the native support is also
supported. See https://github.com/facebook/hhvm/wiki/Extension-API.
Zephir (https://github.com/phalcon/zephir) provides also a clean
solution and easier to maintain or implement PHP extensions.
Python or Perl also provides much cleaner APIs and mix of C and
scripts for extensions developers.
To me, it looks like this is what we should try to solve instead of
creating something we will most likely regret very soon. Benjamin's
original proposal (if technically possible in such a simple way, but I
am not sure about that :) ) is somehow more acceptable than Sara's one
(statically built scrpts with the extension. For one, statically build
scripts into extensions looks to me like statically linking libc. It
also kills any of the advantages of having a glue code, from a release
point of view.
The last thing I do not understand, from Benjamin's point of view, is
the performance part. PHP glue code is used for areas where
performance is not a matter, but then we may end adding this
featurebecause the performance impact is too big. What do I miss? If
the prepend or script loading process are too slow, we should try to
fix this bottleneck instead of opening yet another can of worms.
However I do not see this part of a request as the bottlenecks for
most PHP apps (with opcache).
I do not try to be negative or aggressively opposed to this feature. I
simply think we are trying to solve the wrong parts of the problems.
Cheers,
--
Pierre
@pierrejoye | http://www.libgd.org