?
Referenced as Pull Request for: # 9790
avatar richard67
richard67
7 Apr 2016

Steps to reproduce the issue

See Joomla! Update doesn't work on 3.5.0+ with PHP 7 and opcache in the support forum.

The problem and also the solution (php.ini changes) are explained there.

I do not really think it is an issue to be fixed in Joomla!, but I think there should be a note in the release notes and/or some advice in some documentation.

Question: Where to add such info, and who shall do that?

Let me know if I shall do something.

avatar richard67 richard67 - open - 7 Apr 2016
avatar andrepereiradasilva
andrepereiradasilva - comment - 7 Apr 2016

shouldn't this c864a01 resolve the opcache issues on update? or is this another issue?

avatar richard67
richard67 - comment - 7 Apr 2016

No it doesn't. The thing I reported in the forum I had reproduced using one of my patched update packages, so I tested with updating a 3.5.1 to latest staging (3.5.2-dev), so this change you mentioned was already inlcuded before and after update.

avatar andrepereiradasilva
andrepereiradasilva - comment - 7 Apr 2016

i didn't say it does resolve, i said "shouldn't this" :)

avatar richard67
richard67 - comment - 7 Apr 2016

I don't know if it should, maybe @nikosdion knows.

avatar nikosdion
nikosdion - comment - 7 Apr 2016

Ah, no, it wouldn't fix that issue because of the order of operations. The correct order of operations should be:

    function finalizeRestore($siteRoot, $restorePath)
    {
        // Clear OPcache
        if (function_exists('opcache_reset'))
        {
            opcache_reset();
        }
        elseif (function_exists('apc_clear_cache'))
        {
            @apc_clear_cache();
        }

        // Make sure Joomla!'s code can figure out which files exist and need be removed
        clearstatcache();

        if (!defined('JPATH_ROOT'))
        {
            define('JPATH_ROOT', $siteRoot);
        }

        $filePath = JPATH_ROOT . '/administrator/components/com_admin/script.php';

        if (file_exists($filePath))
        {
            require_once ($filePath);
        }

        // Remove obsolete files - prevents errors occuring in some system plugins
        if (class_exists('JoomlaInstallerScript'))
        {
            $script = new JoomlaInstallerScript();
            $script->deleteUnexistingFiles();
        }

        // We have modified the filesystem, therefore we must clear the stat cache a second time.
        clearstatcache();

    }

The thing is that if you don't bust the cache before trying to load the script you get the cached script (from the older Joomla! version you are upgrading FROM).

avatar nikosdion
nikosdion - comment - 7 Apr 2016

Also, generally speaking, it's a good idea disabling opcode caching before making any code updates. Afterwards clear the cache and re-enable opcode caching. If you think about what opcode caching is supposed to do it makes perfect sense.

avatar richard67
richard67 - comment - 7 Apr 2016

@nikosdion You mean the finalizeRestore function should be changed in the core to what you proposed above? If so, who shall do the PR? You? Or me?

avatar nikosdion
nikosdion - comment - 7 Apr 2016

Yes, it should be changed in the core. When we wrote that code a few weeks ago we only anticipated opcode problems after the upgrade. I hadn't experienced any issues during the upgrade. Now that you mentioned it I can see exactly why it's happening.

