niedziela, 2 grudnia 2012

Retreat


If you know me well then you know that from time to time I try to do something good in my spare time. I speak at Ruby User Group which I love, I try to write Open Source libraries, I was one of the organizers of 1st wroc_love.rb edition and tried to help a little to organize the second edition. But as of today I give up.

I decided to devote all my spare time to fight with my health problems. In last 12 months I was 3 times in hospital, had 2 ear surgeries and as it turned out it was all for nothing. Or at least this is how I perceive it. Because a one tiny infection later and again I am practically deaf in one of my ear.

And that makes me really really sad. So sad that everything requires lot of effort. Working, smiling, everything. And I don't have that much energy when I am sick. I can only imagine how it is to be a healthy programmer. I would have so much time more if I didn't have to fight my illness. And I would love to spend it doing Open Source. I admire everyone who does it. Almost everything that I use for my personal life and in my work is open sourced. Almost all the money I make is earned thanks to solutions built based on Open Source tools. And I always wanted to contribute back. But I've just lost my heart to it. We stand on the shoulders of giants: Ruby, Rails, Postgresql, Redis, Mongodb, ZMQ, Linux, Chef, jQuery, Firefox, Webkit, V8 ... Thank you.

I promise I will be back when it is over. If it is ever over.

piątek, 15 czerwca 2012

Native system notifications in rails applications (development mode)




Let's just say that from time to time you would like to display a notification on your screen of some event that occurred. As an example let's display a request time. The problem occurs when you work in heterogeneous environment and your friends use either linux or mac. In that case you might be tempted to define Gemfile as:


That is not going to work correctly and will lead to problems. Every time you run bundle install on different platform it will resolve dependencies differently and cause problems for your coworkers that are in the second operating system camp. And in worst scenario you will be hit when last Gemfile.lock is committed from Mac but you try to deploy to linux production server using bundle --deployment which is not allowed to recalculate dependencies. You can recognize it by the message "You have modified your Gemfile in development but did not check the resulting snapshot (Gemfile.lock) into version control".

What we basically want to achive is described in Gemfile manual:

"If a gem should only be used in a particular platform or set of platforms, you can specify them. Platforms are essentially identical to groups, except that you do not need to use the --without install-time flag to exclude groups of gems for other platforms."

Except that we want to load different gems depending on ruby platform (that is not the same thing as platform). In other words we want bundler to resolve dependencies considering both libnotify and growl but install only these which are going to work in current environment.


Run once bundle install --without darwin on linux or bundle install --without linux on mac and bundler will store these setings in .bundle/config

Next time you can just use bundle install on your dev machine.

For your production server configure capistrano to skip both of them:


Now we can try to use them in our development mode. We need a way to detect current operating system. There are 2 easy ones that I am familiar with:


I am aware that RUBY_PLATFORM might return "java" but don't care since probably both of them won't work in Java anyway. Finally the small code for displaying a notification on your system which goes into the bottom of config/environments/development.rb so that it is only loaded in development environment (obviously):


Did you like it? Here is what you can do now:

sobota, 5 maja 2012

Apotomo - API done right

During the wroc_love.rb conference I had the opportunity to speak with Nick Sutterer (the original author and maintainer of great Cells and Apotomo gems) and thank him for the architectural choices made for the libraries. He said that I should blog about and help spread the good word instead of just telling him about the things that I like. So, here I am writing this post and keeping my promise.

The architectural choices are not obvious when reading Apotomo tutorial and probably they don't bring so much to most users of the library. Nevertheless they were extremely important to me. If you are not familiar with apotomo, just jump to the official website and Apotomo tutorial to get an idea of how it works.

Here is a little example of what we used apotomo widgets for:


Conceptually in apotomo it all starts in a controller.

But that's a very simple and basic thing you can do with apotomo. It all becomes much more interesting when you realize that the proc used by has_widgets method is not executed once but instead every time there is a request going to the controller. It is executed in scope of controller instance using instance_eval instead of being executed once during class loading with class_eval. And that gives a lot more opportunities and flexibility.

