La Coctelera

in web we trust Fernando Blat's blog, freelance web developer

Categoría: Ruby

14 Julio 2010

The importance of supporting native data types

I'm going to start a new project which can have in very short time hard requirements on database performance: there are two entities, let's say items and users that will be related (a common one-to-many relationship). The question is that this relation is very probable to grow a lot and the item will be related with thousands of users.

In order to avoid having the one-to-many table with millions of rows I have decided to try with some NoSQL solutions, with the good luck that the first that I have tried still keeps me very impressed: Redis is very awesome! It's very fast, extremely easy to use and very powerful. And the set, ordered set or list seem to fit perfectly in my problem.

So I decided to perform some tests:

 total_actions = 100000
 # 10000 actions
 1.upto(total_actions) do |i|
   b = Benchmark.measure do
     subscribers_per_action = 10000
     1.upto(subscribers_per_action) do |user_id|
       $redis.incr "action-#{i}-count"
       $redis.sadd "action-#{i}", user_id
     end
   end
   puts "#{i} / #{total_actions} / #{b.real} / #{$redis.dbsize}"
 end
 

The results are impressive: 10,000 incr and 10,000 adds to a set performed in 2.4 secs approximately. And not only in an empty database. I'm testing it with databases that have a lot of entries and still is performing such well.

So I decided to try the same in a Tokyo Tyrant server. The problem is that Tokyo Cabinet doesn't support datasets, it is a classical key-value storage. So if you want to add elements in a key you have to store them in a YAML, or in a string with a well-known separator, or that way.

The same test with Redis took the double of time with Tokyo Tyrant. I know that 5.7 secs for 20,000 operations is very very fast, but I'm still impressed of the performance of Redis working with data types much more complex that a string. My choice is quite clear.

23 Noviembre 2008

Escrito el: 23 nov 2008 @ 11:43 AM

Categorías: Ruby

Tags: ruby, ibuddy

Comentarios:
10 comentarios

compártelo

Program your i-Buddy with Ruby

This days I have been working on a small library for the i-Buddy device, a small gadget for MSN Messenger lovers, that you can connect to your computer through a USB port and has some functionality like light its head with different colours, light a small hearth, move the flaps and turn left or right.

The main attractive is the price (no more than 25 €) and the simplicity.

The library result of my work is rubi-buddy, and works with Ruby and ruby-usb, and its inspired in the one that developed at 11870.

The library is in progress, because I still have to implement the flap movement. Also, I want to add more examples in the project. At this moment there is only one that checks the response code from La Coctelera and turn the head light green or red.

If you are interested, I encourage you to use it and to add more examples.

19 Agosto 2008

Redefine the run method of Test::Unit::TestCase

A small snippet for testing.

If you want to add some special actions before and after the execution of each test, and don't want to add it to setup and teardown because you will be repeating your code for each unit test and functional test, or because it is a block, you can do an alias_method_chain for the run method:

 module Test
   module Unit
     class TestCase
       
 
       def run_with_my_block(*args, &block)
         Cache.clean # code before 
        
         a_block_that_you_want_to_execute do 
           run_without_my_block(*args, &block)
         end
         
         # Code after
       end
 
       alias_method_chain :run, :my_block
 
     end
   end
 end
 

You can redefine it at the beginning of your test_helper.rb for example.

Note that this code is only for Rails, becaus of the use of alias_method_chain function.

15 Enero 2008

Escrito el: 15 ene 2008 @ 10:30 PM

Categorías: Ruby

Tags: cache, memcached, ruby

Comentarios:
3 comentarios

compártelo

Comprendiendo las estadísticas del Memcached

Memcached (o Memcache) incorpora un sistema de estadísticas interno que nos permite conocer el estado del demonio, su capacidad restante de almacenamiento, uso, conextiones, etcétera.

Para acceder a él a través del cliente de Ruby, por ejemplo, basta con cargar una consola en el entorno deseado e invocar al método stats del objeto de caché.

Por ejemplo, si nuestra configuración es la siguiente:


   CACHE = MemCache.new 'localhost:11211', :namespace => 'wadus_fragments'
 

Podemos utilizar el objeto CACHE de la siguiente manera:


   pp CACHE.stats
   {"bytes"=>746532339,
    "pid"=>10303,
    "connection_structures"=>19,
    "time"=>1200349556,
    "limit_maxbytes"=>1073741824,
    "cmd_get"=>689486,
    "version"=>"1.1.12",
    "bytes_written"=>3296488315,
    "cmd_set"=>265986,
    "get_misses"=>265168,
    "total_connections"=>1238,
    "curr_connections"=>17,
    "curr_items"=>66977,
    "uptime"=>56490,
    "get_hits"=>424318,
    "total_items"=>265986,
    "rusage_system"=>95.012555,
    "rusage_user"=>17.16339,
    "bytes_read"=>3226552602}
 

