Performance Matters!

22 Mar

Performance Matters!

Here are the slides from my talk on Performance at http://rubyconfuruguay.org

  Below you can find the mentioned references and tools.

Why does performance matter?

Google Search uses site speed in search Ranking Marissa Mayer at web 2.0 The Google Gospel of Speed Nielsen Norman group on web response times Articulo pdf de la Unversidad de Nebraska sobre tolerancia de dos segundos

Tools to measure:

jMeter Rails guides for performance testing

Gems that will help you detect problems

Query Reviewer Rails Footnotes New Relic Perftools

Test

The xkcd comic that inspired the test example. The subscription link to Ben Orenstein’s emails with suggestions to speed up the test cycle.

Remember!

Measure, know where to look and most important write enough unit/functional tests to avoid breaking havoc on your app!


Ruby And Exception Notification

1 Feb

The problem

In a project we are working on right now we needed to have a way to be notified when a crash on our application occurred, something that we though was going to we easily archived by a simple:

  gem install 'notify_me'

After some research we came to the conclusion that it was not going to so easy.

Existent solutions

If we where on rails we would just have done:

  gem install 'exception_notification'

And even tough i tried to run that gem outside of a rails application with some hacking i was unsuccessful and even i could have done it i felt like there where way too much dependencies for a simple notification email.

Exception Notification Dependencies


i18n
multi_json
activesupport
builder
activemodel
erubis
journey
rack
rack-cache
rack-test
hike
tilt
sprockets
actionpack
mime-types
polyglot
treetop
mail
actionmailer
eventmachine
multipart-post
faraday
faraday_middleware
hashie
json
http_parser.rb
simple_oauth
twitter-stream
tinder
So we started to take a look to other options like sinatra-enotify, it didn’t seem to cover our needs (you can’t even configure the email settings) and did not seem like a production ready gem. We also investigated bugsnag and airbrake again they seemed overkill for a simple email and even required an account (in some cases paid) on an external site to get them to work.

Path Taken

Having not found any existent solution and in the spirit to do some research and learning i embarked in the process of writing a simple exception notification gem for ruby.
Thus [RU]by [S]imple [E]xception [N]otification (rusen) was born.
The idea behind it was that it should we really easy to pickup and use but also provide more advanced options and control if it was needed.
The simplest way to use it is the following:

  gem install 'rusen'

then use it inside of your ruby script:
  require 'rusen'

  Rusen.settings.email_prefix = '[ERROR] '
  Rusen.settings.sender_address = 'some_email@example.com'
  Rusen.settings.exception_recipients = %w(dev_team@example.com test_team@example.com)
  Rusen.settings.smtp_settings = {
    :address => 'smtp.gmail.com',
    :port => 587,
    :domain => 'example.org',
    :authentication => :plain,
    :user_name => 'dev_team@moove-it.com',
    :password => 'xxxxxxx',
    :enable_starttls_auto => true
  }

  begin
    method.call
  rescue Exception => exception
    Rusen.notify(exception)
  end
It also comes with a rack middleware, how to setup that and the more complex ways to use it can be found in the documentation.

Conclusion

In the end it was an enjoyable experience in witch i learned a lot of things and the end result is something simple yet flexible that we can actually use in our production environment.


We proudly announce our new website

17 Oct

We want to thank everyone who was involved in this challenging and creative process, and truly hope you like the results. We certainly enjoyed the creation.

Part of the celebration was thanks to Mariana de Carli, who brought some delicious homemade cupcakes. Thanks Mariana! They were yummy!

Please have a look at our new website, and leave us your comments if you have a chance.

Keep on mooving!


Moove-iT is meeting up.

16 Oct

We say YES to the Tech Meetup taking place this 3rd November, 2012 in Montevideo, Uruguay.

This is an opportunity for you to share your IT experience and learn from others, grow as professionals and constantly improve your work.

Through the story of seven speakers, we will learn from the experience of professionals from Uruguay and the region in the most different environments.