In my project every user was given some roles (like Admin, Chef, Vice-Chef) and widgets belonged to those roles. UserRoles and RoleWidgets was dynamically stored and retrieved to/from database and the UI changed accordingly. Even such details like widget width (100% vs 50%), position (left vs right) and their order could be configured per every role on database.

So, what's the moral of the story ? Please try to design your API with flexibility in mind. It might be quite easy to achieve it if you create new object every time it is needed and use instance_eval instead of doing all the meta-programming once with class_eval when loading the class for the first time. And if you worry about performance, please don't. Many times the bigger possibilities out-stand the probably negligible performance hit.

sobota, 25 lutego 2012

[PL] Nothing about programming


Everything You Always Wanted to Know About Fibers * But Were Afraid to Ask

I recently found out that most Ruby developers that are not familiar with Event Machine usually knows very little about fibers. So I decided to share some very trivial examples that will help you understand them quickly. Each example should push your knowledge and imagination about possible usages a little further. Tell me in comments if that worked for you.

Example 1:


What happened here, you may ask. We created new fiber. At the begining it was stopped. So we resumed it. It executed and ended. Trying to resume it again did not work. Actually that was very similar to Proc except that we can always call Proc multiple times.

Example 2:


While being inside fiber we can yield. That means that fiber stops and control goes back to the line that resumed fiber. We resumed the fiber second time starting from where we escaped (yielded) previously.

Example 3:


As you see, you can return value from fiber when yielding out. That value is accessible to code that called fiber (resumed it). How is it accessible ? Well "resume" simply returns what was yielded from resumed fiber.

Example 4:


Nothing extrordinary here. When fiber is fininshed the value of last statment is returned. Like always in ruby.

Example 5:


Just using iterators inside fibers to yield multiple times and outside to resume fibers multiple times to get you comfortable with doing that :).

Example 6:


This fiber can be resumed infinite number of times. It returns randomly generated value to the caller.

Example 7:


As you can see in this example now you can resume the fibers in whatever order you like. You are in charge of execution order. That's usually the point of using fibers.

Example 8:


Why would you ever want to use fibers ? Well consider this example. You have an algorithm that requires to somehow operate on the result of two different kind of operations. One of them is very tough like computing prime numbers (obviously my solution to that could be way more optimized, but that is not the point). The second kind of operation is very easy (computing square in our example, trivial). You could use threads for doing that but threads are scheduled by Ruby VM or operating system and you have almost no power over them. If we computed prime numbers in one thread and squared numbers in another thread then probably we would end up with lot more squared numbers computed than prime numbers.

In our examples every algorithm is given enough time to compute one, next sequence number and then yields. That gives the scheduler (our code) the opportunity to resume another fiber and compute next number of second sequence . Fibers give you the ability to manually schedule peaces of codes and avoid the need to synchronize threads for accessing shared data structures.

Example 9:


Two fibers can use the same shared variable without using any kind of lock for accessing it because we are guaranteed that only 1 fiber is executing at the same time. So every fiber can be sure that no other fiber changed anything in any variables until Fiber.yield is called next time.

Example 10:


If fibers are your jobs then you need to know if they are unfinished and can be resumed again or finished and calling them again would lead to "dead fiber error". Usually this is not known upfront by the scheduling code but rather recognized based on returned value.

Summary:

I hope that now you know something, something about fibers (at least more than before reading this post) and it is not a black magic anymore. They might not be of any use to you but that is definitely not an excuse for ignoring them completely.

Caveats:



sobota, 21 stycznia 2012

Model logic

We all know that our models should be fat and controllers / views are supposed to be simple (dumb). Recently I was asked why such code should be put into model :


What's wrong with using Ad.unverified_ads.last in the view. I don't have an answer for the "why?" question often asked by beginner programmers. You can trust your more advanced colleagues that it should, that it is beneficial and will make your life easier or stick with your current way, wait until the application gets bigger, and regret it later. Anyway, I always ask myself one question when I have to decide whether something probably is part of the model. Would I need this method if the application had different way of interacting with the user. If it was a console application or just an API serving JSON to some clients. Given the previous code example. Can I image an usecase that requires me to display last unverified ad to user interacting with the program via command line. Yep, I can. Is it possible that I am gonna need it when serving JSON response? Might be. So I think I would make it part of the model.

