inside upstairs working area 2

Category: ‘Development’

Looking for a new scrum master

July 9th, 2010 | published by Thomas Karsten 2 Comments

In scrum, the scrum master is an essential role. A scrum team that does not have a scrum master should better call itself a team working together on one project, rather than a scrum team. The role of the scrum master is clear, but how would you decide about who is going to be the scrum master in a team? What would be the best way according to scrum?

Recently in one of our teams we were looking for a new scrum master. There were basically two options.

Let the manager decide

When we started with scrum in our company more than two years ago, the team’s manager made the final decision about who is going to be the scrum master in the team. This is a clear decision, and the manager would have the possibility to install a scrum master whom he knows and whom he trusts.

No, let the team decide

But, wait, what does the scrum master have to do with the manager? The scrum master is a team member and is fully dedicated to the team, the scrum master serves the team.

That’s why we were thinking of letting the team members decide who will become the team’s new scrum master, rather than keeping them outside of the loop. This has several advantages:

  • The team acts as a team
  • Team members concentrate on team decisions
  • Team members learn to self-manage themselves
  • Team members understand that their voices are important

Since the team members are actively involved in the decision, it is more likely that they accept the result than if somebody from outside of the team appoints the scrum master.

Having a vote

After listening to the two different options, the team eventually decided to go with the second option. We scheduled a meeting for the election and we even prepared ballot papers with the names of the team members listed. Before the vote, we discussed again about the tasks and duties of “the perfect” scrum master and we also agreed that the new scrum master should prove themselves during a probation time of five sprints (almost four months in our case).

During the vote, each team member had one main vote and one second vote. The second vote would have helped us in case two or more team members received the same number of main votes. The election was held anonymously (which is very easy to achieve with a room big enough). We counted the votes for each team member and finally had a new scrum master for one of our teams.

Conclusion

I am satisfied with the process of our election and how the team discussed this matter. Luckily, the team was already very experienced and also had several good candidates for the new scrum master.

Concluding, I have to say that although it is not a big deal to have an election for the scrum master, I also did not find any sources that described this as a common practice. I was curious to try that out and fortunately the team was open for this opportunity and very curious, too.

TheNetcircle at Symfony Live 2010

February 21st, 2010 | published by Arnaud "Boby" Seilles No Comments

Last week was held in Paris the second Symfony Live conference. Over 2 days, 350 (!!!) participants listened to 20 sessions; covering different subjects like usage of Symfony events, introduction to GIT and the first presentation/release of Symfony 2. It was a great gathering of the framework users but also of PHP and Open Source enthusiasts. We could exchange our experience with other developers, prepare some future collaboration and enjoy some french food.

Alvaro Videla at sflive2010

This was also the first presentation of our work to the outside world thanks to the session of one of our coworker, Alvaro Videla. His talk was about “Debugging and Profiling Symfony applications” presenting the tools developed and/or used in the company to run our main project. It also introduced some performance issue we had to deal with during our deployment of symfony 1.0 and 1.2. This was the first time the company’s work is publicized openly, due to its “special” nature, and the feedback is quite good so far, encouraging us to share more about our work.

The highlight of the conference was the first preview release of Symfony 2 (note the upper case S). This new version focused on speed and flexibility. By getting rid of the magic (magic methods, calls…) and using a few patterns (like dependency injection), the framework matures to a totally new level. Doctrine 2 was also revealed and follows the same path of speed/quality focus as well; this is very encouraging and I hope it will push for an increase of quality and reconnaissance in the PHP world. The final release is still far ahead, planned for late 2010, (beta available on github) but this already sounds very promising.

Another important point was the choice of using some Zend Framework components (logger, cache) instead of reinventing them; showing that collaboration, and not competition, is possible between the different frameworks. This is also quite interesting for the community; let’s see how it develops.

Stay tuned!

Saving pandas with nginx/memcache

August 17th, 2009 | published by Mauro Stettler 2 Comments

During the time when we were building the server environment for a new version of one of our community pages, we tested many different server applications and architectures. One thing which brought us a big speed and efficiency improvement was the combination of Nginx, Memcached and PHP-FPM which we are using and which I’m going to line out here.

First I’ll need to introduce the three main components a little.

  • Nginx is an extremely efficient high performance webserver. Actually its not only a webserver, but I call it that since its other functionalities are crap (subjective opinion). For serving HTTP it provides many things like very advanced URL rewriting and content filtering that includes subrequests to HTTP, FastCGI, Memcache and other backends.
    nginx-logo
  • Memcached is a popular and well known small, fast and simple key-value cache. Memcached
  • FPM is a patch for PHP and stands for FastCGI Process Manager. As the name says it manages processes to serve FastCGI. We first tried to use the spawn-fcgi process manager that comes with the Lighttpd package, but FPM proved to be more reliable and it has some nice features which spawn-fcgi doesn’t provide. PHP-FPM

In our setup we use Nginx as webserver in front of the environment and first entry point for user requests. For each request to non-static files it creates a FastCGI request and forwards it back to the right PHP Cluster.

Caching makes more sense on static content, so we make it static

On our site we serve a community in which each user has a profile that can be seen by other users. Those profiles are probably the most accessed part of the page, so it makes sense to think twice about how to cache them. Big parts of the profiles are more or less static, the users usually don’t change their profile data every day. So first we had to extract all the more dynamic parts, like the guestbook or the users recent forum posts from the profile by loading them via ajax. Now that we load those things on a separate request, we can start treating the profiles as almost static pages.

First steps with the new environment

In the first few months when we started serving the new version to users as a beta, all the requests to profiles arrived on the PHP cluster as FastCGI requests. To serve a request, PHP loaded the whole framework, checked if the profile was already on Memcache, and if not it generated the profile and stored it on the Memcache cluster. If the same profile got requested again, the FastCGI request went back to the PHP again and the PHP loaded the whole framework again only to check the Memcache.

