Closed (fixed)
Project:
Page Manager
Version:
8.x-1.x-dev
Component:
Code
Priority:
Normal
Category:
Bug report
Assigned:
Unassigned
Reporter:
Created:
11 Jul 2014 at 09:06 UTC
Updated:
15 Feb 2016 at 20:44 UTC
Jump to comment: Most recent, Most recent file
Comments
Comment #1
blueminds commentedHere is the patch with quickfix.
Comment #2
tim.plunkettHm, under what circumstances does this happen?
Comment #3
berdirOh, I guess this is only triggered together with #2284005: Implement static contexts, without that, the context is not requested. But the tests there are not failing.
Comment #4
arla commentedThis happens also on head. (Perhaps this has changed since #3 was written.)
I think this goes unnoticed in development environments because the route rebuilding has time to happen before the redirect request i handled. For one D8 project, we have 700 routes which are all rebuilt after creating a new page. Depending on the server, this will take longer than handling the redirect request. Then in PageEditForm::form() -> getContexts() -> ... -> RouteParamContext::onPageContext(), getRoutesByPattern() does not find the newly created route.
Comment #5
arla commentedOne way to trigger the same error in development is to place a breakpoint and stop execution in
RouteParamContext::onPageContext()PageManagerRoutes::alterRoutes(). Drupal should then proceed to handle the new request but without the new route registered.Update: Fixed method reference.
Comment #6
arla commentedArguably, this is a design mistake in how Core handles redirects. Generally this problem would occur when a form, which creates a new route upon submit, redirects to a page that depends on the existence of the new route. I don't know if there are more rebuilding mechanisms, other than that of routes, that have the same problem. What we can do in contrib is to tolerate that such registries (like the router table) are not necessarily up to date—especially after a redirect.
Perhaps we should add a message to the current patch, to explain the silly situation that the user might have to refresh the page to see all contexts.
Sorry for the post spree.
Comment #7
arla commentedUpdated quickfix with a message. Not sure how to test this.
Comment #9
mpotter commentedI was able to reproduce this on my local dev in a fresh install of D8 (beta15):
So, it looks like this happens consistently the first time creating a new page. This is on my docker container on my Macbook, so its not that slow, so not sure about the timing issues mentioned earlier.
I agree with #6 about what is happening here, but I don't see any core issue for this. I'm not sure the watchdog message in #7 is needed. The patch in #1 seems to fix the problem for simple pages but I haven't tested anything with context.
Comment #10
mpotter commentedHmm, I take back my comment on the timing. As soon as I started trying to debug this with xdebug and phpstorm it no longer gets an error.
Edited: In fact, after clearing the database and reinstalling I still don't get the error anymore. So I cannot confirm whether the patch works or not because it's possible the timing changed. I'll continue to try and find a way to reproduce this consistently.
Comment #11
tim.plunkettIt'd be nice to be able to reproduce this, but I'm guessing this is a suitable fix.
Comment #12
mpotter commentedForgive me for any first-timer ignorance on some of this, but I've been tracing through the code to see how this might be happening. Here is what I've learned in case it helps trigger somebody's brains:
So, there are a couple possibilities here:
In patch #1 it is assuming that the $routes array being returned is empty. Like it's not in the database or the database result is cached somewhere. The patch in #11 is a bit more general and just checks to ensure there is the correct Route object type in the return. This also handles the case of an empty $routes array, so seems like a cleaner solution.
But neither address the actual underlying problem. What is causing the DB query to not return the path that was just added. This seems like a more serious, potentially core issue with the DB caching or something.
Sorry for the long post, but are people aware of any DB caching that might be preventing the previous transaction results from appearing in the new db query?
Comment #13
mpotter commentedRelated to #3, I'm not seeing a specific call to the connection->commit anywhere, so somehow it is relying on the database to "lazy commit" this dangling transaction. Perhaps in some cases we are trying to query the DB before this transaction has been committed.
Can somebody more expert in D8 describe why the Drupal/Core/Routing/MatcherDumper.php dump() routine doesn't explicitly commit the transaction it has started? or how this "lazy commit" stuff is supposed to work?
Comment #14
berdirD8 transactions works the same as they do in D7, that's nothing new. A transaction is committed basically at the end of a method.
Comment #15
tim.plunkettDiscussed this with @dawehner, who pointed us to #2564921: In PHP-FPM environment, enabling a module in using a 'configure' route leads to an error page.
Turns out @mpotter uses PHP-FPM and I do not, which explains why I could not reproduce.
Page Manager can still be broken with the fix in the last patch, but it's better than nothing. The other issue should fix it properly.
Working on a unit test now.
Comment #16
tim.plunkettComment #17
valthebaldis this a duplicate of #2564921: In PHP-FPM environment, enabling a module in using a 'configure' route leads to an error page?
Comment #18
tim.plunkett@valthebald Yes, that issue should remove all of the ways to make $route instanceof Route be FALSE, but I think it's a good improvement. I'll commit it shortly.
Comment #19
tim.plunkettApparently I committed this and didn't include the issue number: http://cgit.drupalcode.org/page_manager/commit/?h=61e8602