How about this one:


Would I use it in CLI ? Nope. When rendering JSON ? Not really ? So... Not a model.

Third example:

I think it can be part of your model but does not have to. Even if this method could be useful in console application or for JSON api it looks like it still fits better in the presenter layer (or helper) instead of model layer.

I know that the examples are extremely simplified but that's not the point. When you are in doubt, just image that you would also have to implement the same app in completely different environment that has nothing to do with HTML. Which parts would you still keep in your model ? Asking myself such questions helps me make right decisions.

sobota, 14 stycznia 2012

Active Reload - mission accomplished

Once upon a time I was working on a big Rails application and every time I wanted to fix some CSS or JS issues I had to wait for a few seconds to reload the page which was making me really unproductive and unmotivated. I knew I was not the only one who suffered from such delays when working with big Rails apps. I occasionally spotted some comment about it here and there, in blog comments, reddit, rails forums. There were also other solutions that tried to fix the problem rails-dev-boost, rails_dev_mode_performance but had their limitations. So I decided to do something about. My initial trials were overcomplicated, error prone but eventually I created something that was working fine for my project. And it made my productive on that project again and much more happier. The solution was so incredibly simple (in concept and in materialization) that I still find it astonishing that no one before released such thing as a gem.

The fact that it was working for me meant nothing and proved nothing also. The gem needed to be tested by wider audience which would probably be very skeptical about it. So I had to have their attention somehow. I wanted to show to other people how I felt when using this gem, what is the profit of using it but I could not show the application that I was working on at that time. Also that would not convince anyone since well YMMV and nobody would be able to repeat my performance research without access to my application. My friends from DRUG (Dolnośląski Ruby User Group - the organizers of wroc_love.rb conference) advised me to check out if it works with spree . It turned out to work pretty well so I recorded two videos showing the difference. I used bbq which uses capybara under the hood to driver the browser automatically and make the test independent of human activity which could disturb it. I also provided exact steps to repeat so that everyone could challenge me.

Michał Łomnicki invented this catching phrase "Rails development mode 300% faster" and used it to submit a post to reddit. I did not want initially to make this solution part of Rails code because I knew that at that moment it would be probably hard for me to convince Rails core team that it is useful, working  and could actually solve some people problems. My plan was to make a gem, hope for some buzz, fix bugs, hope that Rails core won't ignore it and will merge it into Rails itself. It all stared to work...


I must admit I wasn't the best gem maintainer. I could not fix some bugs, merging some pull requests took me too much time, testing the gem with newest Rails releases happened often weeks later. Guilty as charged. But it does not change the fact the gem seemed to be helping other people and most of the time did its job well. I wish I could somehow count the amount of time that it saved.

Than one day I woke up and saw that Jose Valim merged Active Reload into Rails and also fixed some bugs during that process and even added very simple solutions to problems that I could not solve (ex.: how to quickly detect changes on database caused by migrations when model file did not change - his solution: observe also schema.rb file which is regenerated after running migrations). And it was like: OMG my gem is in Rails :). And it happened exactly as I planned.

It convinced me that:
  • after so many years you can still have impact over general Rails shape,
  • even when you only spend couple of hours trying to make it better;
  • it does not matter if people know you or not, you can still make a difference and become somehow known in this process;
  • sometimes you only need dozes of lines of code instead of hundreds to make a difference;
  • If it is important to the community, Rails core will notice it and incorporate;
  • If you have some idea: make gem, advertise it (movie is must have in Rails world, sorry) and watch what will happen, maybe something bigger than you imagined. Maybe nothing but it will be still worth trying.
Since Active Reload is now part of Rails ( Announcement ) and it did its job I will no longer maintain it. If it works for your Rails 3.0 or 3.1 application, good. If it does not, try upgrading to 3.2 and maybe you will have a better luck. If there is any problem with this solution in Rails 3.2, create an issue on github. It is now in the hands of Rails community. We are now all responsible to remember that Rails was supposed to allow us developing applications quickly. That's why we felt in love with it. We wanted to make blogs in 15 minutes, not hours.


Die Active Reload, long live Rails.