2

I have wrote a custom API server for magento (the SOAP/REST api was too slow for me) using http://code.google.com/p/phpsocketdaemon/ library and the Mage.php base class.

One of the API Method on my API server is to carry out product update in a specific way, which looks like this:

<?php

function product_update($api_data)
{
    // Init
    $product = json_decode($api_data);
    $product_update_response = array();

    // Load Mage
    $app = Mage::app()->setCurrentStore(Mage_Core_Model_App::ADMIN_STORE_ID);

    // Anticipate Error
    try
    {
        // Check If Product API Data Is Valid
        if (!$product) {
            throw new Exception('Failed to decode API Data.');
        }

        // Workout Website Ids
        list ($retail_store_id, $trade_store_id) = $product->websites;

        // Load Product Id By Sku
        $mage_product_id = Mage::getModel('catalog/product')->getIdBySku($product->sku_code);

        // Proceed If Product Exists
        if ($mage_product_id)
        {
            // Parse Data
            $width = floatval($product->width);
            $height = floatval($product->height);
            $length = floatval($product->length);
            $weight = floatval($product->weight);
            $pack_size = intval($product->unit_of_sale);
            $retail_price = floatval($product->price);
            $trade_price = floatval($product->trade_price);

            // Set [Retail] Product Info
            $retail_product = Mage::getModel('catalog/product')->setStoreId($retail_store_id)->load($mage_product_id);
            $retail_product->setSagename($product->sagename);
            $retail_product->setBarcode($product->barcode);
            $retail_product->setWidth($width);
            $retail_product->setHeight($height);
            $retail_product->setLength($length);
            $retail_product->setWeight($weight);
            $retail_product->setPackSize($pack_size ? $pack_size : 1);
            $retail_product->setStatus($product->status == 'Enabled' ? '1' : '2');
            $retail_product->setPrice($retail_price);
            $retail_product->save();
            $retail_product = null;
            sleep(1);

            // Set [Trade] Product Info
            $trade_product = Mage::getModel('catalog/product')->setStoreId($trade_store_id)->load($mage_product_id);
            $trade_product->setSagename($product->sagename);
            $trade_product->setBarcode($product->barcode);
            $trade_product->setWidth($width);
            $trade_product->setHeight($height);
            $trade_product->setLength($length);
            $trade_product->setWeight($weight);
            $trade_product->setPackSize($pack_size ? $pack_size : 1);
            $trade_product->setStatus($product->status == 'Enabled' ? '1' : '2');
            $trade_product->setPrice($trade_price);
            $trade_product->save();
            $trade_product = null;

            // Generate Success Response
            $product_update_response = array(
                'status'   => 'Success',
                'queue_id' => $product->queue_id
            );
        }
        else
        {
            // Error
            throw new Exception('Product with SKU ['. $product->sku_code .'] Does Not Exists In Magento');
        }
    }
    catch (Exception $ex)
    {
        // Generate Error Response
        $product_update_response = array(
            'status'   => 'Error : '. $ex->getMessage(),
            'queue_id' => $product->queue_id
        );
    }

    // Clean-Up
    $app = null;

    // Finished
    return sizeof($product_update_response) > 0 ? 
           json_encode($product_update_response) : 
           'GlobalError : Failed To Update Products - Possibly No Data Was Posted' . ' (' . __FILE__ . ':' . __LINE__ . ')';
}

?>

Now, this function runs perfectly fine within the socket server. However, after a short period of time, I start getting the following error on the Mage.php base class (captured by the try,catch function):

23/09/2013 10:02:17 : [ 259 / 500 ] Error : SQLSTATE[HY000]: General error: 2006 MySQL server has gone away

I did some searching around and there has been various "suggestions" to fixing this. Most of them involved modifying the my.cnf file to up the limiters.

However, my MySQL Server (Percona) is already optimised: http://pastebin.com/raw.php?i=qJcQb9HM

Can someone help me figure out why the mage base class would report (MySQL Server has gone away) - whilst it clearly hasn't (because the site is still active and working fine).

If I restart the socket server, this error will go away and everything will be back to normal for a short-while and then the error re-appears.

Regards

2

Since you mentioned that restarting the socket server solves the error for a time, this is highly unlikely related to the max packet size being exceeded. That said, even were the env optimized, it would never hurt to double it for a time to see if it effected any change!

It sounds like the socket server is using persistent MySql connections and recycling them after they are closed. If not using persistent connections (and not being entirely familiar with the socket server being used) then I would guess your server is opening a connection when it's started and using that for it's entire life cycle.

If you are using persistent connections, try disabling them. If you're not, and rather opening a connection for the life cycle of the server, you'll either need to implement code to gracefully reopen a closed connection, keep track of idle time to know when it needs to be reopened, or open a single connection for each request being processed. Opening a connection per request could limit throughput, but only very slightly, but is also likely going to be the simplest option to solve the problem.

1

This may be due to the connection to the database is sitting idle while you are operting on sockets.I think that the code is taking longer than MySql is configured to wait before closing an idle connection, I.e. The value of the wait_timeout setting which IIRC is 300 (5 min) by default. Or The other common cause for error 2006 is a max_allowed_packet to small for necessary queries.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.