Some of the topics are: Development Processes (teamwork, scrum, Agile, continuous integration, code review, continuous delivery, testing, QA), Infrastructure and Production (monitoring, scaling and server redundancy, track changes, versioning, deployment) and Others (remote teams, real experiences).

If you want to share your own experience you still have time to sign up as a speaker (whether you work in a large company or from home). We want to hear from you! You just have to complete the form you will find at www.meetup.com.uy.

The event is $ U400 and you can book your place through “Red Pagos” (collective number 34264). If you are a student, you can request a free pass for the event. Just apply through the event website.

Do you like the idea? We will see you next November 3rd, 2012 at 9:00 am at the Telecommunications Tower (Rondeau Ave. and Guatemala St.).

Please contact info@meetup.uy for more information.

Afiche difusión meetup.uy


Handsoap & testing Web Services

3 Sep

HandsoapIf you’re using the Handsoap gem to implement a web service client you may be interested in knowing how to stub the call to the webservice and returning the xml you want.Here is a quick example showing how to do just that.

 

Let’s dive in!

I used Mocha to stub the methods. But you can use whatever library you like.

When using Handsoap normally you have a class that inherits from Handsoap::Service where you configure the Web Service client.
The aim is to use a xml string to mock the web service’s response.
When we want to call a webservice we use the invoke method supplied by the Handsoap::Service class.
Example:

response = invoke('ns:ReturnAccountInfo') do |message|
       message.add 'ns:UserName', username
       message.add 'ns:Password', password
     end

So that method is exactly what we want to stub. That way we make sure we test all our code, not worrying about the gem’s code and of course without actually hitting the remote web service.

The xml string we would like to get as a response might look like this.

 

<?xml version="1.0" encoding="utf-8"?>
 <soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
   <soap:Body><ReturnMethodResponse xmlns="https://www.myawesomeapp.com/webservices">
     <ReturnMethodResult>
       <string>hello</string>
       <string>world</string>
     </ReturnMethodResult>
     <ErrorCode>0</ErrorCode>
     <ErrorText />
   </ReturnMethodResponse>
 </soap:Body>
</soap:Envelope>

 

You can get this xml string if you print out the response of a webservice call.

Looking for the request call

Digging into the handsoap gem I found that the response object of the Service#invokemethod is the one returned by:

parse_http_response(response)

How does parse_http_response work?

Building the response object

If you look at Service#parse_http_response it calls Service#parse_soap_response_document where you can see how it builds the xml object from the raw xml string.
So this is exactly how we will build the response object for our stubbed method, namely:

xml_string = ‘<xml … </xml>’ # Your webservice response
xml_doc = Handsoap::XmlQueryFront.parse_string(xml_string, Handsoap.xml_query_driver)


This is safe to do since we are using Handsoap’s configuration to parse the string and it will work just as if you are using it in production.
Now again in Service#parse_http_response you can see the final line doing:

return SoapResponse.new(xml_document, response)


So when stubbing we need to respond with:

Handsoap::SoapResponse.new(xml_doc, nil)


But before that, make sure that if you did override the on_response_document method, you will have to call it explicitly since the parse_http_response won’t be calling it for us:

MyWebService.on_response_document(xml_doc)


Finally, we are ready to stub the web service with our xml document:

MyWebService.any_instance.stubs(:invoke).returns(Handsoap::SoapResponse.new(xml_doc, nil))

Bringing it all together

