April 12, 2013 Tools 4 comments
April 12, 2013 Tools 4 comments
I’ve always been working in enterprise projects. They usually involve tons of code and sophisticated extensive dependencies inside of code base.
On the other hand I’m keen on keeping code as clean and simple as possible. But how do you find problems quickly within huge set of solutions/projects/assemblies when lot of teams work on those? You have no idea who writes good and who writes bad code or where to look for potential bugs or ugly design.
When you have to analyze a lot of code there is no better static analysis tool than NDepend. There are quite a lot of tools which could perform some analysis here and there, but biggest advantage of NDepend is that everything is in one nice package.
Probably the most exciting feature of NDepend is Code Query LINQ. It allows you to write your own customized queries. Want to see all methods that have cyclomatic complexity higher than 5 and with more than 15 lines of code? Not a problem. Just run this:
As easy as that. Double click on a method and you are already editing it in Visual Studio.
I also like that tool provides analysis on different levels of details. On bigger scale you can identify problematic assemblies. For this purpose there are couple of features. One of them is “Abstractness vs. Instability”. It generates great image with distribution of your assemblies.
Image below was generated for one of projects I’m working on. If most of your assemblies fit into green zone than there is a good balance between abstractness vs. instability. I’m proud to say that code which I write always is in “green zone”.
I went through few of our projects and indeed projects with problematic code base is usually close or is in orange zone. It can be considered bad if you are in “Zone of Pain”. Scott Hanselman has nice post on this and NDepend in general called “Exiting The Zone of Pain – Static Analysis with NDepend”. Check it out.
Another high-scale features would be “dependency graph” and “dependency matrix”. While first one is something that comes with VS (well Ultimate), second one is more sophisticated and not found that frequently in other tools.
This feature gives you complex matrix of all dependencies all the way between assemblies. You can expand it to classes and even methods. On the picture above a dependency cycle is shown. What is great about NDepend is that it always explains in plan English why and what is shown. In this particular situation there was cycle dependency because compiler generated help class for linq query, so I ignored it as I cannot do much about it. But you never know, next time you might have a problem with your code.
When you run analysis NDepend would check against built-in code quality queries. What you get is something as below:
When you click on items on the right you get detailed list of matched classes/methods so you can go through them and verify if anything has to be changed. To be honest even that I’m very scrupulous when it comes to code quality, I discover a lot of new things for myself.
For example I got this in section “.NET Framework Usage”: Collection properties should be read only with an explanation from MSDN:
// A writable collection property allows a user to replace the collection with
// a completely different collection. A read-only property stops the collection// from being replaced but still allows the individual members to be set.
// If replacing the collection is a goal, the preferred design pattern is to
// include a method to remove all the elements from the collection
// (with a call to the ICollection.Clear() method) and then re-populate the collection.
Of course it makes sense, but I just never thought about it. And there are many-many other things which you can learn from the tool only by using it.
During my working experience I started to think that people tend to create too many projects in VS when they finally feel comfortable with doing so. I like when there are as few assemblies as possible. Folders/namespaces are very good logical separation of code, there is no need in assemblies A, B and C if they always run in same application domain and depend on same stuff. NDepend team advices this and also reasons about it. You can read their “white-books”.
Other cool thing about NDepend is that it can be integrated with Visual Studio and Reflector. When you run NDepend it provides you with start page which proposes these add-ins for you. This is very handy.
It is natural that NDepend has console so you can run it from you scripts.
You can see complete list of NDepend features here: http://www.ndepend.com/Features.aspx
I’m afraid that my thoughts were somehow not well structured, I just picked some of the capabilities NDepend has and did not talk much about different use cases, but don’t worry. You will find answers to all your questions on web site: www.ndepend.com/
In my current company NDepend is integrated in build process, in my previous company I used it occasionally to see how we progress over time. Big companies usually take code quality seriously as smallest design flaws now could mean a lot of money leaks in future. Of course everything boils down to employees, but if they have right tools at their disposal you are protecting yourself. This great tool has a price that for sure doesn’t break the bank especially for company that claims to ship high quality software.
Rather than starting this blog post with first excusing about me being not much into IIS. I will share very simple but extremely powerful toolset to be aware how your web application is living its life.
Of course any good application has exception handling and logging in place therefor you know when “shit happens” and possibly able to dig into it, find root cause and fix. Great! But what if you want to know more? What if you want to see some graphics showing distribution of users, their favourite features, pick hours, etc? To some extend Google Analytics could satisfy your needs. I use it for this blog and it is absolutely brilliant there.
You could have better tool in your hands? Plain simple. Plain power.
To enable IIS logging use this boring step-by-step explanation. Or find this self-explanatory nice pictogram
in IIS manager. After enabling it in actions section your logs will be collected accordingly to configuration. (Say for application with high load you might want to change configuration to generate a new log file for each hour.)
Well, first step could be considered as waste of keystrokes for some of you as you find it natural to have IIS logging enabled. But I also know that there are applications running for which no one ever collected any logs and have only preliminary idea how their applications are used and what is happening at all.
Here is bit of my story: We develop HTTP API used by various front-ends. Now we rewrite one of our heavily used endpoints. Therefor it was needed to know usage patterns (GET method parameters) and picks. I was able to quickly find everything out. The most time consuming was to download all those gigs of logs. But as soon as they are easily accessible, everything is piece of cake. Just continue reading…
You would need some tool to start analysing your logs.
Best fit would be Microsoft LogParser. Download it. It is console application which allows to query stuff with SQL-like queries. I said “stuff” because it is not only logs. Have a look on this LogParser architecture diagram:
Output could be also charts (though there is dependency on MsOffice). For example this could be chart of non-200 status codes:
You can utilize this to to build nice reporting system with graphics to be sent to development team and/or managers.
What if you want to quickly analyse something without bothering with console app?
There is Log Parser Studio – an excellent and handy tool.
When you just started it library of different queries is shown to you along with possibility to search among them. So you have a great starting point for your custom queries.
For example here is simple query I just used:
I have found this page to be extremely useful as reference for functions in LogParser.
Be aware that LogParser doesn’t support everything available in SQL. When I tried to write something bit more complex like distinct count with grouping it complained. At least LogParser provided meaningful explanation so I knew that feature isn’t implemented. I had to use temporary file to achieve what I wanted.
You might be in situation when default logging fields are not enough for you:
For example, some token information is supplied in http header. No worries – Install IIS Advanced Logging extension. Now you look for this pictogram:
Setup and configuration is somewhat more complex.
Here is great step-by-step with pictures: http://www.iis.net/learn/extensions/advanced-logging-module/advanced-logging-for-iis-custom-logging
And here is mine shorter example. Say you want to include custom http request header:
There you go. At this moment you can analyse even more information with Log Parser or nice Log Parser Studio.
Hope this post is of help for those who want to know more about their application!
Quick links:
January 30, 2013 YearPlanReport 9 comments
Dear Reader,
I always thought that it is important to keep track of things you are doing and also to have a plan so that you know where you are moving and where you want to be.
This is continuation of my year plan/report thread. I had similar plan for 2010, 2011 and for 2012. Completion of 2010 list was almost 100% successful, completion of 2011 list was less successful. 2012 list completion is somewhere in between. Both 2011 and 2012 greatly changed my life. Same is expected in the year 2013.
Here below is my resolution list for 2013
I tried to keep each point very concise therefore my list may be lacking some of SMART-iness, but in a light of high unpredictability for a long term it would be much easier to remember and follow such a plan.
What do you want to do in this year? Any good suggestions for me?
January 20, 2013 Success, YearPlanReport 2 comments
I tend to have very ambitious plans and even realizing this I never regret because I believe that the higher you mark the higher you are going to reach. Of course there is some frustration and dissatisfaction when it is time for a review. If it is the case for you just neglect all bad and continue looking forward. Life is too short to spoil it with negative emotions. I visited so many places in the past year I wouldn’t believe if you told me this year before. Great and deep feelings of pleasant moments travelling somewhere in Europe together with my wife is the best thing taken from passed year. I hardly remember last piece of code I worked on, but I clearly see golden sun smoothly going down on the beach of Falassarna.
At the beginning of 2012 my life was about to change much once again. I changed my job, but this time it also meant change of a country. While we were finishing relocation paper work I tried to enjoy last month of being unemployed. I went skiing many times and slept well. Besides I released my e-book on design patterns.
Suddenly we appeared in Austria. Here is picture of me in front of my company’s logo at first day of our arrival:
Finding an apartment was a first challenge. After overcoming it and few others we almost stopped worrying. Starting in a completely different country and company with different mindset was extremely interesting and exciting.
After some acclimatization me and wife started to travel. Leveraging Schengen Area we really travelled a lot, I even did not expect that much. You will find complete list later on.
My professional life though did not thrive much in the past year. For sure I’ve improved my skills in many areas. For example my English has improved and a lot of new working experience was gained. I also learned some new to me approaches of delivering software and understood a lot about new company setup and its product available and used by millions. Additionally I introduced myself to few programming languages and did some pet programming.
Year ended with long vacation back in Ukraine together with my parents, friends and relatives. I wish I could be in many places at the same time.
Now lets look at each of the items I planned year ago in my 2012 “Where do you want to be in a Year?”.
– Buy a car in Europe (some used German car)
Car is a whole separate topic. Turns out that keeping car in Europe is quite expensive. Just mandatory insurance costs close to 100 Euro each month. Of course it depends on car size and your driving experience and can be much decreased if you willing to drive Matiz while having 9 years driving background.
I didn’t buy a car in 2012 for myself, but I bought people carrier for my father. It was first time I really leveraged from duty fee. 20% of taxes were returned when I brought back confirmation of exporting car out of EU. Well registering car in Ukraine is tough task and I’m glad I didn’t have to deal with it.
In addition I now hold Austrian driving license and proud to state that I passed an exam with my first try. It might sound ridiculous, but many friends I know here didn’t pass exam immediately, even they had some experience from Ukraine. Even 3 other fellows who tried to pass exam same day with me have failed. One try costs 130, printed license costs 90 and medical check 35. Total 225 euro just to get license if you already hold one from other country. If you want to pass it from scratch it would cost around 1,3K.
If you do the math, renting car is by far more cheaper and preferable over owning one if you only have some weekend trips time-to-time. Unfortunately I cannot drive to Ukraine by hired car. This year I drove Hyundai i40, Hyundai Accent, Opel Corsa, Opel Astra. As of not rented I drove Hyundai i20, Fiat Scudo carrying twice as many people as in normal car and finally I had a chance to drive my Chevrolet before I sold it. I think I like driving.
– Travel though major cities in Austria (Vienna, Salzburg, Linz, Graz, Innsbruck, Bregenz, Eisenstadt, Klagenfurt)
It would be a titanic work to write about all places we visited with my wife during passed 2012 year, but thanks to her there is report on each of our travel. Below is list in chronological order with links to her blog.
I won’t start commenting on those above, because it would take ages. If you can read Ukrainian you have all stories there, otherwise just see some pictures.
– Sport activities (have two-three summer hikes into the Alps & ski in the Alps)
I don’t have a bike. But you can ride one completely free of charge here in Vienna. You just register with your credit card and whenever you use bike less than 1 hour you are not charged. Me and wife used this to spend many summer days with joy and benefit for health. We also had one hike in Alps Reichenau an der Rax. So far I went skiing only once and not in so distant Alps. Want to ski in some “real” Alps.
Generally I’m not completely satisfied with completeness of this point. But environment in Austria is more suitable for active life. People ride, run, walk really lot in dozen of parks.
– Learn German for at A2 level (which is elementary)
Ich glaube meine Deutsch ist noch zu schlecht. I attended one intensive course and also joined language courses offered by my company. Placement test reckons me for A2 level. I doubt it being even close to truth, but I will continue with German in 2013.
– Improve English and rich C1 level (which is advanced)
Probably C1 is pre-advance. For sure I’ve improved my English. Online estimation gives me 7.7K known words versus 4.9K in the beginning of the year. But dictionary is very small portion of what can be considered as proficiency in a language. Fluency in speech is very important. Everyday work in English-speaking environment is a great advantage.
I have extensive blog post on languages I use here in Austria, called “Існує die Frage of Language. Или нет?”.
– Show kick-ass performance at work
For sure I performed really well. Many of my skills were noticed and acknowledged, especially technical ones. On the other hand I’m still lacking in self-confidence and communication skills and maybe some other soft skills. There is already one conference I’m going to visit to improve some of those. But I also doubt that I’m so bad in such things, as I have already been in role of tech lead and it was quite smooth. I think I need more time and motivation which is melting in new company.
– Get promotion (or get clear idea on career opportunities, if not possible)
I think I now have much better idea on career opportunities and raises. It is completely out of synch with what I expected when I just started. Have you seen films in which guys work years to get any promotion meanwhile fighting with others to be pick number one. Of course it is not that severe as in movies, but there are many factors which make it closer to movies than to Ukrainian IT reality.
– In Vienna find local .net community (user group, whatsoever) and join
As per me .NET user group here is marketing driven and besides is held in German so not something I can join easily, at least not for first years. Overall IT market is rather small here.
– Visit TechEd Europe or NDC2012 (if possible because of budged considerations)
I’m too greedy to spend almost 2K euro on conference while videos can be downloaded later. It is exactly what I did. Watched dozen of those. Though I visited small conference kindly offered by company.
– Have new friends in Austria, who share same opinions
Many new friends, but I wouldn’t say that I have any Austrian as my real friend. Also by “same opinions” I largely meant interest in technical topics. It is even worse with that. I tried code and beer session and it didn’t go well. I hope it is just matter of time.
– Write couple of WP7 applications and post them to marketplace
Nothing in marketplace. Played a bit with couple of ideas, but gave up. Not sure I still want to do this. I wrote couple of Win8Metro applications for fun and also gave up. It would be not fair to say that I competed this point.
– Release “Design Patterns” Book – I have 1 month to do so
I’m happy to know that I didn’t leave Ukrainian IT without any of my contribution.
Book has been released and is available on its web site.
– Read 15 books (see my LinkedIn reading list)
I read 7 books and have way too many in progress. Us usual there are Book Reviews on my blog.
– Learn programming language(s). I will start with “7 languages in 7 weeks” and then pick up one for deeper insight (not compulsory from book)
This year I tried many programming languages. Here are my posts on each of the languages from the book:
– Discipline myself to get up at some certain time
We have daily standup meeting at 10:30 so it forces me to be up at latest at 10AM. I cannot say that I failed with this, but also not completely what I wanted.
– Have more public visibility and community impact
This year I had drastically much less public visibility than year before.
I’m planning to have blog post on working experience here in Austria in general and in comparison with Ukraine as it could be very interesting for many of you.
Next year is promising to be life changing once again!
December 17, 2012 .NET, REST, WCF 5 comments
There are few different ways of consuming REST services in .NET
In this post I would like to demonstrate how you can consume REST in C#.
Before we proceed to examples, let’s choose some very simple public REST API to consume. I stopped at this one: http://timezonedb.com/api. It is very simple service providing current local time for requested time zone. After registering you will get some key to access api. In this blog post we will use “YOUR_API_KEY”.
Here is sample response of the service we chose to consume:
<?xml version="1.0" encoding="UTF-8"?> <result> <status>OK</status> <message></message> <countryCode>AU</countryCode> <zoneName>Australia/Melbourne</zoneName> <abbreviation>EST</abbreviation> <gmtOffset>39600</gmtOffset> <dst>1</dst> <timestamp>1321217345</timestamp> </result>
Whichever approach we take, we would need some entities corresponding to the API’s response.
For XML response use cases I prepared following entity:
[XmlRoot("result")] public class TimezoneDbInfo { [XmlElement("status")] public string Status { get; set; } [XmlElement("message")] public string Message { get; set; } [XmlElement("countryCode")] public string CountryCode { get; set; } [XmlElement("zoneName")] public string ZoneName { get; set; } [XmlElement("abbreviation")] public string Abbreviation { get; set; } [XmlElement("gmtOffset")] public int GmtOffset { get; set; } [XmlElement("dst")] public int Dst { get; set; } [XmlElement("timestamp")] public int Timestamp { get; set; } }
For JSON use cases we will use the following:
[DataContract(Name = "result")] public class TimezoneDbInfoJson { [DataMember(Name = "status")] public string Status { get; set; } [DataMember(Name = "message")] public string Message { get; set; } [DataMember(Name = "countryCode")] public string CountryCode { get; set; } [DataMember(Name = "zoneName")] public string ZoneName { get; set; } [DataMember(Name = "abbreviation")] public string Abbreviation { get; set; } [DataMember(Name = "gmtOffset")] public int GmtOffset { get; set; } [DataMember(Name = "dst")] public int Dst { get; set; } [DataMember(Name = "timestamp")] public int Timestamp { get; set; } }
So let’s start!
Here is how you can consume REST using WebRequest:
var urlTemplate = "http://api.timezonedb.com/?zone={0}&key={1}"; var url = string.Format(urlTemplate, "Europe/Kiev", "YOUR_API_KEY"); var request = WebRequest.Create(url); var response = request.GetResponse(); var s = new XmlSerializer(typeof(TimezoneDbInfo)); var timezoneDbInfo = (TimezoneDbInfo)s.Deserialize(response.GetResponseStream());
And if you would need to consume same data but in JSON format, you can come up with following code:
var urlTemplate = "http://api.timezonedb.com/?zone={0}&key={1}&format=json"; var url = string.Format(urlTemplate, "Europe/Kiev", "YOUR_API_KEY"); var webClient = new WebClient(); byte[] downloadedRawResponse = webClient.DownloadData(url); var stream = new MemoryStream(downloadedRawResponse); var s = new DataContractJsonSerializer(typeof(TimezoneDbInfoJson)); var timezoneDbInfo = (TimezoneDbInfoJson)s.ReadObject(stream);
Either way, using WebRequest or WebClient allows for some lower level of flexibility like controlling timeouts, headers and many other things. For example:
Some of the disadvantages of above approach are manual building of a request URL and manual deserialization of a response. Many of you might not like the above code, thus let’s switch to WCF approach, which looks more elegant and robust at the first glance.
Not a secret that we can create REST services with WCF. Effectively this means that we can also create client for other REST services. For this all we need is just to create proxy as if it was our own service. Since, we cannot get wsdl with metadata for our service we have to create proxies manually.
To start we put some WCF configuration in place:
<system.serviceModel> <bindings> <webHttpBinding> <binding name="webHttpBindingCustom" receiveTimeout="00:01:01" sendTimeout="00:01:01"> <security mode="None"/> </binding> </webHttpBinding> </bindings> <client> <endpoint address="http://api.timezonedb.com/" binding="webHttpBinding" bindingConfiguration="webHttpBindingCustom" behaviorConfiguration="tzBehavior" contract="ConsumingRestInNet.ITimezoneDb" name="TimeZoneDbREST" /> </client> <behaviors> <endpointBehaviors> <behavior name="tzBehavior"> <webHttp/> </behavior> </endpointBehaviors> </behaviors> </system.serviceModel>
We already have some configuration flexibility which comes with WCF. Now, let’s define service contract:
[ServiceContract] public interface ITimezoneDb { [OperationContract] [XmlSerializerFormat] [WebGet(UriTemplate = "?zone={zone}&key={key}")] TimezoneDbInfo GetTimezoneInfo(string zone, string key); [OperationContract] [WebGet(UriTemplate = "?zone={zone}&key={key}&format=json")] TimezoneDbInfoJson GetTimezoneInfoJson(string zone, string key); }
(In above method we can avoid having 2 methods by orchestrating our TimezoneDbInfo entity with DataContract in addition to XmlRoot and by having 3rd param).
XML consumption:
var channelFactory = new ChannelFactory<ITimezoneDb>("TimeZoneDbREST"); var channel = channelFactory.CreateChannel(); var timezoneDbInfo = channel.GetTimezoneInfo("Europe/Kiev", "YOUR_API_KEY");
JSON consumption:
var channelFactory = new ChannelFactory<ITimezoneDb>("TimeZoneDbREST"); var channel = channelFactory.CreateChannel(); var timezoneDbInfo = channel.GetTimezoneInfoJson("Europe/Kiev", "YOUR_API_KEY");
You can also go further and implement your own Client class:
public class TimezoneDbClient : ClientBase<ITimezoneDb>, ITimezoneDb { public TimezoneDbClient(string endpointConfigurationName) : base(endpointConfigurationName) { } public TimezoneDbInfo GetTimezoneInfo(string zone, string key) { return base.Channel.GetTimezoneInfo(zone, key); } public TimezoneDbInfoJson GetTimezoneInfoJson(string zone, string key) { return base.Channel.GetTimezoneInfoJson(zone, key); } }
Now consumptions will look like piece of cake:
var client = new TimezoneDbClient("TimeZoneDbREST"); var timezoneDbInfo = client.GetTimezoneInfoJson("Europe/Kiev", "YOUR_API_KEY");
Well, of course! All nasty code went to other classes and the config.
It would be a perfect ending for a blog post. But it is not. On one hand using WCF provides us with great abstraction over service, but on the other hand it is just overhead for doing simple things. Also some people think that coupling generated by WCF defeats the point of REST.
Here is extract of a great answer on SO about what exactly is RESTful programming:
Really, what it’s about is using the true potential of HTTP. The protocol is oriented around verbs and resources. The two verbs in mainstream usage is GET and POST, which I think everyone will recognize. However, the HTTP standard defines several other such as PUT and DELETE. These verbs are then applied to resources.
To leverage all of this potential Microsoft has built System.Net.Http.HttpClient.
HttpClient is inside of namespace System.Net.Http but nuget package is called Microsoft.Net.Http. So don’t get confused. If you add the package it will simply reference System.Net.Http in your project. Nuget page says:
“This package provides a programming interface for modern HTTP applications. This package includes HttpClient for sending requests over HTTP, as well as HttpRequestMessage and HttpResponseMessage for processing HTTP messages.”
Here is how we can use HttpClient:
var urlTemplate = "http://api.timezonedb.com/?zone={0}&key={1}&format=json"; var url = string.Format(urlTemplate, "Europe/Kiev", "YOUR_API_KEY"); var httpClient = new HttpClient(); var streamTask = httpClient.GetStreamAsync(url); var s = new DataContractJsonSerializer(typeof(TimezoneDbInfoJson)); var timezoneDbInfo = (TimezoneDbInfoJson)s.ReadObject(streamTask.Result);
Code above looks pretty much the same as when we used plain WebRequest. But HttpClient is much more advanced and adopted for consuming REST services. For example, it has methods: GetAsync and PostAsync. Reading and sending custom headers is much more simplified. Here is great post with many examples of using HttpClient: http://www.bizcoder.com/index.php/2012/01/09/httpclient-it-lives-and-it-is-glorious/
So, are there any other possibilities to consume REST in .NET?
Yes. There are dozen of libraries out there implemented exactly for that, though I’m sure that a lot of them cannot be considered as good candidates.
[Edit 2015-Sep-2016] People often mention Restsharp and Hammock libraries.
Hope this post comes handy for you!
December 16, 2012 Book Reviews No comments
This is a review of a book called “Seven Languages In Seven Weeks”, which I have started reading quite long time ago. Maybe I could have finished it in seven weeks, if I only was reading it chapter by chapter and not in between of other books.
I have found couple of very interesting feedbacks on this book, some of them even criticizing. Bad critics mostly were about languages selection, concentration on very simple stuff in Days 1 and 2 and jumping to cool stuff only in Day 3, also many complained about some important features missed.
I guess such kind of opinions come from people who either have tons of experience or either are complainers by their nature. Either way, though I agree that the book is not giving solid picture about each of the languages, I don’t think it was its purpose! As per me intension of the book was to introduce readers to interesting programming concepts represented in those 7 languages and encourage to actually code something in each of them. Author says “If you simply read this book, you’ll experience the flavor of the syntax and no more.” and it is complete truth. I know it because, for instance, I skipped coding in Erlang thinking that I will do it in the end, but it didn’t work that smooth.
I tried to have blog posts on each of the languages, but I didn’t strictly follow home works, as some guys did. For example, Ben Nadel has posts for each of “days”.
Here are my posts on each of the languages from the book:
Some of posts are not part of the book’s reading process. BTW, list sorted by how much each of languages appeal to me.
I have answer up-front, copied from my comment to similar question. Here you go: “… it always depends on your needs. If you are interested to quickly go through couple of interesting languages I would recommend this book. Though book is not always easy to follow. Also when you read always do home work. If you want deep insight into one-two languages or comprehensive explanations or step-by-step samples this book is not your choice.” I still keep the same attitude about recommending it, but if someone expects a short answer, than it is going to be – YES.
December 13, 2012 Erlang, Languages No comments
The one I didn’t get. But don’t worry, I can “kill” myself and “spawn” another me to try once again.
Not sure if I have to repeat some of the definitions given to this language, because I doubt that my readers read only this blog and never heard about Erlang. But who would start searching for “Erlang” if you are already here, so to avoid this dilemma I just copied one of its definitions later on.
Erlang is great and hard language at the same time. Its syntax easily looks somewhat alien to many developers, not saying about normal people, who are capable of reading only few human languages. On the other hand ideas behind Erlang are just astonishing. “Let it crash” concept works, because there is no shared state between processes, and if something crashes you just restart stuff, not worrying about overhead as processes are lightweight. And how does this sound to you: dynamic language in which you can change code on the fly? I don’t think you can allow for downtime when you are in a rocket. Not sure if NASA uses Erlang, but many telecom companies use it for sure, which resulted in birth of Open Telecom Platform (OTP) – a library for telecom applications.
I’ve found following explanation very sensible:
Erlang was developed at Ericsson and was designed from the ground up for writing scalable, fault-tolerant, distributed, non-stop, soft-realtime applications. Everything in the language, runtime and libraries reflects that purpose, which makes Erlang the best platform for developing this kind of software.
Use Erlang if you want your application to:
- handle very large number of concurrent activities
- be easily distributable over a network of computers
- be fault-tolerant to both software & hardware errors
- scale with the number of machines on the network
- be upgradable & reconfigurable without having to stop & restart
- be responsive to users within certain strict timeframes
- stay in continuous operation for many years
Please visit http://veldstra.org/whyerlang/ for more “why Erlang?”.
This or some similar question often is very interesting when its about some exotic or small language. Hard to answer, but I’ve found this really nice site: http://roberto-aloi.com/languagesintheworld/#. Try it out to figure out who is coding Erlang/Haskell/Scala/… in your country.
In my Haskell post I wrote “I’m too new to Haskell to talk about some advanced features and to write programs which are over 10 lines of code.” I can ensure that now I can write Erlang programs which are more than 10 lines of code, but I won’t be able to confidently talk about most of aspects of this language either.
I can write larger programs, because I wrote one. Pitfall here is that I don’t completely understand how it works. I believe this is due to the fact, that I’ve chosen wrong problem to solve with this language. Erland is not really build for stuff like “run this for 10 seconds”, but rather for stuff like “that’s your message, deal with it”. Though, I could easily be wrong.
I decided that my first Erlang program will be “sleeping barber” problem, which I’ve already done in Clojure (BTW, there is small bug, spot it!). Once again:
Problem called "sleeping barber." was created by Edsger Dijkstra in 1965. It has these characteristics:
- A barber shop takes customers.
- Customers arrive at random intervals, from 10 to 30 milliseconds.
- The barber shop has three chairs in the waiting room.
- The barber shop has one barber and one barber chair.
- When the barber’s chair is empty, a customer sits in the chair, wakes up the barber, and gets a haircut.
- If the chairs are occupied, all new customers will turn away.
- Haircuts take 20 milliseconds.
- After a customer receives a haircut, he gets up and leaves.
Write a multithreaded program to determine how many haircuts a barber can give in 10 seconds.
Counter – does nothing smart except of counting number of customers with new haircut
Barber
-module(barber). -import(counter,[incr/1]). -export([loop/0, cuthair/3]). loop() -> receive {Pid, Counter}-> timer:sleep(20), Pid ! "haircut done!", counter:incr(Counter), loop() end. cuthair(To, Barber, Counter) -> % make barber work synchronously Barber ! { To, Counter }, receive BarberService -> BarberService end.
Barbershop
Crazy stuff. For example, take a look at how I implemented continuous generation of customers. It is tail recursion function, which takes 10000 as starting WorkTime and generates customer after 10-30ms of thread sleeping, then calls itself with WorkTime minus time needed to send customer to barbershop. It continues until function is out of WorkTime. Similar I do for barber_work_day.
-module(barbershop). -export([loop/3,customers/2,barber_work_day/4]). loop(FreeChairs, Barber, Counter) -> receive { customer } -> loop(FreeChairs-1, Barber, Counter); { barber } -> loop(FreeChairs+1, Barber, Counter); { free_chairs_count, To } -> To ! { chairs, FreeChairs }, loop(FreeChairs, Barber, Counter) end. barber_work_day(WorkTime, Barbershop, Barber, Counter) when WorkTime < 1 -> 1; barber_work_day(WorkTime, Barbershop, Barber, Counter) when WorkTime > 0 -> receive { start } -> self() ! { start }, X = 20, FreeChairs = get_free_chairs_count(Barbershop), case FreeChairs of _ when (FreeChairs < 3) -> timer:sleep(X), Barber ! { self(), Counter }, Barbershop ! {barber}, barber_work_day(WorkTime-20, Barbershop, Barber, Counter); _ -> barber_work_day(WorkTime, Barbershop, Barber, Counter) end end. get_free_chairs_count(Barbershop) -> Barbershop ! { free_chairs_count, self() }, receive { chairs, FreeChairs } -> FreeChairs end. customers(WorkTime, Barbershop) when WorkTime < 0 -> 1; customers(WorkTime, Barbershop) when WorkTime > 0 -> receive { start } -> self() ! { start }, X = random:uniform(21) + 9, timer:sleep(X), FreeChairs = get_free_chairs_count(Barbershop), case FreeChairs of _ when (FreeChairs > 0) -> Barbershop ! {customer}, customers(WorkTime-X, Barbershop); _ -> customers(WorkTime-X, Barbershop) end end.
Program
Here I just initialize random, create processes and kick-off generation of customers and barber’s work day.
{A1, A2, A3} = now(). random:seed(A1, A2, A3). Counter = spawn(fun() -> counter:loop(0) end). Barber = spawn(fun barber:loop/0). Barbershop = spawn(fun() -> barbershop:loop(3,Barber,Counter) end). Customers = spawn(fun() -> barbershop:customers(10000,Barbershop) end). BarberWorkDay = spawn(fun() -> barbershop:barber_work_day(10000,Barbershop,Barber,Counter) end). BarberWorkDay ! {start}. Customers ! {start}. counter:get_count(Counter).
Un-obviously it executes slightly longer than 10 seconds (12-15), so when I call counter:get_count(Counter) exactly after 10 seconds I’m getting slightly lower numbers than expected, so I just call get_count in console until number stops growing with some very realistic number, like 434.
Now you can blame me for my dumbness, because it is really a lot of code for quite simple problem and it took me good 6+ hours to implement.
Links:
I really hope you liked this post! If true, instead of blaming me, you are welcome to share your own experience with Erlang.
November 30, 2012 Clojure, Languages 2 comments
(defn big [st n] (if ( > (count st) n) true false)) ; usage (big "is length of this string longer than 15?" 15)
Day 1: Function that identifies collection.
(defn collection-type [col] (cond (vector? col) (str "vector:") (list? col) (str "list:") (map? col) (str "map:"))) (collection-type [1]) (collection-type (list 1 2)) (collection-type {:chewie :wookie :lea :human})
Day 2: An unless with an else condition using macros.
(defmacro unless [test body] (list 'if (list 'not test) body)) (macroexpand '(unless condition body)) (unless (> 1 10) (println "Did you really think that 1 > 10?"))
Day 2: Type using defrecord that implements a protocol.
(defprotocol Person (writeName ) (writeAge )) (defrecord PersonImpl [name age] Person (writeName [_] (println name)) (writeAge [_] (println age)) Object (toString [this] (str "Name=" (writeName this) "& Age=" (writeAge this) ))) (def andriy (PersonImpl. "Andriy" 25)) (writeName andriy) (writeAge andriy) (println andriy)
Hey! Stop scrolling! :)
Day 3: Sleeping barber problem.
Problem called “sleeping barber.” was created by Edsger Dijkstra in 1965. It has these characteristics:
- A barber shop takes customers.
- Customers arrive at random intervals, from 10 to 30 milliseconds.
- The barber shop has three chairs in the waiting room.
- The barber shop has one barber and one barber chair.
- When the barber’s chair is empty, a customer sits in the chair, wakes up the barber, and gets a haircut.
- If the chairs are occupied, all new customers will turn away.
- Haircuts take 20 milliseconds.
- After a customer receives a haircut, he gets up and leaves.
Write a multithreaded program to determine how many haircuts a barber can give in 10 seconds.
My solution:
(def counter (agent 0)) (def chairs (agent 0)) (def workingTime (agent 1)) (defn haircut [x] (do (Thread/sleep 20) (println "...haircutting...") (+ 1 x))) (defn customer [x] (if (< x 3) (do (send counter haircut) (println "I'm next!") (+ 1 x)) (do (println "I went home. This barber shop sucks!") (- 1 x)))) (defn waitUntilEndOfTheDay [x] (do (Thread/sleep ( * 10 1000) ) (println "[ Clock ticked end of working day ]") (dec x) )) (send workingTime waitUntilEndOfTheDay) (while (pos? @workingTime) (do (Thread/sleep ( + 10 (rand-int 21) )) (send chairs customer))) (println "Barber has finished the day giving " @counter " haircuts.")
…
…haircutting…
I went home. This barber shop sucks!
…haircutting…
I’m next!
…haircutting…
I’m next!
I’m next!
[ Clock ticked end of working day ]
…haircutting…
Barber has finished the day giving 365 haircuts.
nil
November 25, 2012 Personal No comments
I’m not only reading books & blogging about them. Of course these two things require lots of computer resources :), but I also do some programming and simply sit in front of my laptop, which sometimes requires much more resources, especially if sitting is virtual.
In blog post “My new Dell Studio XPS 16 (1647) laptop” I wrote “So looking at the pictures above it is seen that bottleneck of my new laptop is hard disk and memory speed. This means that when something will require accessing hard disk (loading something into memory, working with svn, etc) I will not gain performance. Sadly, but I can do nothing about this.”
Well, I can!
After:
I think it is pretty much obvious what happened to my laptop. It got two presents from Amazon:
Samsung MZ-7PC256B/WW 256GB SSD (2,5’’, 256MB Cache, SATA 6.0Gbps)
Corsair PC1333 8GB (1333MHz, 204-polig, 2x 4GB) DDR3-RAM Kit
While 8Gb of memory and SSD it is not something that can surprise someone these days I feel very happy about my purchase and confident that current performance is enough for me at least for 1 year.
I’ve been thinking if it worth posting my journey of migrating to new hard drive, which includes screwdrivers, aches of system image restoring, backups in clouds and on my external 2Tb drive, ending with bullet points, aka. recommendations for you. But you are not stupid, and internet is full of this crap. Sometimes I’m just getting sick when watching primitive “unpack” videos on youtube, so I hope you didn’t get sick because of my post. I just wanted to share my happiness with you!
November 22, 2012 Book Reviews, UnitTesting No comments
I always wanted to read some comprehensive book on unit testing, therefore book “The Art of Unit Testing: With Examples in .Net” appeared in my list of books to read. It has been more than 1 year since I planned to read it, finally it took me only 2 days to read it – yesterday and the day before yesterday. Sometimes comprehensive things are not that comprehensive as you imagine them or… maybe with time topic is no longer that vast for you.
Nevertheless, I remember my first months of my first job as Software Developer. During one of my first team meetings question of failed Unit Tests was raised. Our clients were really concerned about quantity of tests and reasons behind tests failing during nightly builds. I clearly remember that passionate discussion and someone saying “… or are there guys who don’t know what Unit Test is?” and loud laugh after that. I made smile on my face. I maybe heard once or twice about such combination of words, resulting in abbreviation UT, but it didn’t ring a bell. I wasn’t brave enough to ask. Now I think I wasn’t one in that room who didn’t know, otherwise why would we had problems in the first place?
Because of coincidences and my eagerness, when I was about to leave many considered me as internal expert in Unit Testing. No surprises, I have many posts on UnitTesting.
Reading this book forced me to think twice about some of the testing techniques I use. Probably I changed my mind about some code I write, both in test and outside. I took some notes for myself.
Good indicator if book is for beginners is if it has something like “right click on…” – Yes, this book has few mouse clicks.
Roy introduces many definitions. Some of them are bit contradictional. For example, it might look like there are fakes, stubs and mocks while reading the book, but at some point of time you read this “A fake is a generic term that can be used to describe either a stub or a mock object (handwritten or otherwise), because they both look like the real object.” At least Martin Fowler thinks that fake is different from stub and mock. It is something I also don’t like about definitions in UnitTesting, they are blurred. Every faking mocking framework has its own interpretation and word “mock” is too much overloaded.
As per me, there are some things, which might look not completely professional for the book writer. I mean phrases like this one: “When all else fails and your code is hard to test, you have three choices: use a “super” framework like Typemock Isolator, change the design, or quit your job.” I hope you know why Typemock is highlighted as well. :)
Sometimes stuff is over explained. For example, “One test calling another breaks isolation and introduces a dependency” and then goes explanation why this is bad idea with lots of bullet points. Well, I wouldn’t even think about mentioning stupidity of doing such things.
Book “Working Effectively with Legacy Code” is referenced really often. It worth reading it. I even have hardcopy of it, but only read few pages.
Book is really easy to read. It is straight, well structured and formatted. I enjoyed reading it.
Caution: this list is my personal, for you it might look completely different.
– I tend to write extremely testable code, which often results in overengineered design with low percentage of “private” code. Roy recommends to not test methods, which are better left private to code under test.
– Stop overspecifying unit tests.
– One mock per test. I would like to violate this rule less frequently.
– Ideally one assert per test.
– Think more about applying some global testing techniques, like separation of integration tests from unit tests, or fast from slow, etc.
– Utilize more syntaxes and capabilities of testing/mocking frameworks.
Do I recommend the book?
In short, YES. If you are just starting with Unit Tests this book is excellent for your learning and I highly recommend it. If you have developers in your team who need to learn Unit Testing give them this book. Finally, read it yourself, at least scroll parts 1 and 2, read part 3 and slowly scroll part 4.