La interpretación de todos estos valores se puede encontrar en la definición del protocolo:

   Name              Type     Meaning
   ----------------------------------
   pid               32u      Process id of this server process
   uptime            32u      Number of seconds this server has been running
   time              32u      current UNIX time according to the server
   version           string   Version string of this server
   pointer_size      32       Default size of pointers on the host OS
                              (generally 32 or 64)
   rusage_user       32u:32u  Accumulated user time for this process 
                              (seconds:microseconds)
   rusage_system     32u:32u  Accumulated system time for this process 
                              (seconds:microseconds)
   curr_items        32u      Current number of items stored by the server
   total_items       32u      Total number of items stored by this server 
                              ever since it started
   bytes             64u      Current number of bytes used by this server 
                              to store items
   curr_connections  32u      Number of open connections
   total_connections 32u      Total number of connections opened since 
                              the server started running
   connection_structures 32u  Number of connection structures allocated 
                              by the server
   cmd_get           64u      Cumulative number of retrieval requests
   cmd_set           64u      Cumulative number of storage requests
   get_hits          64u      Number of keys that have been requested and 
                              found present
   get_misses        64u      Number of items that have been requested 
                              and not found
   evictions         64u      Number of valid items removed from cache                                                                           
                              to free memory for new items                                                                                       
   bytes_read        64u      Total number of bytes read by this server 
                              from network
   bytes_written     64u      Total number of bytes sent by this server to 
                              network
   limit_maxbytes    32u      Number of bytes this server is allowed to
                              use for storage. 
   threads           32u      Number of worker threads requested.
                              (see doc/threads.txt)
 

En concreto cuatro parámetros me han parecido interesantes de observar:

  • el parámetro bytes junto con el de limit_maxbytes: el primero representa el total de bytes ocupados actualmente, frente el máximo.
  • el número de fallos de caché que refleja el valor del parámetro get_misses junto con el número de aciertos get_hits

Los primeros nos permiten saber si hemos llegado al límite el almacenamiento que necesita nuestra aplicación y el segundo nos permite saber si nuestra política de caché es adecuada: diviendo hits entre misses obtenemos la proporción de fragmentos encontrados frente a fragmentos que ya no existían. Un valor de 1 indica que por cada dos búsquedas, una tiene éxito y otra no.

Por supuesto un valor inferior a uno muestra que la caché no sirve de nada (indicaría por ejemplo que necesitaríamos ampliar el Memcache o que tenemos una política de borrado "exagerada").

5 Agosto 2007

Escrito el: 5 ago 2007 @ 10:43 PM

Categorías: Ruby

Tags: ruby

Comentarios:
1 comentario

compártelo

Entendiendo la diferencia entre and y &&

Para aquellos que nos preguntábamos por qué && y and no son lo mismo, y porqué en el Core de Rails prefieren && aquí hay una buena explicación sobre cuál es su principal diferencia, que no es más que un tema de precedencia de operadores.

Supongo que todo es acostumbrarse a utilizar uno u otro.

25 Diciembre 2006

Escrito el: 25 dic 2006 @ 12:13 PM

Categorías: Ruby Humor

Tags: humor, navidad, ruby

Comentarios:
2 comentarios

compártelo

Feliz Navidad en Ruby

Perdonad la flojera que ha invadido a este blog últimamente, se le debe haber contagiado del autor.

Y volviendo al tema que nos atañe, felicita tus Navidades con Ruby:

print "#{def r(x);rand(x);end; C = "\033["}2J#{C}0;0f#{C}32m"; w=r(20).to_i+13
 h=w-r(10).to_i; h.times { |line| puts " " * ((w / 2) - (line / 2)) + 
 (1..line+1).collect { r(rand(12)) == 0 ? "#{C+'5m' if Time.now.usec % 2 == 0}#{C}#{r(7) + 
 31}m*#{C}0m#{C}32m":'='}.join}; print "#{C}33m"; 3.times{ puts (("x" * (w / 6)
 ).center(w)) }; puts "#{C}0m\n", "Merry Christmas From Ruby Inside!"

Visto en el Calendario de Adviento de Ruby.

17 Diciembre 2006

Escrito el: 17 dic 2006 @ 11:56 PM

Categorías: Ruby

Tags: ruby, gem

Comentarios:
1 comentario

compártelo

Wirble: coloreado y autocompletado de sintaxis para la consola de Ruby

Leído en Ruby Inside:

gem install -y wirble

Y luego editar en nuestro directorio $HOME un fichero .irbrc con el siguiente contenido:

require 'rubygems'
 require 'wirble'
 Wirble.init
 Wirble.colorize

Si arrancamos el irb dispondremos de autocompletado y coloreado de sintaxis.

3 Diciembre 2006

Escrito el: 3 dic 2006 @ 01:12 PM

Categorías: Ruby Humor Citas

Tags: ruby, humor, citas

Comentarios:
7 comentarios

compártelo

¿Un libro de Ruby en castellano?

En un hilo de la lista de Rails en español sobre la existencia de un libro de Ruby en castellano:

Programar en Ruby sin saber inglés es como irse a la Feria de Abril de Sevilla sin conocer a nadie. Puedes hacerlo, pero no es tan divertido.

Ale dixit.

Y ahora en serio, mi humilde opinión coincide con la de Ale: Ruby es un lenguaje de programación que tiende al lenguaje natural, que permite construir sentencias de programación que suenan como frases.

No conocer el inglés te impide llegar a mimetizarte con el propio lenguaje, y, aunque no es imposible programar así, sin duda es bastante más incómodo.

Conclusión

Si quieres programar aprende inglés, y si quieres entrar de lleno en el mundo web, aprende inglés, que la iniciativa la llevan los anglosajones y nos sacan unos cuantos años, además.