xml_string = ‘<xml … </xml>’ # Your webservice response
xml_doc = Handsoap::XmlQueryFront.parse_string(xml_string, Handsoap.xml_query_driver)
MyWebService.on_response_document(xml_doc)
MyWebService.any_instance.stubs(:invoke).returns(Handsoap::SoapResponse.new(xml_doc, nil)


Now, whenever you call invoke on your web service class, it will respond with the xml string you passed in to the XmlQueryFront#parse_string.


Running Selenium on a Headless server and running tests with PHPUnit

16 Jul

When it comes to functional testing, please have a look at Selenium, a testing framework that provides tools and asserts on a webpage running on a web browser.

The aim of this article is to show you how to set up a Selenium server, with or without Xserver, and run PHP unit tests on a web page.

Before starting you will need:

  • Linux running machine (with or without Xserver)
  • Java
  • Selenium server jar file (can be found here)

You will learn how to install the following:

  • Xvfb (check this) [just if we dont have a Xserver]
  • PHPUnit – PHP – Pear - Selenium TestCase extension (PHPUnit_Extensions_SeleniumTestCase)

I am going to use Fedora for this example, but bear in mind that the only thing that might change in other Linux ditros could be the package manager. [...]


Why Uruguay?

27 Jun

Outsourcing to Uruguay does make sense.

According to CUTI, the Uruguayan Chamber of Information Technologies, Uruguay’s strategic location, cultural affinity and economic stability are some of the key factors that make this country one of the top technology producers in Latin America.

Please have a look at the infographic below for further information.

 


Agile Development on Rails

24 May

Do you want to learn how to make some cool Web developments using Ruby on Rails? Have you searched but you didn’t find a course that fills all your requirements? Moove-It is inviting you to be part of “Agile development on Rails”, our new two months e-learning course.

Using the Uruguayan e-learning platform “Hacé un Click” (http://www.haceclick.com.uy/) we’ve developed a really dynamic course with all you need to know about servers like Ruby, Git, Deployment, Ruby on Rails, Unit Test and Rspec.

The coolest thing about his new course is that it will be based in a real practice case, that is; the entire course designed as a real project so you can have a real time learning experience working directly on the code and see you final results on a real prototype.


HowTo – Create UDFs using Python for your Piglatin scripts

24 May

When using Pig to query and transform the information stored on our HDFS, we might need functions that are not part of the default arsenal of Piglatin (the language used by Pig). But the cool thing about this tool, is that we can actually extend the language using UDFs (or User Defined Functions).

So what’s a UDF?

A UDF is a function that you write in order to extend the language you’re using (in this case: Piglatin).
Even though Pig is written in Java, you can use different languages to create your own UDFs. For this specific example, we’ll discuss creating such functions using the Python programming language.

By default, Pig allows you to define your UDFs on the following languages: JAVA, Python and Javascript. Currently JAVA UDFs are the ones that have the most extensive support, specially since they have access to additional interfaces (such as the Algebraic Interface and the Accumulator Interface) but you can achieve a lot of things using python and JS as well.

If you want more details on how to write UDFs using one of these languages, you can visit the official documentation here [...]


That Big Data problem – Thinking the Hadoop way

20 Mar

What is the “big data problem”?

 

“On the night of July 9, 1958 an earthquake along the Fairweather Fault in the Alaska Panhandle loosened about 40 million cubic yards (30.6 million cubic meters) of rock high above the northeastern shore of Lituya Bay. This mass of rock plunged from an altitude of approximately 3000 feet (914 meters) down into the waters of Gilbert Inlet (see map below). The impact generated a local tsunami that crashed against the southwest shoreline of Gilbert Inlet. The wave hit with such power that it swept completely over the spur of land that separates Gilbert Inlet from the main body of Lituya Bay. The wave then continued down the entire length of Lituya Bay, over La Chaussee Spit and into the Gulf of Alaska. The force of the wave removed all trees and vegetation from elevations as high as 1720 feet (524 meters) above sea level. Millions of trees were uprooted and swept away by the wave. This is the highest wave that has ever been known.“ (quoted from http://geology.com/records/biggest-tsunami.shtml)

Now lets use our imagination a bit, and pretend we’re on a digital world, and that an even bigger wave can be seen on the horizon, only that the wave is made up of 1’s and 0’s. That’s the current status of information on the net right now.

A huge wave of data is being generated every second, ranging from user generated information such as tweets, status updates, uploaded pictures, blog posts, comments, text messages, e-mails and so on to machine generated data, like server access logs, error logs, transaction logs, etc.

And that’s not even the problem, the problem is that we need to start thinking in terms of TB or even PB of information, billions of rows instead of millions of them in order to be able to handle this big wave that’s coming.

[...]