Enterprise Edition Controller events not firing if Full Page Cache is enabled - magento

So on one of our recent launches we had a lot of events that we were observer such as controller_action_predispatch. Once the site went live we started noticing that our observers were never getting called for those. After a little investigation one of our developers found this block of code in Mage_Core_Model_App around line 292
if ($this->_cache->processRequest()) {
$this->getResponse()->sendResponse();
} else {
$this->_initModules();
$this->loadAreaPart(Mage_Core_Model_App_Area::AREA_GLOBAL, Mage_Core_Model_App_Area::PART_EVENTS);
if ($this->_config->isLocalConfigLoaded()) {
$this->_initCurrentStore($scopeCode, $scopeType);
$this->_initRequest();
Mage_Core_Model_Resource_Setup::applyAllDataUpdates();
}
$this->getFrontController()->dispatch();
}
As you can see if $this->_cache->processRequest() that is true which it is when full page cache is enabled you never get to the dispatch. The developer did find http_response_send_before which gets call either way but it seems to me like this is a bug or you should never ever use those controller dispatch events for anything if you have full page caching enabled. Any thoughts?

Given the nature of the full page caching, I'd call this "works as intended". While it can be a little strange not to have some events firing, they had to pick a line and this one makes sense to me, especially since the controller is never really dispatched.
You should use those controller dispatch events for anything that affects the page (as it still needs to be generated), but if you are using it for tracking and such, no it would not be appropriate.

See here if you want to learn how Caching works with Magento Enterprise
http://magentophp.blogspot.com/2011/02/magento-enterprise-full-page-caching.html

The only reliable event to listen for with and without Full Page Cache enabled is http_response_send_before.

controller_front_send_response_before
This event will be fired irrespective of FPC enabled

Related

How to add a flashdata after session_write_close()

I upgraded my application from CI2 to CI3 (CI v3.1.9 and PHP7). Now I have performance issue with the new concurrency system in the session (see doc).
Some of the actions in the application are very long (because of calling an external APIs that can takes several minutes to respond for example) and I don't want those actions to lock the session. As recommended, I would use session_write_close() function in the controller before doing the very long action.
The problem is that I want to display a message to user after redirecting at the end of this action. Right now, I am using session->set_flashdata() before the redirection, but because I closed the session earlier, it is not working.
Does anyone have recommendations on how to achieve that?
If I am starting the session again with session_start() it is working, but I have no idea if this is best practice to use PHP session like that with Codeigniter.
There is no problem with starting the session again using session_start(). The CodeIgniter "Session" class is still loaded and the instance is still valid. So all the "special" stuff that CI does to make sessions work is good to go.
I tested and then used this scheme in a project some time back and didn't experience any problems. Haven't had any blow-back from the client of a still operating site either. YMMV.
BTW, in the __construct() function of the CI_Session class a call to session_start() is made in order to start up PHP's session extension. So making that call is clearly not a "bad" practice. :)

Nativescript - resumeEvent handling

In my app when the app is resumed from a sleep, I'd like to
reload the page - or ideally, just update specific UI elements.
How can this be done?
Preferably in a platform independent way.
You want to hook into the onResume method in the application module which exposes the event when an app resumes from the background.
https://docs.nativescript.org/api-reference/modules/application.html#onresume
So in your app.js (the entry point of your application), import the module and add the onResume event handler and it can run everytime the app resumes. Now reloading a page will require a little more work. You'd have to use the frame module and find out the current page and do your work, but I'm guessing it can be done with a little effort using the approach mentioned.
UPDATE: based off your comment, you need the reloadPage() method from the ui/frame module. https://docs.nativescript.org/api-reference/modules/_ui_frame_.html#reloadpage
The correct method is reloadPage() in the Frame module (as contributed by #Brad) but the problem is that it's NOT an exposed api.
No problem - just copy/paste it and it works.
The problem is that it basically does a navigateTo() to the currentPage and that effects the navigation history. You have 2 choices - setting clearHistory to true and you lose all history (don't want that) or set clearHistory to false which creates a a duplicate of the current-page (don't want that either). There's also a backstackVisible option but that doesn't help in this scenario.
#Brad tells me that there's api that allows access to the navigation stack - haven't looked into it.
For my app - the user will be at the root page most of the time, so I decided to reload the page only if on the root page and then set clearHistory to true and that works for me.

How to add information to Glimpse after EndRequest?

I'm the maintainer of the Miniprofiler Glimpse plugin and with the latest Miniprofiler versions I'm not able to push data to Glimpse because the Profiler is not yet populated (in previous versions it was) when the GetData() method of the tab is called.
Right now what I do is wrap the Miniprofiler Storage and when the Save() method is called, all the needed information is there but it's too late and I don't know how to send it to the tab.
So, what is the best approach (if possible) to add this information to a tab when it's ready in Miniprofiler?
Unfortunately EndRequest is currently the last moment you can subscribe on to return the necessary data. That is the moment when Glimpse will finalize its monitoring for the given request and the moment it will persist that information to the persistence store.
Although in v1 it is possible to add data after the EndRequest but only when using the default in memory store. So you could return your wrapper, which will be empty at that moment, and it will be stored in memory, allowing you to change the wrapped content afterwards.
But the above will not work for other persistence stores. We might also change this in v2 to make it deterministic, independent of the persistence store being used.
Maybe you could have your wrapper ask MiniProfiler to calculate the results at that moment, so they can be stored, even though those results might not be 100% complete?

Queue System for Registration JSP

I have a registration website in JSP (Server: Tomcat), how can I limit how many users can see registration page (Like 10 users ) ...and after that users will get in a Queue ..so that my website performance is not hit.
I have seen this kind of system in Prometric..so kind of wondering how can I also achieve the same using Java..
I don't think it's a good idea, but if you really have to do it, then use a Semaphore initialized with 10 permits, acquire the semaphore at the beginning of the servlet/jsp/action, and release it, in a finally block, when the servlet/jsp/action has ended its work.
You might also do this in a Filter, to decouple the access limitation code from the functional code.

Magento admin will not load when there is another action running

I do have my own Controller in Magento, that has been done by following the guidelines here:
http://alanstorm.com/magento_admin_controllers
My controller extends Mage_Adminhtml_Controller_Action and inside there is a method:
public function myAction() {
sleep(1000);
die('I am done');
}
When this method is running I cannot load any other Magento Admin pages. They will load eventually right after the method above is complete.
Also Frontend works fine, running the very same action from the Frontend controller does not cause Magento to hang like this.
Any solutions to keep my method in Admin and while this method is running, rest of the admin should stay usable?
Longest time this process runs is about 4-5 hours and it imports products. Yes I do have cron also set up, but I would like to give the user the ability to init processes at will also.
This is a feature.
The workaround is to use two browsers, e.g. Firefox + Chrome, Firefox + Opera and so on.
It is better to work two-browser on these tasks as you don't want a crash in your other tabs to interrupt your import.
I know that is not an in-depth programming answer, sometimes the lateral solution works though.
Have to answer this myself:
Solution is mega simple:
call this right before the long process (make sure that you have done manipulating the session data before calling this method, otherwise errors may occur)
session_write_close();
And voila, you can run multiple processes at the same time!

Resources