blog nginx-memcache pic1

Improvement

If a profile got stored on the Memcache by PHP already, it doesn’t make much sense to load the whole, in our case really heavy, PHP framework again just to decide that it doesn’t need to regenerate the profile but read it from the cache instead. Luckily Nginx provides a really nice functionality to do subrequests to Memcache directly.

Probably you can already more or less imagine what we did. And now in detail:

Everytime when a request arrives at the Nginx, it first checks if this is a request for a static file or another subsystem like for example the forum. If not, the Nginx itself checks on the Memcache cluster if a key exists which it generates out of the URI. If it gets a hit, it totally bypasses the PHP by serving the request directly from Memcache.

To implement this, of course we needed to make sure that nothing else might accidentally store a key into the Memcache that might get hit by the Nginx and make it serve nonsense. Maybe it sounds stupid to mention this because its obvious, but honestly it actually happened.

blog nginx-memcache pic2

Enough theory

Thats where the magic happens:

1  location /{
2     if ($request_method != GET)
3     {
4       rewrite . @fallback last;
5     }
6     default_type    text/html;
7     add_header      "Content" "text/html; charset=utf8";
8     charset         utf-8;
9     set             $memcached_key nginx_prefix$uri;
10    memcached_pass  profilememcache;
11    error_page      500 404 405 = @fallback;
12 }
13 location @fallback {
15    /* pass to FastCGI */
16 }

That snippet is a part of our Nginx configuration. On top of that snippet all static requests or requests to other subsystems got catched aleady. So we can be sure that requests which reach the location / are dynamic and belong to the main system which is our PHP framework.

The location @fallback is where the requests have to go if they want to reach the PHP.

On line 2 all requests which are not of method GET get catched, of course we don’t want to have application logic on the Nginx, so they get rewritten to be handled by the @fallback location and sent to PHP.

Lines 6-8 are defining the encoding and content type. Since we don’t store any HTTP headers on the Memcache, but only the HTML output itself, the Nginx needs to know about those things on its own.

On line 9 the variable $memcached_key gets set. This variable name is defined by the Nginx Memcache module, and the variables value will be the key which gets retrieved from the Memcache backend.

Finally, on line 10 Nginx does the request to the Memcache backend. If you now think “How does it know how to reach this profilememcache?”. Profilememcache is the name of an upstream which I defined somewhere above in the config and it includes the IP and port of the entry point of the Memcache cluster.

Another really nifty things happens on Line 11. The Parameter error_page defines what the Nginx has to do in case of a certain HTTP error. If the request on line 10 doesn’t succeed and gets a miss back from Memcache, the Nginx will raise a 404 error. Thanks to line 11, the 404 error will let the Nginx fall back to the location @fallback where the request gets sent to FastCGI, and now you know where the second location got its name from.

Does that work?

Yes, it works like hell. We saved our PHP framework cluster from handling hundreds of thousands of requests to which the Memcache already knew the answer. This significantly lowered the machine load, which made the cluster suck less power and saved the pandas.

Waking up a server

April 3rd, 2009 | published by Thomas Karsten No Comments

For one of our web sites we programmed a server that provides us with information about the whole friendship network on this site: Who is friends with who, six degrees of separation information, etc. Back in 2007, we wrote that server in C and since we started using it, it was running with absolute reliability.

Suddenly it stopped working, without any prior warning. It did not crash, the process was still alive. It just did not response to any requests that we sent to it. All requests timed out. And even worse, there was no helpful log information that pointed us to any specific direction we could look for the error.

Check list

The good thing was, since we programmed the server, we already had several points to think about first. On top of a C programmer’s check list is the segmentation fault, that happens when trying to access a memory area that the process does not own. But we could almost exclude this point, since the server would have logged any segmentation fault it did. This point got crossed out.

This left a second point on our check list: Blocking. Our server creates worker threads that deal with each client’s requests. For responding to the requests, all threads are sharing the same information about the friendship network, or, in a mathematical term, the graph. Here we are using mutexes in order to keep the information consistent (by preventing to have more than one writing operation at a time or to have a read request while there was some data written).

Mutual exclusion? Dining philosophers? Race condition? Deadlock?

Read the rest of this entry »

Profiling symfony with CouchDB

February 20th, 2009 | published by Alvaro 3 Comments

During the last two sprints we run in the need to perform statistic analysis to profile a symfony application. As I explained here symfony logs to the file system quite a lot of useful information regarding the request that is processing. We wanted to be able to easily parse those logs and then perform queries to filter data. The data was going to be collected form our productions servers, which means that whatever tool we choose must not impact the performance of the website. We knew that symfony logs to the filesystem which was not an option for our production servers.
Our first attempt was to research Facebook Hive and Facebook Scribe, but we declined the idea. We then thought that we could try to build our own tool, probably writing some daemon in Erlang, but something appeared in our way…

During the research regarding map reduce Wikipedia led me to the mighty CouchDB, which in their words is:

Apache CouchDB is a distributed, fault-tolerant and schema-free document-oriented database accessible via a RESTful HTTP/JSON API. Among other features, it provides robust, incremental replication with bi-directional conflict detection and resolution, and is queryable and indexable using a table-oriented view engine with JavaScript acting as the default view definition language.

I must say this: after seeing some examples about it’s functionality my mind blew off. It was awesome, awesome like in CouchDB :-)

Then the idea popped in my mind:
Why not to build a symfony logger that talks to CouchDB and create some CouchDB views that will produce the statistics? I was at home and It was late at night, but my inner geek told me: let’s give it a try.

Read the rest of this entry »