Can you please do the PR yourself? I'm in the middle of deep refactoring my own software, I can't afford to be distracted by core PRs :(

avatar richard67
richard67 - comment - 7 Apr 2016

OK, will do PR soon today.

avatar andrepereiradasilva
andrepereiradasilva - comment - 7 Apr 2016

@nikosdion thanks.

avatar richard67
richard67 - comment - 7 Apr 2016

Yes, thanks @nikosdion

avatar richard67
richard67 - comment - 7 Apr 2016

PR is ##9790 - I will close this issue here as soon as I have tested the PR myself here with success.

avatar richard67
richard67 - comment - 7 Apr 2016

Hmm, PR #9790 does not work. @nikosdion can you check?


This comment was created with the J!Tracker Application at issues.joomla.org/joomla-cms/9788.

avatar wilsonge
wilsonge - comment - 7 Apr 2016

Let's keep this in one place. I'll close this issue in favour of #9788

avatar wilsonge wilsonge - change - 7 Apr 2016
Status New Closed
Closed_Date 0000-00-00 00:00:00 2016-04-07 19:24:16
Closed_By wilsonge
avatar wilsonge wilsonge - close - 7 Apr 2016
avatar wilsonge wilsonge - close - 7 Apr 2016
avatar richard67
richard67 - comment - 7 Apr 2016

@wilsonge I think you meant "... in favour of #9790". #9788 is the one here.
Problem is: #9790 does not help.

avatar wilsonge
wilsonge - comment - 7 Apr 2016

Sorry! I blame a complete lack of sleep last night. I'll just close github until tomorrow i think :P

avatar richard67
richard67 - comment - 7 Apr 2016

Then have a good night and sleep enough so you are fit tomorrow :tongue:

avatar brianteeman
brianteeman - comment - 8 Apr 2016

re-opened

avatar brianteeman brianteeman - change - 8 Apr 2016
Status Closed New
Closed_Date 2016-04-07 19:24:15
Closed_By wilsonge
avatar brianteeman brianteeman - reopen - 8 Apr 2016
avatar brianteeman brianteeman - reopen - 8 Apr 2016
avatar richard67
richard67 - comment - 8 Apr 2016

@mahagr I leave the branch of the closed PR with changes proposed by Nik open, so you can use it for testing: https://github.com/richard67/joomla-cms/archive/fix-jupdate-opcache.zip, custom URL for patched 3.5.2-dev update container is still http://test5.richard-fath.de/list_test8.xml.

In addition I just created a new branch with changes as proposed by you plus the same for restore.php, as I wrote in the closed PR: https://github.com/richard67/joomla-cms/archive/fix-jupdate-opcache-2.zip, custom URL for update test will follow in a while in a comment below.

Meanwhile I will test excluding not the complete com_joomlaupdate folder but only particular files from being cached in ordert to find out which of the php scripts loading causes the error. If I find out something, details will follow also below.

avatar richard67
richard67 - comment - 8 Apr 2016

My feeling is that the best would be to suspend (disable) opcaching at all during the update, but am not sure if this can be done in a safe way with later restore of previous opcache setting (enabled or disabled) of the opcache enabled status. Maybe the way would be to save the setting (opcache enabled and similar for apc) in the temporary restoration.php file and restore the setting at the end with the information obtained from that file?

avatar richard67
richard67 - comment - 8 Apr 2016

@mahagr Custom URL for a 3.5.2-dev update container based on my new branch mentioned in my comment #9788 (comment) above is http://test5.richard-fath.de/list_test9.xml.

avatar richard67
richard67 - comment - 8 Apr 2016

@mahagr For code comparisons here the branch with Michael's changes from the closed PR: staging...richard67:fix-jupdate-opcache.

And here for my new branch with changes as proposed by you plus same in restore.php (was my idea): staging...richard67:fix-jupdate-opcache-2.

But both changesets do not help for my issue.

avatar richard67
richard67 - comment - 8 Apr 2016

@mahagr Meanwhile I have found out that it is sufficient to exclude only 1 file from opcache to solve my problem:
administrator/components/com_joomlaupdate/restore.php

If I have only this in the blacklist for opcache so it is not cached, and have deleted cached compiled version of this file, and all other Joomla! files are being cached and compiled versions exist, my issue does not appear anymore, and the update works well.

I will add this info to the forum post mentioned in the issue description, too.

And I will see if I can use your code for this file somehow, and if so and it works, I will make a new PR.


This comment was created with the J!Tracker Application at issues.joomla.org/joomla-cms/9788.

avatar mahagr
mahagr - comment - 8 Apr 2016

I see that you have done exactly the same in here (the code causes restore.php to recompile):

richard67@c8dee3e

It should work as long as the version you are upgrading from has above code in it.

avatar richard67
richard67 - comment - 8 Apr 2016

@mahagr No, the code you proposed causes script.php to recompile, and my extension to your proposal causes restoration.php to recompile. But we have to do it for restore.php, and this is somewhere else.

avatar mahagr
mahagr - comment - 8 Apr 2016

Then find where the file gets called and hope that its only included/loaded after extracting all files. Adding recompile also for it should do the trick, mostly because of it works without opcache so it gets loaded only after files have been copied over.

avatar richard67
richard67 - comment - 8 Apr 2016

The restore.php is not called inside php but via a get or post request or a redirect, I have to check details.

So we have to recompile it before the request/redirect happens.

Question is if we should use the other changes in my commit you referred to, even if they do not help in my case, because they might help for others? Could be related to timings and the revalidation frequency on the particular server for hwich of the files this problem occurs?

Or should we focus on the restore.php only because this is the one with which I consistently can reproduce my problem?

avatar richard67
richard67 - comment - 8 Apr 2016

@mahagr There is another place where script.php is called, beside the one where your proposed code takes place:

https://github.com/joomla/joomla-cms/blob/staging/administrator/components/com_joomlaupdate/models/default.php#L570

So beside the redirect.php thing which I still am investigating where we could recompile this, that one should also be handled, just to be on the safer side? But if so, there is no check if the file exists in the code up to now, so I would do it a bit different, have the check "if file exists" only around the recompile stuff and then later loading the file is like it is now, i.e. not inside the "if file exists".


This comment was created with the J!Tracker Application at issues.joomla.org/joomla-cms/9788.

avatar richard67
richard67 - comment - 8 Apr 2016

Hmm, maybe I should have checked my http log earlier.

Could be that opcache is not the problem but somehow makes the error appear.

I have a 404 not found in my log for the request

POST /administrator/components/com_joomlaupdate/restore.php HTTP/1.1

with the referrer

https://test1.richard-fath.de/administrator/index.php?option=com_joomlaupdate&task=update.install

Note that the post request is not https, and I have in global config secure = admininstrator, means force https for the admin area.

Maybe this is the problem, and not the opcache stuff, and it just works somehow without opcache or when I disable opcache for the restore.php, for whatever reason?


This comment was created with the J!Tracker Application at issues.joomla.org/joomla-cms/9788.

avatar mahagr
mahagr - comment - 8 Apr 2016

There's no harm of recompiling files that we know to have been changed; in contrary its the only way to make sure the latest version of the file gets loaded. So those recompiles should be added regardless if they fix your issues or not.

You may be right that there's more into this than just recompile. In 3.5.0 I was also experiencing some Joomla caching issues, but I saw another fix for it so I didn't mention it. Maybe the issue you're seeing is also coming from somewhere else..?

avatar richard67
richard67 - comment - 8 Apr 2016

@mahagr Well I have meanwhile added that to my new branch you can see here: staging...richard67:fix-jupdate-opcache-2 and have also updated the update zip behind this custom url http://test5.richard-fath.de/list_test9.xml for testing.

avatar mahagr
mahagr - comment - 11 Apr 2016

I wasn't able to find any time last weekend and I'm quite busy at my work now that my co-worker got back from vacation. I'll try to find some time ASAP, though.

One thing I did notice on my code: opcache_compile_file() causes a warning if opcache had been disabled -- so it's probably better to just remove it and just use opcache_invalidate() on all PHP 5.5+ versions. Someone found the issue in my own code and I've already fixed it -- but it should also be fixed for Joomla changes.

So just use this:

// Compile cached file into bytecode cache
if (function_exists('opcache_invalidate')) {
    opcache_invalidate($file->filename(), true);
} elseif (function_exists('apc_compile_file')) {
    // PHP 5.4
    apc_compile_file($file->filename());
}

APC function doesn't seem to display any warning on failure.

avatar richard67 richard67 - close - 15 Apr 2016
avatar richard67
richard67 - comment - 15 Apr 2016

Based on @nikosdion 's comment here #9515 (comment) I close this issue:

the only reasonable solution is asking people to use opcode caching as it was designed to be used: disable it before updating PHP code, re-enable it afterwards.

Yes, that's also what I found when checking Zend Opcache manuals and other sources.

For me my issue seems to be very special for my shared hosting situation, and I have a workaround for it anyway (excluding admin from being cached), and have made this workaround available in the support forum for others who might have the same issue.

@mahagr Feel free to provide a PR if you see a way to solve the issues you had, but for solving my issue all stuff we tried did not help.

avatar richard67 richard67 - change - 15 Apr 2016
Status New Closed
Closed_Date 0000-00-00 00:00:00 2016-04-15 11:05:56
Closed_By richard67
avatar richard67 richard67 - close - 15 Apr 2016
avatar mahagr
mahagr - comment - 16 Apr 2016

Yeah, the issue has proven to be really hard to solve in Joomla. Something still gets cached and I don't know what. I know its possible to have a fix for this, but I'm not sure whats going on.

Add a Comment

Login with GitHub to post a comment