Magento - many of same cache requests - performance

today I realized that the Magento doest a lot of same requests to my memcached server, it's requesting the key Zend_LocaleC_en_GB_currencynumber_ . Do you anyone know where is it generated and how can I improve it? It's probably somehow related to rendering of price box but I dont see reason why it's 50 times in a page. Thanks, Jaro.
Edited:
So far I did quick fix
Zend_Cache_Backend_Memcached::load
public function load($id, $doNotTestCacheValidity = false)
{
if ( isset($GLOBALS[$id]) ) {
return $GLOBALS[$id];
}
$tmp = $this->_memcache->get($id);
if (is_array($tmp) && isset($tmp[0])) {
$GLOBALS[$id] = $tmp[0];
return $tmp[0];
}
return false;
}
It's not nice but seems to be working. At least many of requests agains memcached server disappeared. Jaro.

It is one of the known issues in Zend Framework community. It even was reported as an improvement for 1.0.3 release (http://framework.zend.com/issues/browse/ZF-2311).
You fix make sense for Magento where a lot of calls to Zend_Currency is performed and connection to memcached having some limitations or slow enough.
For instance on most of the projects we are using memcached and haven't experienced too big loss in page load time with this calls.
However you can fix it in Magento to make a workaround with ZF:
Rewrite core/locale model in your module
Override currency() method
public function currency($currency)
{
if (!isset(self::$_currencyCache[$this->getLocaleCode()][$currency])) {
$currencyObject = parent::currency($currency);
$currencyObject->setFormat(array(
'format' => Zend_Locale_Data::getContent($this->getLocale(), 'currencynumber')
));
return $currencyObject;
}
return parent::currency($currency);
}

Related

Cookie-less Laravel sessions

We have a small quiz type functionality built in Laravel to be embedded in a site via an iframe served from a separate domain (to work around CMS limitations).
It uses sessions to keep track of the user's progress in the quiz. This doesn't work in Safari (Mac/iOS), I believe because Apple disable cookies issued from within an iframe.
Assuming that limitation is one we're stuck with, has anyone had any success making Laravel sessions cookie-less? I found this code on Github, which looks promising but is old enough (and incompatible with current Laravel) that I can't tell if it's going to be a solution.
In case it helps someone else, or anyone can see any silly errors in my code, this is what I did (an adaption of the Github code, to work in Laravel 9).
I extended StartSession and SessionServiceProvider (to use my new StartSession). I created an override for handleStatefulRequest in Start Session, and where it adds a cookie to the reponse (it calls addCookieToResponse) did this:
if ($request->cookies->get($session->getName())) {
$this->addCookieToResponse($response, $session);
}
else {
// Add session ID to header
$this->addIdentifierToResponse($response, $session);
}
That new function looks like this:
protected function addIdentifierToResponse(Response $response, Session $session)
{
if ($this->sessionIsPersistent($config = $this->manager->getSessionConfig())) {
$response->headers->set("X-Session-Token", $session->getId());
}
}
I also changed the getSession method to get the session ID from that newly set header (when no cookie found):
public function getSession(Request $request)
{
return tap($this->manager->driver(), function ($session) use ($request) {
if ($request->cookies->get($session->getName())) {
Log::debug('1. Set session ID from cookie');
$session->setId($request->cookies->get($session->getName()));
}
else if ($request->headers->get("X-Session-Token", $request->input("sess_id"))) {
$sessionToken = $request->headers->get("X-Session-Token", $request->input("sess_id"));
$session->setId($sessionToken);
}
});
}
I created a Github repo containing the whole thing.

Laravel Debugger showing duplicated queries

Does any one has an idea about this. I don't know why it is showing duplicated queries. I searched a lot, found one answer on stackoverflow, but didn't get proper answer. If anyone faced the same error then please let me know. Thank you
protected $_param;
public function __construct(Utility $utility)
{
$league = $utility->checkDomainController();
view()->share('league', $league);
$this->league = $league;
}
This is the code in controller. which shares league to all the views. But there is only one query in $league = $utility->checkDomainController();
Here is the checkDomainController
if(\Request::server('HTTP_HOST') == env('MAIN_DOMAIN'))
{
$leagueSlug = Route::current()->getParameter('league');
$league = League::where('url', $leagueSlug)->first();
}
else
{
$league = League::where('custom_domain', \Request::server('HTTP_HOST'))->first();
}
if(!$league)
{
//error page
}
return $league;
Anytime you call a property which relies on a related model in blade, Laravel executes a new query, unless you eager load and pass from the controller to the view the preloaded data.
This example you posted seems to me as a loop somewhere within your blade code. Maybe if you can share a bit more of the code related to the front-end, I can help you figure it out.

Laravel session expiration on Carbon::setTestNow()

I'm using Carbon::setTestNow() for testing purpose on laravel 4.2 project and all the time when I make next refresh after the method call where I used Carbon::setTestNow() system log me out.
It happens because session cookie expiration date sets to Carbon::setTestNow() date. How can I override that because it's annoying to make login again all the time. Thanks, hope some one can help me to find some solution.
Just come to the same situation and here's the result:
The "official way" is to extend the Illuminate\Session\Middleware::addCookieToResponse or ::getCookieLifetime
But I find it's quite complicated and bloated.
Come to a simple solution:
Check if the provided mock time is from the past, override the session.lifetime if needed, here's the codeblock I added into app/start/global.php
// Set mock time if requested
if ( ! empty($_GET['mocktime'])) {
try {
$real_time = \Carbon\Carbon::now();
$mock_time = \Carbon\Carbon::parse($_GET['mocktime']);
\Carbon\Carbon::setTestNow($mock_time);
$diff_min = $real_time->diffInMinutes($mock_time);
if ($diff_min > 0) {
// requested mock time is from the pass
$org_lifetime = Config::get('session.lifetime');
Config::set('session.lifetime', $diff_min + $org_lifetime);
}
} catch (Exception $ex){
Log::warning('Mocktime requested but unable to set: '.$ex->getMessage());
}
}
As this answer is coming late, hope it can help someone later.

Magento Resources and API Data Sources

As I work with third-party APIs pretty frequently, I thought it would be helpful to create some Magento modules to enable easy connection and querying of them. Ideally, you could query an API like this...
$data = Mage::getModel( 'tools/apixyz_list' )->getCollection();
It would instantiate a model for one of the list items, then attempt to get a collection of them by querying the API. This would require some kind of hookup in the config between the Resource Model and the API and that's where I'm having a little trouble.
Is there a recommended way to do this? I'm having a lot of difficulty finding anything on the subject yet I feel like it should be a pretty common issue given the amount of APIs that generally need to get integrated from project to project.
Yes! I actually built this for Recurly - I'm trying to get it open sourced, but it's not open yet. Here's a snippet from the load() method which is the guts of it.
// TBT_Recurly_Model_Resource_Recurly_Abstract_Collection
public function load($printQuery = false, $logQuery = false)
{
if ($this->isLoaded()) {
return $this;
}
if ($this->_isCached()) {
return $this->_loadCache();
}
$this->_beforeLoad();
$this->_renderFilters()
->_renderOrders()
->_renderLimit();
$this->clear();
try {
# This is ultimately doing the API call
$recurly_list = $this->_getListSafe();
} catch (Recurly_Error $e) {
Mage::logException($e);
$this->setConnectionError($e->getMessage());
return $this;
}
foreach ($recurly_list as $recurly_item)
{
$item = $this->getNewEmptyItem();
$item->getResource()->setDataOnObject($item, $recurly_item);
// Recurly appears to sometimes return duplicate subscription items in it's list response.
if (!isset($this->_items[$item->getId()])) {
$this->addItem($item);
}
}
$this->_afterLoadRecurly();
// We have to setIsLoaded before we saveCache b/c otherwise it will infinite loop
$this->_setIsLoaded();
$this->_saveCache();
$this->_afterLoad();
return $this;
}
We actually ended up taking this and putting it into a base REST class, and it was really cool because it ended up being really easy to implement new REST APIs on top of it.
As far as best practice goes, I'm not sure that I've answered your question specifically. But basically I think the main things to do to make it clean are:
Follow the Magento models / collection method signatures for querying.
Implement caching
Implement the API communication in the resource model layer

how to integrate SMF with CodeIgniter?

I am working on a project that will solely use the SMF member system. Meaning that SMF is the only member system that I am using to have logins, not my own system along with SMF, just plain SMF. However, I am running into one problem... I need to be able to get information from SMF based on a given ID_MEMBER. My article database uses SMF's ID_MEMBER field as the author information. Seeing that CodeIgniter is MVC and uses classes, I searched for a general SMF class all over the internet, but could not find one. I decided to write my own, but cannot get it to work correctly... I don't have much experience with OOP.
<?php
class smf {
var $context;
var $memberContext;
function __construct($who){
include('/../../forums/SSI.php');
$this->context = $context;
}
function user_context(){
return $this->context['user'];
}
function member_context($id = NULL){
loadMemberData($id);
loadMemberContext($id);
return $memberContext[$id];
}
}
The user_context function works fine, but not the member_context function. In the SSI.php file, the LoadmemberContext function compiles all of the information into an array called $memberContext[$id]. When I call the method from my CodeIgniter controller, I get an error saying that the $memberContext variable is undefined. Why is this happening?
I stumbled upon this question too and managed to fix it. Try this, it worked for me:
function member_context($id = NULL) {
loadMemberData($id);
loadMemberContext($id);
global $user_profile;
return $user_profile[$id];
}

Resources