Case Study : How bad code can hurt performance and even breakPradip Shah
Many websites, notably eCommerce and WordPress, live with bad code. They end up spending more effort in improving performance by adding more resources. It is like adding more horsepower to an inefficient car engine – will consume more gas and in the long run fixing the engine would be a better thing.
Not all such attempts will succeed, however. Bad code takes many forms. There are times when your application is dependent on an external service. The problem comes when this service is executed inline when your visitor is waiting for your server to respond. The two popular dependencies are sending email (smtp) and curl calls for external http access. (curl is a popular library to access remote servers programmatically).
In this article we will analyse a bad code example we found in production. A customer in India (we manage the Magento site hosting) raised a ticket that their international shipping costs stopped working. Since we take care of their release process, we investigated to see if this was an inadvertent code change that made it to production. We could find no change. Infact, there was no release made from the day the problem started. So, with permission from the customer, we investigated further.
The bad code
They had overridden the default table shipping with custom logic. The primary reason was that they wanted to give shipping costs in USD for US customers. Magento has concepts of base currency and display currency. All calculations are done in base currency (in this case INR) while the charge was in display currency (USD).
... $to_Currency = urlencode($to_Currency); $url = "http://www.google.com/finance/converter?a=$amount&from=$from_Currency&to=$to_Currency"; $ch = curl_init(); $timeout = 0; curl_setopt ($ch, CURLOPT_URL, $url); curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1); ...
I wondered why it took over 4 years since the bad code was written to break. The reason it finally broke was that google took the URL out of service. The code below would return 0 as it did not find the appropriate tag in the output. So, all shipping was free.
Analyziing the bad code
- Instead of using Magento’s functions for currency conversion, the developer thought of
- Accessing the google finance page
- Scraping the HTML output
- Might be in violation of Google’s terms of service (programmatic access)
- The customer has a one step checkout plugin – this code gets called each step, when anything changes. This is slowing down the checkout page.
- There is no retry or reporting of failure
- The conversion rate used for shipping may be different for the products, as the site conversion rates are updated daily.
Using curl in code that is accessed as the visitor waits is a bad idea. Apart from slowing down user interaction, the probability of an error increases and then the error has to be handled appropriately.