Pietro Menna2023-02-27T16:39:12+00:00http://pietro.menna.net.brPietro Mennapietro@menna.net.brLessons learned during a Developer on Duty: Observability2021-09-12T22:20:00+00:00http://pietro.menna.net.br/personal/2021/09/12/dod-observability<p>A month ago, I had the chance to participate as “Developer on Duty” for my team. Developer on Duty basically means you are “On-call” and that you can receive a call if there is any system down or production down problems. When I got called, I became grateful that we had some great tools to analyze issues.</p>
<p>You are running a cloud system, which is live, and you have real customers using the system. Unfortunately, you do not have access to run a debugger on these systems (and I guess we should not have). How to analyze the problem then? Observability (o11y) is the keyword here: infer the internal state from knowledge of its external outputs. As output, we use not only the error messages regular users are getting but also the logs.</p>
<p>I became familiar with two tools: Kibana (reading Logs) and Dynatrace (Tracing). I am also aware the system has some monitoring functionalities to analyze CPU load, database, etc. But I have not yet become familiar with those tools.</p>
<p>Kibana supports several ways to search for information about a problem, the most common search I use is correlation_id. With it, I can see all the logs that a request triggered to be raised.</p>
<p>Dynatrace allows the use of the same correlation id, not only on the log of the application but also across components, such as databases, other systems, etc.</p>
<h2 id="log-level-per-instance-or-service">Log level per instance or service</h2>
<p>Specifically, on one of the nights I received a call, I noticed I could not get enough information for a given problem. I got lucky and found out that it was possible to change the log level of a given instance that is running. The log level of an application is usually a parameter, or environment parameter applications read and allows setting the minimum log level to be sent. By increasing the log level, it was possible to get more details about the problem.</p>
<h2 id="conclusion">Conclusion</h2>
<p>If possible, get familiar with the logging, tracing, and monitoring tools available in your environment. They can be convenient in some situations, and learning to use them should not take too much time.</p>
Why use message queues?2021-08-03T20:20:00+00:00http://pietro.menna.net.br/personal/2021/08/03/why-use-message-queues<p>A few weeks ago, I interviewed a candidate who worked with Message Queues, and I asked why you would use one? What is the architectural advantage of using it? The candidate did not know how to answer, so I explained what I thought they were for, and this post is because maybe it is helpful to others.</p>
<p>Let say you just opened a pizza restaurant and hired two employees: a waiter and a cooker. You just have 2 tables. Since you just opened the shop, the waiter just walks to the kitchen and screams the order. Everything is alright, you can fulfill all orders in time, and everyone is happy. The cooker must start working on what he just hears, and as soon as he finishes, he calls the waiter to take the delicious pizza to the table.</p>
<p>This is what we call synchronous communication. The waiter is not waiting for the cooker to fulfill the order, but he waits for an acknowledgment.</p>
<p><img src="/public/message-queue-1.png" alt="message-queue-1" title="Shouting method looks like" /></p>
<p>Let’s say your restaurant grows due to the great pizza you deliver, and you are still using the same system (shout + acknowledgment). At some point in time, the cooker in the kitchen might be so busy that it misses one order here. As a result, your restaurant has unhappy customers, and you lose popularity. So, you invent a system that works better: you waiter has a piece of paper that describes an entire order for a given table that he leaves in the kitchen. As soon as a whole order is ready, the guy in the kitchen calls the waiter to fulfill the order.</p>
<p>This new system has two advantages: you stop losing orders because people working in the kitchen were too busy to listen to new orders and allow more than one cooker to work on the same orders. In addition, waiters now leave the orders in an “orders queue,” and kitchen workers process “orders.” Waiters are not particularly interested if someone is there to pick orders immediately in the kitchen now.</p>
<p><img src="/public/message-queue-2.png" alt="message-queue-2" title="Shouting method looks like" /></p>
<p>Ok, now you saw the queue word.
Message queues allow asynchronously exchanging messages between services. This means that the service that posted something is not there waiting for something to happen to continue, or we miss something if the processor is available to take a message. We do not even know if the message will be processed at all.</p>
<p>An HTTP post is similar to the shout method. It is synchronous communication that can be lost if the service is too busy processing something else. With the message queue, you stop losing messages by decoupling the systems.</p>
<p>Now you may have noticed I added more waiters and workers in the kitchen picture. This is because you no longer care about “who” processes the order. Instead, it may now be a group of services or replicas of the service, allowing you to scale the number of processors you may have. This is what it means when people say message queues will enable you to “scale.”</p>
<p>There are other points that I could mention, but the idea was to share this simple explanation with a story. I hope you enjoyed it.</p>
What I learned with COVID-192020-04-16T14:00:00+00:00http://pietro.menna.net.br/personal/2020/04/16/learnings-from-covid-19<p>Wherever you were browsing on the internet during the last 6 weeks, you probably already read about COVID-19. In any sense, you probably have not read anything positive about. I am not trying to say that is something positive, but during these almost 6 weeks of confinement I learned a lot of stuff that otherwise I would have not learnt.</p>
<h1 id="remote-working">Remote working</h1>
<p>I have already worked remote in the past, but never to this degree. Mostly I stayed home some days or worked on a customer site during my professional life until today. The most important pieces I learned about working remote are:</p>
<ul>
<li>You need few items, but all of the basics are mandatory: a computer, internet connection, and phone. Then comes the space: you need a quiet room, and headphones. Without any of the above, it is pretty much impossible to work from home extended times.</li>
<li>In order to keep social relationship with peers, you must communicate proactively and with intent. This means you have to prepare before the call, but also start by talking non-work-related topics (at most 5 minutes).</li>
<li>Differentiate what requires a synchronous communication and what can be left (and it is best) to have as asynchronous communications. There are many tools that development teams use on their daily work, but they are not always used properly. Example: e-mails, instant messengers, product management tools, shared file stores, etc.</li>
<li>Closed door, open calendar: You are remote, nobody can see you (closed door), but keep your calendar updated. Colleagues and peers should be able to reach us by looking into our calendars and being able to schedule time for synchronous communication (MS Teams, Slack Calls, Skype, Zoom).</li>
<li>Use the same todo list for personal stuff and for work related stuff. This means you will use the same calendar tool to schedule such events.</li>
<li>Set clear expectations on how you prefer people to contact you, and respect how people would like to be contacted. Some people prefer that you contact them via Slack, other prefer scheduled meetings on Outlook, etc.</li>
<li>For synchronous meetings, send an Agenda at least a day before.</li>
<li>Use video when possible</li>
<li>And yes, the benefit of doubt when you read and e-mail that sounds harsh. This is key. Have empathy with remote colleagues, and always assume best intentions. It is the best for the long run. And remember, one day you might be the person who was understood as harsh and you would prefer to have also the benefit of doubt.</li>
</ul>
<h1 id="be-grateful-for-what-you-have">Be grateful for what you have</h1>
<p>I just realized how many things we just take for granted: be it having a job (many people lost jobs), be it having food (before the crisis, I used to eat every day outside, now at home we have to cook), be it being able to stay with your loved ones (not everyone can do that at the moment, think on medical doctors or others that have to stay away from family). Not everyone has access to this, and realizing that is somehow conforting.</p>
<p>I am grateful that I work with very professional and nice people as peers. The company I work for is very concerned about our wellbeing and my direct boss is super comprehensive on all the needs I may have. Also, my peers and colleagues are super fun and are fully adapted as well to work remotely the best they can. It is good to be able to count with such vibe.</p>
<p>I am really grateful to be employed, but also, I am grateful that I am able to everyday look at my daughter having breakfast. When I did go to the office, I almost never had this chance. This is a unique opportunity for me. I am grateful to had the chance to experience this.</p>
<h1 id="conclusion">Conclusion</h1>
<p>Overall, I think the crisis is a real learning opportunity. We can choose to use it to learn stuff and go out stronger and smarted than we were before it, or just complaining about it every day. I try to choose the first always.</p>
The role of a senior developer2019-07-12T21:20:00+00:00http://pietro.menna.net.br/personal/2019/07/12/the-role-of-the-senior-developer<p>Last year, around August/September, I got the chance switch my role at work. I became a Development Manager, which is something similar to Engineering Manager in some places. It is not a technical possition such as “technical Leader” or “Development Lead”.</p>
<p>Since I got to this role, I heard sometimes the question “What do I need to do to become a senior developer?”. I do not know if I have a real answer to this question since it depends a lot in different factors.</p>
<h1 id="what-it-means-to-me-being-a-senior-developer">What it means to me being a senior developer?</h1>
<p>Being senior in something means you have experience in something, you have been exposed to many situations that you had to figure out on your own. I do not mean just technically, I also mean having worked in different roles in different projects, having to deal with conflicts, having to deal with having to eventually help others in matters that you are not an expert, but you wanted to help and learn so you both grow together.</p>
<p>It is not related to having more knowledge of a technology domain (expert in the libary usage), but knowing how to browse for solutions or whom to ask for help.</p>
<p>It is not about “knowing better” than the junior colleagues, but listening to all ideas and learning from others.</p>
<p>It is not about being the one who always will deliver on time, but to have maturity to say: “I will not be able to deliver in time, but I will be able to deliver up to X point in time”.</p>
<p>It is not about being more aligned with you management structure, but the one who can warn management when something is not right.</p>
<p>It is also not about being the role model or the one that takes administrative tasks. But it is about being involved in more than just code, for example discussing with stakeholders, mentoring peers, helping in interviews for other engineers, etc.</p>
<h1 id="it-depends-a-lot">It depends a lot</h1>
<p>The truth is that it depends on a lot of factors, and it is different everywhere. Some criterias that maybe are useful in many places are: years of experience, knowlegde in the domain you work, interpersonal skills, technical skills, the overall perception you cause on your other peers, how you got into your organization and your initial negotiation.</p>
<p>There are organizations where is common to see a lot of people with the senior title. In this case, what it really means to be senior?</p>
<p>In other places, being senior is a way of recognizing a person.</p>
<h1 id="conclusion">Conclusion</h1>
<p>It really depends a lot and to have a real answer for your own situation, you must analyze your organization.</p>
Never install a database again2016-07-17T23:28:00+00:00http://pietro.menna.net.br/personal/recurse-center/2016/07/17/never-install-database-again<p>Yesterday I went to <a href="http://softwarelivre.org/fisl17">FISL</a> to watch some of the talks. I learned a lot in just a few hours and got impressed how networking and events such as conferences can make participants to learn such amount of content in just few time.</p>
<p>Some of the talks I went to listen were about <a href="https://www.docker.com/">Docker</a> and others about UX and <a href="https://www.mongodb.com/">MongoDB</a>.</p>
<h1 id="docker">Docker</h1>
<p>The <a href="https://twitter.com/paulodiovani">speaker</a> of the docker talk I went to see, said an interesting phrase: “Never install a database again”. His point was that Docker allowed us to have the service we need without having to install in a local environment again.</p>
<p>Some years ago, when we wanted to to have development environments which we could share with someone else, we created a <a href="https://www.vagrantup.com/">Vagrant</a> image. Which was a virtualized, full installation of a operating system, the databases required, and the libraries required.</p>
<p>Whenever we needed to upgrade a component in that image (lets say a new version of ruby), you needed to create a new image and distribute it again. We can say that the image would be large.</p>
<p>Docker allows to share a container (which happens to be a minimal image of a operating system which only provides a single service). By service we can assume a “Database”, or a “Web Server”, or <strong>any other type of application communicates via network socket</strong>.</p>
<h1 id="docker-composer">Docker composer</h1>
<p>What most impressed me was that in a 1 hour time, it was shown how to generate 4 development environments by using <a href="https://docs.docker.com/compose/">Docker Compose</a>.</p>
<p>With Docker Compose it is possible to define the services which interact with you application. It is basically a way to define multi-container environment for your application in which each container contains a part of your application.</p>
<p>In order to define the multi-container environment, the developer has to set up a <code class="language-plaintext highlighter-rouge">docker-compose.yml</code> which described the application. More information <a href="https://docs.docker.com/compose/">here</a>.</p>
<h1 id="not-installing-mongodb-as-example-but-having-available">Not installing MongoDB as example (but having available)</h1>
<p>Cool, but I just want to benefit to install easily a Database, not using composer or anything like that yet! Let`s try MongoDB.</p>
<p>In order to achieve this, we can follow the steps:</p>
<ol>
<li>
<p>Install Docker, in my case, I installed <a href="https://docs.docker.com/engine/installation/mac/">Docker for Mac</a>. There is also the <a href="https://docs.docker.com/engine/installation/windows/">Windows</a> version, and of course the linuxes versions which depends on your linux flavor you use.</p>
</li>
<li>
<p>All next steps are on the terminals. Ensure your deamon is running.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> $ docker version
Client:
Version: 1.12.0-rc2
API version: 1.24
Go version: go1.6.2
Git commit: 906eacd
Built: Fri Jun 17 20:35:33 2016
OS/Arch: darwin/amd64
Experimental: true
Cannot connect to the Docker daemon. Is the docker daemon running on this host?
</code></pre></div> </div>
</li>
</ol>
<p>If you get that, you need to ensure that Docker deamon is running. In that case you will get something similar to:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> $ docker version
Client:
Version: 1.12.0-rc2
API version: 1.24
Go version: go1.6.2
Git commit: 906eacd
Built: Fri Jun 17 20:35:33 2016
OS/Arch: darwin/amd64
Experimental: true
Server:
Version: 1.12.0-rc2
API version: 1.24
Go version: go1.6.2
Git commit: a7119de
Built: Fri Jun 17 22:09:20 2016
OS/Arch: linux/amd64
Experimental: true`
</code></pre></div></div>
<ol>
<li>
<p>Get the image you are looking for. Also if you have a chance, browse for it on <a href="https://hub.docker.com/">Docker Hub</a>. For mongo it is <a href="https://hub.docker.com/_/mongo/">here</a>. For getting the image, use <code class="language-plaintext highlighter-rouge">docker pull</code></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> $ docker pull mongo
Using default tag: latest
latest: Pulling from library/mongo
8ceedfe606fc: Already exists
de56a622d4ac: Already exists
6f6965220a2d: Already exists
290580b9cb91: Already exists
74518025c1d4: Already exists
7caf7e3d8fb7: Pull complete
dcfe9afaf914: Pull complete
b3c5b8f22de4: Pull complete
b66f9b8214cf: Pull complete
Digest: sha256:fc89af57055910959cd94c3f852150fc0dafc95e2b081 b57d109711dbcf0d506
Status: Downloaded newer image for mongo:latest
</code></pre></div> </div>
</li>
<li>
<p>You are ready now, just run the image my forwarding the port of the service you need:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> $ docker run -d -p 27017:27017 -p 28017:28017 mongo
curl localhost:27017
It looks like you are trying to access MongoDB over HTTP on the native driver port.
</code></pre></div> </div>
</li>
<li>
<p>It worked!</p>
</li>
</ol>
<p>Now I have a working mongodb service running on my machine and I am ready to learn Mongo!</p>
<h1 id="conclusion">Conclusion</h1>
<p>It is possible to avoid the hassle of installing software which is not always necesary on your computer by using Docker. Docker also provides mechanisms for developers to create virtual environments which are replicable on any machine which runs Dockers thanks to the container technology.</p>
The problem of eBooks Business Model2016-01-20T16:08:00+00:00http://pietro.menna.net.br/personal/recurse-center/business-models/books/2016/01/20/ebooks-business-model<p>The expectation of readers of eBooks is different to the readers of paper books. They are completely different technologies and its users have different expectations. The expectation also depends on the type of content of the book/eBook.</p>
<p>Currently there are some publishers and authors who struggle to see the difference, they keep publishing eBooks as if they were only <em>books</em>. In some cases, example for technical content eBooks (example: eBooks about a programming language), this should be <strong>unacceptable</strong>.</p>
<h2 id="different-expectations-for-different-models">Different expectations for different models</h2>
<h3 id="novels">Novels</h3>
<p>Reading novels on a paper book feels a lot better than reading on a eBook. You feel the paper, you can carry anywhere, and also the reader is usually pride and wants to show what novel is currently reading.</p>
<p>Novels also do not get updated, it is rare (or inexistent) the case in which a novel has a new version. Usually only a few words gets changed from one print to another, the <strong>content</strong> is the same.</p>
<p>When a reader buys a novel as eBook, its expectation is usually to read on a <a href="http://www.amazon.com/kindle">Kindle</a> device, or his <a href="http://www.apple.com/ipad/">iPad</a>, or any other digital media. His expectation is that the content is readable on his device, and that the content is the same as the printed book.</p>
<h3 id="technical-books">Technical books</h3>
<p>When a reader buys a technical book, because he wants to learn a new technology, he expects that the book is accurate and the examples contained on it work. It is understandable, that a typo may have gotten through and go to an errata on a web site.</p>
<p>When a publisher/author charges extra for the digital version, the expectation is the same as if it was a novel book, plus that the eBook will be updated with the new prints. If the reader downloads the latest version, it should be reading a version in which the errata is already corrected.</p>
<h2 id="the-technology-business-model-of-booksebooks">The technology business model of books/eBooks</h2>
<p>Technology is always evolving, and changes to software, programming languages are inevitable. Some changes are also not backwards compatible. As an author, it is great opportunity to get a technology from the begin and publish a book about it.</p>
<p>If the initial book is successful, and lot of changes occurred to the software/programming language, it is an opportunity again to make money! You can release a new version of the book with updates! Specially if you wrote a very good previous version, lots of people will buy the new version.</p>
<p>For a reader, it may be interesting to buy the new version if many things changed, but otherwise it will just stick with the old one.</p>
<h3 id="ebooks-as-opportunity">eBooks as opportunity</h3>
<p>For authors, an eBook should be an opportunity to keep the readers updated with any small change that may come. This is a way to keep them reading the <strong>content</strong> which was initially sold in a more accurate way.</p>
<p>When a book contains examples which are to be run on a computer, they must be working! If a small change on the language software breaks an eBook, the author has an opportunity to make a small correction and release it in the latest version of the eBook. This practice is better than keeping an errata or a “companion”.</p>
<h3 id="just-buy-the-next-edition">Just buy the next edition</h3>
<p>This is what you would usually hear as a reader, but in days that <em>subscription model</em> is what we hear, and that re-generating an eBook should take the same amount of time that writing an errata, you should have the most accurate content available.</p>
<p>We should actually pay for <strong>new content</strong>. For example, a new version is released which requires major rework for the author, we should pay for it. Maybe not the full price, but it is even understandable.</p>
<h2 id="my-bad-experience">My bad experience</h2>
<p>When you buy an eBook about <a href="https://www.bignerdranch.com/we-write/cocoa-programming/">Cocoa Programming for Mac OS X</a>, you expect the examples to work. You do not expect to read the eBook, watch the examples not to compile, and read a <strong>companion</strong>.</p>
<p>The people from <a href="https://www.bignerdranch.com/">Big Nerd Ranch</a> actually have the <strong>best books</strong> for Cocoa and iOS, and they are very professional to release the companion guide.</p>
<p>Unfortunately, my expectation nowadays is not a companion, but a new eBook version which contain the changes from the companion.</p>
<p>I bought the previous edition of <a href="https://www.bignerdranch.com/we-write/cocoa-programming/">this</a> book , and decided to buy the current version because of the change from <strong>Objectice C</strong> to <strong>Swift</strong>. I wouldn’t have bought if I knew I would have to read a book in which the examples do not compile!</p>
<p>It does not compile not because of the authors are careless, but I think it is related to be published by <a href="https://www.informit.com/">informit</a>. I have not yet seen an eBook from this publisher to be updated. I suspect this bad practice comes from the publisher which has an outdated business model.</p>
<p>Don’t get me wrong, <a href="https://www.informit.com/">informit</a> publishes great books from awesome authors, but this practice of not updating is not correct!</p>
<h2 id="my-good-experiences">My good experiences</h2>
<p>The expectations I have mentioned in this post comes from the books and eBooks I buy from the <a href="https://www.pragprog.com/">Pragmatic Programmers</a> site.</p>
<p>Their good practices are:</p>
<ul>
<li>Update eBooks instead of errata.</li>
<li>Small updates even on code examples, creates a new version of the eBook, and this is usually free.</li>
<li>New versions of eBooks, usually come as an upgrade of the previous version, sometimes with discounts.</li>
<li>The reader receives updates about the eBooks he owns.</li>
</ul>
<p>There are other authors and publishers which also follow these practices. This is what I expect as a technology guy who reads technical stuff.</p>
<h2 id="summary">Summary</h2>
<p>The content of a book determines the expectation of the eBook version. Some publishers still works in a Business model which is no longer the ideal for the reader point of view for technical eBooks.</p>
<p>Maybe as readers we should demand more from the publishers and cheer the publishers and authors who play nice.</p>
My understanding of Microservices2015-11-28T15:10:00+00:00http://pietro.menna.net.br/personal/recurse-center/microservices/2015/11/28/my-understanding-of-microservices<p>No matter where you look into the Internet, of the trends you always read the same buzzwords: Big Data, DevOps and Microservices. I plan to explain what I understood the talks I watched <a href="https://www.youtube.com/watch?v=wgdBVIX9ifA">here</a>, <a href="https://www.youtube.com/watch?v=C4c0pkY4NgQ">here</a> and some others, but I am in no way an expert on the subject.</p>
<h1 id="monoliths-and-microservices">Monoliths and Microservices</h1>
<p>Before begin, lets imagine that we are a shop with three “components”: Finance & Accounting, Distribution and the Store. A component would be a working group of the organization represented in the system.</p>
<p>Usually applications are built as <strong><em>monoliths</em></strong>. In our example, it means, that in the same system, we have all the components together. They share the same source code, technology stack and datastore. It also runs everything on the same server. So imagine that we have to reset the system because of a problem with the Distribution; the “Finance & Accounting” will also be down during the system reset.</p>
<p>Oh, I forgot, there is the IT group which is in charged of all the applications!</p>
<p>Lets imagine now the same shop, but that runs as <strong><em>microservices</em></strong>. We have the same “components” with the only exception of the IT group. Instead, each of the groups has like 3 - 4 people working on only on their specific application. For example, the “store” group, only works on the “store”. The people from the <em>Store</em> may decide to use <em>NodeJS</em> and <em>MongoDB</em> while the <em>Finance & accounting</em> people would prefer <em>Ruby on Rails</em> and <em>Postgres</em>.</p>
<p>Each group decides its own technology stack, and if one of the groups needs to reset their system, not all groups are offline because of it.</p>
<p>It is time to add another buzzword: <a href="https://en.wikipedia.org/wiki/Conway%27s_law">The Conway`s law</a>, which states:</p>
<blockquote>
<p>“…Organizations which design systems … are constrained to produce designs which are copies of the communication structures of these organizations…”</p>
</blockquote>
<p>Back to our example, everyone agrees that in the shop all the “components” needs to talk to each other in real life. They all depend on each other so the “Store” is successful.</p>
<h2 id="in-microservices-world-every-user-request-is-a-sequence-of-requests">In microservices world, every user request is a sequence of requests</h2>
<p>Let’s say I am an external user, I want to buy something on the “store”, when I buy something on the store, I do not know and I do not care if they are all in one system. I just expect my goods to be delivered and to pay for it.</p>
<p>When I buy something, behind the scenes, the <strong>Store component</strong> would communicate with the <strong>distribution component</strong> in charged with the shipping. Also after getting billed, probably the F&A component would get notified.</p>
<p>As you can see in this example, since they are all different systems (maybe even computers), as a user I do not know that. Also, you can see that the system is <strong>distributed</strong>.</p>
<h1 id="lets-talk-in-developers-terms">Let’s talk in “Developer’s terms”</h1>
<ul>
<li><strong><em>RESTful Architecture</em></strong>: the communication should occur in RESTful way. In many places you can read this as the <strong><em>Smart endpoints, dumb pipes</em></strong>.</li>
<li><strong><em>Distributed Data Governance</em></strong>: each of the components decides its technology stack, also its data store. This is because you can choose depending on the requirements of each component. Remember, not every problem is a nail and not every solution is a hammer.</li>
<li><strong><em>Single Responsibility</em></strong>: The store component, is only responsible for being a good store for customer`s to buy. Nothing else! One Component: one responsibility.</li>
<li><strong><em>You share nothing</em></strong>: A developer from the Store does not have access to the datastore or even code from the F&A component. All the communication should occur via the common interface.</li>
<li><strong><em>Infrastructure automations</em></strong>: Since you own your stack, you probably need to know how to generate your own system and how to run it. Developers probably woud need to have code as infrastructure to take care of its own system.</li>
</ul>
<h1 id="some-of-the-origins">Some of the origins</h1>
<p>It is said that Microservices is a consequence of Conway’s Law and DevOps. It is also said many ideas come from <a href="https://www.amazon.com">Amazon</a>.</p>
<p>In particular, Amazon is known for the <a href="http://blog.jasoncrawford.org/two-pizza-teams">two pizza size team</a> (a team should have no more people than the amount of people who can be fed with 2 American pizzas). This means, the team should have a size of less than 10-12 people, and most important have the <strong>accountability</strong> and <strong>autonomy</strong>to execute its task.</p>
<p>Microservices teams also follow the <strong><em>“Products, not projects”</em></strong> mentality. We can say “Product” is “Component”. Each team should take care of its <strong><em>Product</em></strong> even the operations side: this is also known as the <strong><em>“You build it, you run it!”</em></strong>.</p>
<h1 id="implications--conclusion">Implications & Conclusion</h1>
<p>For developers, everything should be thought from day zero to be externalizable to be able to work on a microservices world.</p>
<p>Also, it has some drawback, since it is distributed system, the problems which may occur are more difficult!</p>
Patterns and Integrations2015-11-12T22:30:00+00:00http://pietro.menna.net.br/personal/recurse-center/2015/11/12/patterns-and-integrations<p>I admit that I am upset that I have to consume an API from a front-end application that reads like methods from something like Java methods. Something like <code class="language-plaintext highlighter-rouge">whatever-domain.com/getBusinessAreas</code>.</p>
<p>I hear arguments like no one will consume the link directly, or access this address directly. <strong>I am still not convinced it is a good practice</strong>.</p>
<h1 id="patterns-patterns-patterns">Patterns, patterns, patterns…</h1>
<p>Why do we have Patterns in the Software Industry? <strong>to communicate with other developers</strong>.</p>
<p>Just like <a href="https://blog.cleancoder.com/uncle-bob/2014/06/30/ALittleAboutPatterns.html">design patterns</a>, there are other types of patterns. The king of Pattern that was violated by the API mentioned before is called an <strong>Integration Pattern</strong>.</p>
<p>There are a lot of Integration Patterns, just to name some: RMI, SOAP, REST, Message Channels, Pipes, and many others. The ones I am interested here are <a href="https://en.wikipedia.org/wiki/SOAP">SOAP</a> and <a href="https://en.wikipedia.org/wiki/Representational_state_transfer">REST</a>.</p>
<h1 id="choosing-between-soap-and-rest">Choosing between SOAP and REST</h1>
<p>##SOAP##</p>
<p>SOAP exposes a service, by using a Service Descriptor (right, the WSDL file). All communication is via this service, and it uses an XML “Envelope”.</p>
<p>SOAP in the web came in disuse. I will not say it is dead, a lot of services still use it. Eg: Jira.</p>
<p>I still believe it might be useful in some scenarios. <strong>But I am quite sure it not designed for UI-centric consumptions</strong> such as browser consumption. So, if a front-end in HTML5 will consume, do not go for SOAP.</p>
<h2 id="rest">REST</h2>
<p>It is an Architecture Style. Every RESTful service must respect certain constraints: Client-Server, Stateless, Cacheable, Layered System and Uniform Interface.</p>
<p>A simple example: putting the previous service to REST.</p>
<p>The example from the beginning of this post, could have easily have been named as: <code class="language-plaintext highlighter-rouge">GET /BusinessAreas</code>. It would retrieve the list of “Business Areas” that exist in the system.</p>
<p>We could have retrieved the details of one specific, like BusinessArea “1” simply by <code class="language-plaintext highlighter-rouge">GET /BusinessAreas/1</code>.</p>
<p>To create a new “Business Area”, we could use <code class="language-plaintext highlighter-rouge">POST /BusinessAreas/</code>. In the body of the POST we send the details required to create one.</p>
<p>To update the details for a given business area, we could use <code class="language-plaintext highlighter-rouge">PUT /BusinessAreas/1</code></p>
<p>At last, in order to delete one Business Area, we could use <code class="language-plaintext highlighter-rouge">DELETE /BusinessAreas/1</code>. The example would have updated Business Area 1.</p>
<p>#Conclusion</p>
<p>The REST approach allowed to remove the ugly <em>camelCase Java like</em>. But actually, the architectural style significantly improves the readability of the service. Imagine you have more entities, they would all follow the same pattern for access.</p>
<p><strong>Does it look simpler?</strong> To me at least, <strong>yes</strong>. It looks a lot better thanks to uniform access pattern gained by following a simple standard.</p>
Jekyll adjustments for Blaggregator post-rc2015-10-19T23:07:00+00:00http://pietro.menna.net.br/recurse-center/2015/10/19/jekyll-adjustments-for-blaggregator-post-rc<p>It has been a long time since I got back from <a href="http://recurse.com">Recurse Center</a>, and only now I realized that everything I write here still will appear on <a href="http://blaggregator.us">Blaggregator</a> (An awesome service that I check out like every two days that contains blog posts from recursers).</p>
<h2 id="how-does-blaggregator-works">How does Blaggregator works?</h2>
<p>Once you subscribe to Blaggregator, it is possible for you to “Add your blogs” to it. By adding your blogs I mean you are able to add feed urls (RSS and Atoms I guess).</p>
<p>I there is a job which grabbs the feeds and parses it to see if there is a new entry.</p>
<h2 id="awesome-so-what-is-the-problem">Awesome, so what is the problem?</h2>
<p>It turns out, I am using <a href="https://jekyllrb.com/">Jekyll</a>, and when I suscribed to blaggregator I added the feed that came with the theme I use. All my posts are going to Blaggregator.</p>
<p>In order to be able to select what gets into Blaggregator, I will need to adjust the file which is generated by Jekyll as <code class="language-plaintext highlighter-rouge">atom.xml</code> or create a new one specially for the service.</p>
<h2 id="jekyll-adjustments">Jekyll Adjustments##</h2>
<ol>
<li>I copied the current <code class="language-plaintext highlighter-rouge">atom.xml</code> to <code class="language-plaintext highlighter-rouge">atom_rc.xml</code>. This way, I will have one full feed for the site, and one only for blaggregator for the RC related posts.</li>
<li>I marked the relevant posts, with category <code class="language-plaintext highlighter-rouge">recurse-center</code>. Each post which shall be included in this new file requires this “tag”.</li>
<li>Added the code which only picks if category contains “recurse-center”. Lines 18 and 27 of <a href="https://gist.github.com/pietromenna/961b86db53beda5e6863">this</a> GitHub gist.</li>
<li>Remember to update your link at Blaggregator!</li>
</ol>
<h2 id="conclusions--maybe-apologies">Conclusions & maybe apologies!</h2>
<p>Maybe this is useful for other recurses which may also would like to select the posts which gets listed in blaggregator. This is the intention!</p>
<p>Apologies if by making this change in my blog all my old posts gets re-published! :-(</p>
Rails 4.2, Vagrant and ... Problems!2015-07-27T22:39:00+00:00http://pietro.menna.net.br/recurse-center/2015/07/27/vagrant-rails-net-issues<p>I started a new personal project. I set up <a href="https://www.vagrantup.com">Vagrant</a> so I can have the “same” development environment across all computers.</p>
<p>The project uses <a href="http://rubyonrails.org">Ruby on Rails</a>, so I set up the line below in the <code class="language-plaintext highlighter-rouge">Vagrantfile</code>.</p>
<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">config</span><span class="p">.</span><span class="nf">vm</span><span class="p">.</span><span class="nf">network</span> <span class="s2">"forwarded_port"</span><span class="p">,</span> <span class="ss">guest: </span><span class="mi">3000</span><span class="p">,</span> <span class="ss">host: </span><span class="mi">3000</span>
</code></pre></div></div>
<p>It means forward port 3000 from the guest as if it was 3000 on the host.</p>
<p>I started up the virtual machine and ran <code class="language-plaintext highlighter-rouge">rails server</code>. From the host I fired up Safari open address <code class="language-plaintext highlighter-rouge">http://localhost:3000</code>. I expected to see my app, but what I saw was:</p>
<p><img src="/public/CannotOpen.jpg" alt="CannotOpen" title="Can`t connect" /></p>
<p>Of course, browsing on the Internet for possible solutions was the next step. All the effort I spent Googling was in vain. In part because I looked for everything in the log which may seem like a problem, like:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>default: The guest additions on this VM do not match the installed version of
default: VirtualBox! In most cases this is fine, but in rare cases it can
default: prevent things such as shared folders from working properly. If you see
default: shared folder errors, please make sure the guest additions within the
default: virtual machine match the version of VirtualBox you have installed on
default: your host and reload your VM.
default:
default: Guest Additions Version: 4.3.10
default: VirtualBox Version: 5.0
</code></pre></div></div>
<p><strong>Totally misleading</strong> and the wrong approach for this particular problem.</p>
<p>##The analysis##</p>
<p><strong>How does <code class="language-plaintext highlighter-rouge">vagrant ssh</code> work but <code class="language-plaintext highlighter-rouge">rails server</code> not? Both rely on port forwarding</strong> This was the starting point question.</p>
<p>I tried listening with <a href="http://netcat.sourceforge.net">nc</a> (netcat) on port 3000 and making a requests from the host. Unfortunately no response again:</p>
<pre><code class="language-Bash">nc -l localhost 3000
</code></pre>
<p>No matter what I sent to port 3000 on the guest, it was not reached.</p>
<p>So nothing to do with Rails, right? <strong>No, but yes!</strong> I don’t know why, but I read the manpage for <code class="language-plaintext highlighter-rouge">nc</code>, and found out that <code class="language-plaintext highlighter-rouge">-p</code> is for ports, by trying <code class="language-plaintext highlighter-rouge">nc -l -p 3000</code> I could reach the guest from the host on the desired port.</p>
<pre><code class="language-Bash">vagrant@vagrant-ubuntu-trusty-64:~$ nc -l -p 3000
GET / HTTP/1.1
Host: localhost:3000
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
If-None-Match: W/"b56dd5f9363ed0f7bd4d11c36d9471dd"
Cookie: _ga=GA1.1.1880364256.1438043513
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_4) AppleWebKit/600.7.12 (KHTML, like Gecko) Version/8.0.7 Safari/600.7.12
Accept-Language: en-us
Accept-Encoding: gzip, deflate
Connection: keep-alive
</code></pre>
<p><strong>But what does Rails have to do with it?</strong></p>
<p>Reading the change log from Rails 4.2 <a href="http://guides.rubyonrails.org/4_2_release_notes.html#default-host-for-rails-server">here</a>. We can find the text below:</p>
<p>“Due to a change in Rack, rails server now listens on localhost instead of 0.0.0.0 by default “</p>
<p>##What I learned##</p>
<p>127.0.0.1 (or localhost) <strong>is not the same</strong> as 0.0.0.0.</p>
<p>The ip address <strong>0.0.0.0</strong> means <strong>all IP addresses on the local machine</strong>. It includes all interfaces, including the virtual interface used by virtualbox.</p>
<p><strong>127.0.0.1</strong> is the “loopback connection”, it is <strong>only be available from the same host/system</strong>. In this case, it was the guest virtual machine. This was the reason why I could not reach from the host. The guest is a different host/system than the guest.</p>
<p>##The solution##</p>
<p>Make rails listed on 0.0.0.0. This can be achieved by running rails server this way: <code class="language-plaintext highlighter-rouge">bin/rails server -b 0.0.0.0</code>, or by changing file <code class="language-plaintext highlighter-rouge">config/boot.rb</code> to include:</p>
<pre><code class="language-Ruby">require 'rails/commands/server'
module Rails
class Server
new_defaults = Module.new do
def default_options
default_host = Rails.env == 'development' ? '0.0.0.0' : '127.0.0.1'
super.merge( Host: default_host )
end
end
# Note: Module#prepend requires Ruby 2.0 or later
prepend new_defaults
end
end
</code></pre>
<p>If you make this change, you can just use <code class="language-plaintext highlighter-rouge">rails server</code> as usual.</p>
Snakes and Socket.IO2015-07-02T11:15:00+00:00http://pietro.menna.net.br/recurse-center/js/go/2015/07/02/snakes-and-socketio<p>Last Wednesday during my commute on the train, I coded a game just to see how long it would take. The game I coded is a web version of the classic Snake Game and can be checked out <a href="http://pietro.menna.net.br/web_snake">here</a>.</p>
<p>I showed it to <a href="https://twitter.com/daveypocket">Brad</a>, and he wanted to make a multiplayer version of it. The same day, <a href="https://twitter.com/aishwarya923">Aishwarya</a> and <a href="https://twitter.com/HeidiKasemir">Heidi</a> gave a workshop on creating a <a href="https://github.com/hkasemir/RCworkshopMultiPlayerGame">Web multiplayer game using SocketIO</a>.</p>
<h2 id="implementing-the-game">Implementing the game</h2>
<p>We began with a small design session, in which we agreed that it should be Web based (this meant we could re-use parts of my single player version) and that we should use <a href="https://golang.org">Go</a> for the back-end.</p>
<p>We tried to use TCP/IP sockets, but unfortunately they are not available in the front-end JS world.</p>
<p>We tried to then see an alternative, we even thought on re-making the front-end as a Java Applet in order to have TCP/IP. We ended up finding an alternative which was to use <a href="https://github.com/Automattic/socket.io">Socket.IO</a>.</p>
<p>Oh! and there is a SocketIO implementation for go called <a href="https://github.com/googollee/go-socket.io">go-socket-io</a>.</p>
<h2 id="socketio--websockets">Socket.IO & WebSockets</h2>
<p>Socket.IO is based on <a href="https://www.websocket.org/aboutwebsocket.html">WebSockets</a>. This is a technology that the Web Server must support which allows “Real Time Web Applications” by providing a connection which is full-duplex communication channel. This must be supported by the Web Server and by the Browser.</p>
<p>The WebSocket connection is requested by the browser by using a special header: <code class="language-plaintext highlighter-rouge">Connection: Upgrade</code>.</p>
<p>In the case the Web Server accepts, the HTTP connection is replaced by a Web Socket connection re-using the same port (HTTP 80 or HTTPS 443).</p>
<h3 id="the-game-protocol">The game protocol</h3>
<p>For the game we went for the simplest protocol we could think of. The board after our design discussion can be seen below:</p>
<p><img src="/public/multiplayer-snake-design.jpg" alt="DesignSession" title="Design of the Protocol image" /></p>
<p>All the client code which handles the communication fits in less than 20 lines of code:</p>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="kd">var</span> <span class="nx">socket</span> <span class="o">=</span> <span class="nx">io</span><span class="p">();</span>
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">playing</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">socket</span><span class="p">.</span><span class="nx">emit</span><span class="p">(</span><span class="dl">'</span><span class="s1">join game</span><span class="dl">'</span><span class="p">,</span><span class="dl">'</span><span class="s1">j</span><span class="dl">'</span><span class="p">);</span>
<span class="nx">playing</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
<span class="p">}</span>
<span class="nx">socket</span><span class="p">.</span><span class="nx">on</span><span class="p">(</span><span class="dl">'</span><span class="s1">init setup</span><span class="dl">'</span><span class="p">,</span><span class="kd">function</span><span class="p">(</span><span class="nx">data</span><span class="p">){</span>
<span class="kd">var</span> <span class="nx">currentState</span> <span class="o">=</span> <span class="nx">data</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">game</span> <span class="o">!=</span> <span class="kc">undefined</span><span class="p">){</span> <span class="nx">game</span><span class="p">.</span><span class="nx">setStatus</span><span class="p">(</span><span class="nx">currentState</span><span class="p">);}</span>
<span class="k">else</span> <span class="p">{</span><span class="nx">game</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Game</span><span class="p">(</span><span class="nx">currentState</span><span class="p">);}</span>
<span class="nx">socket</span><span class="p">.</span><span class="nx">emit</span><span class="p">(</span><span class="dl">'</span><span class="s1">ready</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">y</span><span class="dl">'</span><span class="p">);</span>
<span class="p">});</span>
<span class="nx">socket</span><span class="p">.</span><span class="nx">on</span><span class="p">(</span><span class="dl">'</span><span class="s1">tick</span><span class="dl">'</span><span class="p">,</span> <span class="kd">function</span><span class="p">(){</span>
<span class="nx">game</span><span class="p">.</span><span class="nx">tick</span><span class="p">();</span>
<span class="p">});</span>
<span class="nx">socket</span><span class="p">.</span><span class="nx">on</span><span class="p">(</span><span class="dl">'</span><span class="s1">die</span><span class="dl">'</span><span class="p">,</span> <span class="kd">function</span><span class="p">(){</span>
<span class="nx">alert</span><span class="p">(</span><span class="dl">'</span><span class="s1">You just died!</span><span class="dl">'</span><span class="p">);</span>
<span class="p">});</span>
<span class="nb">window</span><span class="p">.</span><span class="nx">addEventListener</span><span class="p">(</span><span class="dl">'</span><span class="s1">keydown</span><span class="dl">'</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">event</span><span class="p">)</span> <span class="p">{</span>
<span class="k">switch</span> <span class="p">(</span><span class="nx">event</span><span class="p">.</span><span class="nx">keyCode</span><span class="p">)</span> <span class="p">{</span>
<span class="k">case</span> <span class="mi">37</span><span class="p">:</span>
<span class="nx">socket</span><span class="p">.</span><span class="nx">emit</span><span class="p">(</span><span class="dl">'</span><span class="s1">change</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">LEFT</span><span class="dl">'</span><span class="p">);</span>
<span class="k">break</span><span class="p">;</span>
<span class="k">case</span> <span class="mi">38</span><span class="p">:</span>
<span class="nx">socket</span><span class="p">.</span><span class="nx">emit</span><span class="p">(</span><span class="dl">'</span><span class="s1">change</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">UP</span><span class="dl">'</span><span class="p">);</span>
<span class="k">break</span><span class="p">;</span>
<span class="k">case</span> <span class="mi">39</span><span class="p">:</span>
<span class="nx">socket</span><span class="p">.</span><span class="nx">emit</span><span class="p">(</span><span class="dl">'</span><span class="s1">change</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">RIGHT</span><span class="dl">'</span><span class="p">);</span>
<span class="k">break</span><span class="p">;</span>
<span class="k">case</span> <span class="mi">40</span><span class="p">:</span>
<span class="nx">socket</span><span class="p">.</span><span class="nx">emit</span><span class="p">(</span><span class="dl">'</span><span class="s1">change</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">DOWN</span><span class="dl">'</span><span class="p">);</span>
<span class="k">break</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">},</span> <span class="kc">false</span><span class="p">);</span>
</code></pre></div></div>
<h3 id="what-we-could-have-improved-">What we could have improved ?</h3>
<p>Currently, we are passing many times the <code class="language-plaintext highlighter-rouge">init setup</code> message. We pass it at each direction change, when a snake dies, when a new player joins the game, and even if someone eats the fruit!</p>
<p>What really bothers me is that we are doing the same computation on the client and on the server at the same time. In some way, we have duplication of knowledge and we are not being “DRY”.</p>
<p>This makes me wonder: <strong>How many other client-server applications have duplicate knowledge accross boundaries?</strong>.</p>
<p><strong>How many times we repeat code (or knowledge) just because it is the fastest solution we think at the moment?</strong></p>
<h2 id="conclusions">Conclusions</h2>
<p>It was pretty fun to work with <a href="https://twitter.com/daveypocket">Brad</a> once again! Also, WebSockets seems to be performing ok (I expected it to be slower since it is a higher level abstraction than raw TCP sockets).</p>
<p>Unfortunately, I think is my last project at <a href="http://recurse.com/">RC</a> since it is my last day.</p>
Rusty Torrent2015-06-19T18:25:00+00:00http://pietro.menna.net.br/recurse-center/rust/2015/06/19/rusty-torrent<p>Since last week, <a href="https://twitter.com/ken_pratt">Ken Pratt</a> and I started writing a BitTorrent Client written in <a href="http://www.rust-lang.org/">Rust</a>. The idea in this post is to leave some comments about what I learned from it, hoping that maybe it becomes useful to others who would like to create their own BitTorrent Client.</p>
<h2 id="experience-gained-by-a-failed-attempt">Experience gained by a failed attempt</h2>
<p>I tried before to build on my own the BitTorrent Client before, on my own. I naively tried to built everything from scratch, and in a language I was not that confortable. Yes, I failed!</p>
<p>I believe that the experience gained by my failed attempt allowed us to go faster. There were also other factors which allowed us to build this project very quickly: for example, <a href="https://twitter.com/ken_pratt">Ken</a> decided not to build everything from scratch, but to use what is already there as much as possible. This was a very wise decision.</p>
<p>##The implementation ##</p>
<p>We spent 9 days for the current implementation. In this subsection I would like to comment about the milestones of each of the days and leave some comments about parts of the code.</p>
<h3 id="day-1---tracker-communication-working">Day 1 - Tracker Communication working</h3>
<p>We used a bencoding library which was available in Rust, created the Metainfo file structure and the Info Dictionary info structure. The most important piece this day was to be able to construct the correct Request to the file. It was achieved by the code below:</p>
<pre><code class="language-Rust">pub fn run(metainfo: Metainfo) {
let length_string = metainfo.info.length.to_string();
let encoded_info_hash = percent_encode(&metainfo.info_hash, FORM_URLENCODED_ENCODE_SET);
let params = vec![("left", length_string.as_ref()),
("info_hash", encoded_info_hash.as_ref()),
("downloaded", "0"),
("uploaded", "0"),
("event", "started"),
("peer_id", "-TZ-0000-00000000000"),
("port", "6881")];
let url = format!("{}?{}", metainfo.announce, encode_query_params(&params));
let mut client = Client::new();
let mut res = client.get(&url).header(Connection::close()).send().unwrap();
}
</code></pre>
<p><strong>Why we went this approach?</strong> Simply because the BitTorrent specification does not use the latest URLenconding schemes, so any library that makes requests with URLencoding ended up changing the strings we needed to send.</p>
<p>The end of the day code can be found <a href="https://github.com/kenpratt/rusty_torrent/tree/972a8b17699717513a9346805d6829bfd03e693f">here</a>.</p>
<h3 id="day-2---parsing-tracker-response">Day 2 - Parsing Tracker Response</h3>
<p>The Tracker Response is a bencoded dictionary, it was pretty easy to extract the information we required. The only tricky part was how peers are encoded in the response. The implementation code:</p>
<pre><code class="language-Rust">pub struct Peer {
pub ip: Ipv4Addr,
pub port: u16,
}
impl Peer {
fn from_bytes(v: &[u8]) -> Peer {
let ip = Ipv4Addr::new(v[0], v[1], v[2], v[3]);
let port = (v[4] as u16) * 256 + (v[5] as u16);
Peer{ ip: ip, port: port }
}
}
</code></pre>
<p>The Peers are represented in 6 bytes. The first four bytes represents the digits of the Ip address, the last two bytes represent the port number. For example: bytes (60, 7E, 68, DB, 1A, E9) refer to address: 96.126.104.219:6889.</p>
<p>The end of the day code can be found <a href="https://github.com/kenpratt/rusty_torrent/tree/fe83707d06d81fe0f37a2b583ad988e9a0acf088">here</a>.</p>
<h3 id="day-4---1-file-downloading-on-1-peer-in-order-download">Day 4 - 1 File Downloading, on 1 Peer, In-Order download</h3>
<p>We made the peer communication for Downloads and made it to download the famous Tom Flag in these 2 days. Some important decisions:</p>
<ul>
<li>
<p>We had the concept of a Download running. This was supposed to be the control of the Peer Connection. One of the reponsabilities was to handle the peer connections and also to store the file being downloaded.</p>
</li>
<li>
<p>The peer connection contained all the information of how to handle the peer communication for Downloads. In particular it knew how to handle each message a Peer can send:</p>
</li>
</ul>
<pre><code class="language-Rust">enum Message {
KeepAlive,
Choke,
Unchoke,
Interested,
NotInterested,
Have(u32),
Bitfield(Vec<u8>),
Request(u32, u32, u32),
Piece(u32, u32, Vec<u8>),
Cancel,
Port,
}
impl Message {
fn new(id: &u8, body: &[u8]) -> Message {
match *id {
0 => Message::Choke,
1 => Message::Unchoke,
2 => Message::Interested,
3 => Message::NotInterested,
4 => Message::Have(bytes_to_u32(body)),
5 => Message::Bitfield(body.to_owned()),
6 => {
let index = bytes_to_u32(&body[0..4]);
let offset = bytes_to_u32(&body[4..8]);
let length = bytes_to_u32(&body[8..12]);
Message::Request(index, offset, length)
},
7 => {
let index = bytes_to_u32(&body[0..4]);
let offset = bytes_to_u32(&body[4..8]);
let data = body[8..].to_owned();
Message::Piece(index, offset, data)
},
8 => Message::Cancel,
9 => Message::Port,
_ => panic!("Bad message id: {}", id)
}
}
</code></pre>
<ul>
<li>When saying “1 File Downloading, on 1 Peer, In-Order download”, I mean that we could only download from a single peer, torrents which contained only one file, and that we requested each of the pieces/blocks in order. For example: if each piece contained 2 blocks, we would have requested piece 1, block 1, piece 1 block 2, then piece 2, block 1, and so on.</li>
</ul>
<p>The end of the day code can be found <a href="https://github.com/kenpratt/rusty_torrent/tree/d1f7b43a1e88d1b2e570dc484105b62ef5240662">here</a>.</p>
<h3 id="5th--6th-day---multiple-peers--requests-queuing">5th & 6th Day - Multiple peers / Requests Queuing</h3>
<p>The cool parts begin here. We had to use two concurrent/parallel programming techniques here: mutexes and channels.</p>
<p>We used mutex (Exclusive Lock or Exclusive Access) for the interactions which the <em>Peer Connections</em> needed to do on the <em>Download</em> entity which were changing the status of the <strong>Downloaded File</strong>.</p>
<pre><code class="language-Rust">fn connect(peer: &Peer, download_mutex: Arc<Mutex<Download>>) -> Result<PeerConnection, Error> {
let stream = try!(TcpStream::connect((peer.ip, peer.port)));
let num_pieces = {
let download = download_mutex.lock().unwrap();
download.metainfo.info.num_pieces
};
</code></pre>
<p>We used channels for asynchronous calls from the <em>Download</em> to the <em>Peers Connections</em>. For example, in the case a Peer Connection finished downloading a Block, it should notify all the other Peer connections that the pieces was no longer required, and that in the case they happened to be downloading the same piece, they could cancel it. The code below:</p>
<pre><code class="language-Rust">fn process_message_from_download(&mut self, message: PeerMessage) -> Result<(), Error> {
match message {
PeerMessage::CancelRequest(piece_index, block_index) => {
match self.requests_in_progress.iter().position(|r| r.matches(piece_index, block_index)) {
Some(i) => {
let r = self.requests_in_progress.remove(i);
self.send_message(Message::Cancel(r.piece_index, r.offset, r.block_length))
},
None => Ok(())
}
}
}
}
</code></pre>
<p>We also do not request one block at a time to other peers, we request ten at a time (defined as MAX_CONCURRENT_REQUESTS):</p>
<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">fn</span> <span class="nf">request_more_blocks</span><span class="p">(</span><span class="o">&</span><span class="k">mut</span> <span class="k">self</span><span class="p">)</span> <span class="k">-></span> <span class="n">Result</span><span class="o"><</span><span class="p">(),</span> <span class="n">Error</span><span class="o">></span> <span class="p">{</span>
<span class="k">if</span> <span class="k">self</span><span class="py">.am_i_choked</span> <span class="o">==</span> <span class="k">true</span> <span class="p">{</span>
<span class="k">return</span> <span class="nf">Ok</span><span class="p">(())</span>
<span class="p">}</span>
<span class="k">while</span> <span class="k">self</span><span class="py">.requests_in_progress</span><span class="nf">.len</span><span class="p">()</span> <span class="o"><</span> <span class="n">MAX_CONCURRENT_REQUESTS</span> <span class="k">as</span> <span class="nb">usize</span> <span class="p">{</span>
<span class="k">let</span> <span class="n">next_block_to_request</span> <span class="o">=</span> <span class="p">{</span>
<span class="k">let</span> <span class="n">download</span> <span class="o">=</span> <span class="k">self</span><span class="py">.download_mutex</span><span class="nf">.lock</span><span class="p">()</span><span class="nf">.unwrap</span><span class="p">();</span>
<span class="n">download</span><span class="nf">.next_block_to_request</span><span class="p">(</span><span class="o">&</span><span class="k">self</span><span class="py">.have</span><span class="p">)</span>
<span class="p">};</span>
<span class="k">match</span> <span class="n">next_block_to_request</span> <span class="p">{</span>
<span class="nf">Some</span><span class="p">((</span><span class="n">piece_index</span><span class="p">,</span> <span class="n">block_index</span><span class="p">,</span> <span class="n">block_length</span><span class="p">))</span> <span class="k">=></span> <span class="p">{</span>
<span class="k">let</span> <span class="n">offset</span> <span class="o">=</span> <span class="n">block_index</span> <span class="o">*</span> <span class="n">BLOCK_SIZE</span><span class="p">;</span>
<span class="nd">try!</span><span class="p">(</span><span class="k">self</span><span class="nf">.send_message</span><span class="p">(</span><span class="nn">Message</span><span class="p">::</span><span class="nf">Request</span><span class="p">(</span><span class="n">piece_index</span><span class="p">,</span> <span class="n">offset</span><span class="p">,</span> <span class="n">block_length</span><span class="p">)));</span>
<span class="k">self</span><span class="py">.requests_in_progress</span><span class="nf">.push</span><span class="p">(</span><span class="n">RequestMetadata</span> <span class="p">{</span>
<span class="n">piece_index</span><span class="p">:</span> <span class="n">piece_index</span><span class="p">,</span>
<span class="n">block_index</span><span class="p">:</span> <span class="n">block_index</span><span class="p">,</span>
<span class="n">offset</span><span class="p">:</span> <span class="n">offset</span><span class="p">,</span>
<span class="n">block_length</span><span class="p">:</span> <span class="n">block_length</span><span class="p">,</span>
<span class="p">});</span>
<span class="p">},</span>
<span class="nb">None</span> <span class="k">=></span> <span class="p">{</span>
<span class="nd">println!</span><span class="p">(</span><span class="s">"We've downloaded all the pieces we can from this peer."</span><span class="p">);</span>
<span class="k">return</span> <span class="nf">Ok</span><span class="p">(())</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="nf">Ok</span><span class="p">(())</span>
<span class="p">}</span>
</code></pre></div></div>
<p>The end of the 6th day code can be found <a href="https://github.com/kenpratt/rusty_torrent/tree/b19f96e42aecd6b1929757df59fa7f8b8ee6dfd8">here</a></p>
<h3 id="7th--8th-day---uploadingseeding-working">7th & 8th Day - Uploading/Seeding working!</h3>
<p>Unfortunately I could not work with Ken on the 8th Day, but he made possible Seeding/Uploading on his own.</p>
<p>It was added support for sending <em>BitField</em> and <em>Have</em> messages and to <em>Upload</em> the requested blocks by other peers.</p>
<p>An interesting Entity which was created during this day was the <strong>Funnel</strong> inside <em>Peer Connection</em>. The idea of the funnel is that there was an entity which was in charge of collecting all the incomming messages from the TCP socket, and also for the outgoing messages on the Channels.</p>
<pre><code class="language-Rust">let downstream_funnel_thread = {
let stream = self.stream.try_clone().unwrap();
let tx = self.incoming_tx.clone();
thread::spawn(move || DownstreamMessageFunnel::start(stream, tx))
};
// spawn a thread to funnel outgoing messages from the outgoing message channel into the socket
let upstream_funnel_thread = {
let stream = self.stream.try_clone().unwrap();
let tx = self.incoming_tx.clone();
thread::spawn(move || UpstreamMessageFunnel::start(stream, outgoing_rx, tx))
};
</code></pre>
<p>The end of the 8th day code can be found <a href="https://github.com/kenpratt/rusty_torrent/tree/5bdf2ddee92906eade0787e5b624a79a3c0e08ee">here</a></p>
<h2 id="advices-to-build-your-own---what-i-learned-from-this-project">Advices to build your own - What I learned from this project</h2>
<p>The first and most impportant, <strong>do not try to re-invent the wheel everytime</strong>. For example, if you find a ready to use solution for the <em>bencoding</em>, use it! If you find wrappers for the TCP connections, use them! It is better the faster you can get feedback about what you are building than to struggle and abandon a project. This does not mean that if you afterwards would like to change one of the modules for one you built form scratch it will be imposible.</p>
<p>The second advice: <strong>work in pairs</strong>: this keeps up the motivation and also I believe it allows a better solution. Many of the discussions we had, lead to the solution which was implemented.</p>
<p>Last advice, but not least, before trying to write a BitTorrent client, read the resouces below:</p>
<ul>
<li><a href="https://wiki.theory.org/BitTorrentSpecification">Unnoficial BitTorrent Specification</a></li>
<li><a href="http://www.kristenwidman.com/blog/33/how-to-write-a-bittorrent-client-part-1/">Kirsten blog entries</a></li>
</ul>
<p>These resources are really important, and contain a lot of information which is required.</p>
<h2 id="conclusions">Conclusions</h2>
<p>I learned a lot from this project. Ken acted as a mentor for me in this project, he always explained the decisions which were at stake, and he always had patience with my lack of experience with Rust.</p>
<p>This project allowed me us work with Sockets, and Concurrent and Parallel programming.</p>
<p>The latest version of the project code can be found <a href="https://github.com/kenpratt/rusty_torrent">here</a>.</p>
Writing my first Interpreter2015-06-05T18:25:00+00:00http://pietro.menna.net.br/recurse-center/clojure/2015/06/05/brainf-fck-interpreter<p>Talking with <a href="https://twitter.com/daveypocket">Brad</a> on Wednesday, he showed to me an <a href="https://github.com/DaveyPocket/BFinterpreter">Interpreter for BrainFuck</a> he written in Go. I really liked his idea, so I also implemented mine but in JS (I have never written or seen before an interpreter).</p>
<h1 id="the-interpreter">The interpreter</h1>
<p>I am impresed which such a cool name there is for a switch statement with some bunch of extra variables.</p>
<p>Since Brain F* only contains few keywords: ‘>’, ‘<’, ‘]’, ‘[’, ‘+’, ‘-‘, ‘,’ and ‘.’. It was very quick to implement it.</p>
<p>Now I am wondering if all the <em>interpreted languages</em> just have a huge switch for each keyword? I will have to figure this out!</p>
<h2 id="my-interpreter-code">My interpreter code</h2>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="k">this</span><span class="p">.</span><span class="nx">run</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(){</span>
<span class="k">while</span><span class="p">(</span><span class="nx">instruction_pointer</span><span class="o"><</span><span class="nx">instructions</span><span class="p">.</span><span class="nx">length</span><span class="p">){</span>
<span class="k">switch</span><span class="p">(</span><span class="nx">instructions</span><span class="p">[</span><span class="nx">instruction_pointer</span><span class="p">])</span> <span class="p">{</span>
<span class="k">case</span> <span class="dl">'</span><span class="s1">></span><span class="dl">'</span><span class="p">:</span>
<span class="nx">data_pointer</span> <span class="o">=</span> <span class="nx">data_pointer</span> <span class="o">+</span> <span class="mi">1</span><span class="p">;</span>
<span class="k">break</span><span class="p">;</span>
<span class="k">case</span> <span class="dl">'</span><span class="s1"><</span><span class="dl">'</span><span class="p">:</span>
<span class="nx">data_pointer</span> <span class="o">=</span> <span class="nx">data_pointer</span> <span class="o">-</span> <span class="mi">1</span><span class="p">;</span>
<span class="k">break</span><span class="p">;</span>
<span class="k">case</span> <span class="dl">'</span><span class="s1">+</span><span class="dl">'</span><span class="p">:</span>
<span class="nx">memory</span><span class="p">[</span><span class="nx">data_pointer</span><span class="p">]</span> <span class="o">=</span> <span class="nx">memory</span><span class="p">[</span><span class="nx">data_pointer</span><span class="p">]</span> <span class="o">+</span> <span class="mi">1</span><span class="p">;</span>
<span class="k">break</span><span class="p">;</span>
<span class="k">case</span> <span class="dl">'</span><span class="s1">-</span><span class="dl">'</span><span class="p">:</span>
<span class="nx">memory</span><span class="p">[</span><span class="nx">data_pointer</span><span class="p">]</span> <span class="o">=</span> <span class="nx">memory</span><span class="p">[</span><span class="nx">data_pointer</span><span class="p">]</span> <span class="o">-</span> <span class="mi">1</span><span class="p">;</span>
<span class="k">break</span><span class="p">;</span>
<span class="k">case</span> <span class="dl">'</span><span class="s1">.</span><span class="dl">'</span><span class="p">:</span>
<span class="nx">output</span> <span class="o">=</span> <span class="nb">String</span><span class="p">.</span><span class="nx">fromCharCode</span><span class="p">(</span><span class="nx">memory</span><span class="p">[</span><span class="nx">data_pointer</span><span class="p">]);</span>
<span class="kd">var</span> <span class="nx">current_output</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nx">getElementById</span><span class="p">(</span><span class="dl">"</span><span class="s2">output</span><span class="dl">"</span><span class="p">).</span><span class="nx">innerHTML</span><span class="p">;</span>
<span class="nx">current_output</span> <span class="o">=</span> <span class="nx">current_output</span> <span class="o">+</span> <span class="nx">output</span><span class="p">;</span>
<span class="nb">document</span><span class="p">.</span><span class="nx">getElementById</span><span class="p">(</span><span class="dl">"</span><span class="s2">output</span><span class="dl">"</span><span class="p">).</span><span class="nx">innerHTML</span> <span class="o">=</span> <span class="nx">current_output</span><span class="p">;</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nb">String</span><span class="p">.</span><span class="nx">fromCharCode</span><span class="p">(</span><span class="nx">memory</span><span class="p">[</span><span class="nx">data_pointer</span><span class="p">]));</span>
<span class="k">break</span><span class="p">;</span>
<span class="k">case</span> <span class="dl">'</span><span class="s1">,</span><span class="dl">'</span><span class="p">:</span>
<span class="kd">var</span> <span class="nx">character</span> <span class="o">=</span> <span class="nx">prompt</span><span class="p">(</span><span class="dl">"</span><span class="s2">Input a character to be stored</span><span class="dl">"</span><span class="p">);</span>
<span class="nx">memory</span><span class="p">[</span><span class="nx">data_pointer</span><span class="p">]</span> <span class="o">=</span> <span class="nx">character</span><span class="p">.</span><span class="nx">charCodeAt</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span>
<span class="k">break</span><span class="p">;</span>
<span class="k">case</span> <span class="dl">'</span><span class="s1">[</span><span class="dl">'</span><span class="p">:</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">memory</span><span class="p">[</span><span class="nx">data_pointer</span><span class="p">]</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">instruction_pointer</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">findMatching</span><span class="p">(</span><span class="nx">instruction_pointer</span><span class="p">);</span>
<span class="k">continue</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">break</span><span class="p">;</span>
<span class="k">case</span> <span class="dl">'</span><span class="s1">]</span><span class="dl">'</span><span class="p">:</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">memory</span><span class="p">[</span><span class="nx">data_pointer</span><span class="p">]</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">){</span>
<span class="nx">instruction_pointer</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">findMatching</span><span class="p">(</span><span class="nx">instruction_pointer</span><span class="p">);</span>
<span class="k">continue</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">break</span><span class="p">;</span>
<span class="p">}</span>
<span class="nx">instruction_pointer</span> <span class="o">=</span> <span class="nx">instruction_pointer</span> <span class="o">+</span> <span class="mi">1</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>
<p>#Live run your Brain F*ck code below #</p>
<h2 id="brain-fck-code-goes-here">Brain F*ck code goes here!</h2>
<script src="public/interpreter.js"></script>
<form>
<textarea id="input" rows="20" cols="72">++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++.</textarea>
</br>
<button type="button" onclick="process_file()">Run!</button>
</form>
<h2 id="output-of-the-program">Output of the program</h2>
<p id="output"></p>
<h3 id="thanks-a-lot-brad-for-the-idea-and-help-during-the-implementation">Thanks a lot Brad for the idea and help during the implementation!</h3>
How I began with Clojure - My first steps2015-06-02T16:00:00+00:00http://pietro.menna.net.br/recurse-center/clojure/2015/06/02/my-start-with-clojure<p>During my lunch today at <a href="https://www.recurse.com">Recurse Center</a>, I don’t know how, but luckily in the table I was sitting, there were only people interested in learning <a href="http://clojure.org/">Clojure</a>. I was really glad since this did not happen in my Batch. (most Spring 2 2015 colleagues were interested in learning <a href="https://www.haskell.org/">Haskell</a>).</p>
<p>In this post, I plan to write about what I think would have been useful to me in those first days.</p>
<ol>
<li>Start by installing correctly leiningen. Do not use <code class="language-plaintext highlighter-rouge">brew install leiningen</code>. <a href="http://leiningen.org/#install">Install manually!</a></li>
<li>Try the <a href="http://iloveponies.github.io/">Clojure Workshop</a> training.</li>
<li>Do lots of <a href="https://www.4clojure.com">4clojure</a> exercises!</li>
<li>Get a Clojure Book. I think some Clojure Books are available at RC Libary. I got the first edition of <a href="http://www.joyofclojure.com/">Joy of Clojure</a> which <a href="https://github.com/davoclavo">David</a> gave me as present.</li>
<li>Try an easy project on your own. Maybe do one you already did in the past.</li>
</ol>
<p>At this point I can share that I have not done the 5th. I tried to do the <a href="https://github.com/pietromenna/btcj">BitTorrent Client</a>, but this project has problems on its own. Also java has it’s quirks which makes it difficult to do it. At lost focus and energy trying to do this project. So the advice is again <strong>do something you did already in a language you master, and try to port it</strong>.</p>
<p>The last but not least I would have told me <em>work in groups</em>. Unfortunately I did not have that resource. But I received some great help from the people whom I got to pair at least for a small time (Charlie, Mary Rose and Zach).</p>
<p>#Some resources which I found be useful#</p>
<ul>
<li><a href="http://conj.io/">Grimoire</a>: A Cheatsheet of many Clojure functions presented in a nice way!</li>
<li><a href="http://clojuredocs.org/">ClojureDocs</a>: Is the community-powered documentation and examples repository.</li>
<li><a href="http://clojurewerkz.org/">Clojure Werkz</a> A growing collection of open source Clojure libraries</li>
</ul>
<p>#What I am currently doing with Clojure?#</p>
<p>Still doing, <a href="https://www.4clojure.com">4clojure</a> exercises, and I am also trying to port an App I did in group which is <a href="https://follow-recursers.herokuapp.com/">Follow Recursers</a> to Clojure. This App is currently written in JS.</p>
<p><strong>If you would like to join me, you are more than welcome!</strong></p>
Game of Life!2015-05-27T18:30:00+00:00http://pietro.menna.net.br/recurse-center/2015/05/27/game-of-life<p>Today I paired with <a href="https://github.com/erisa85">Erisa</a> in order to implement the Game of Life. The code can be found <a href="https://github.com/erisa85/GameOfLife">here</a>.</p>
<script src="/public/game_of_life.js"></script>
<canvas id="canvas" width="400" height="400"></canvas>
<script type="text/javascript">drawCanvas();</script>
<script type="text/javascript">setInterval(function() {
MainLoop(); }, 1000);</script>
<p>Initially I thought that this was a very complex problem, but if you read from <a href="http://en.wikipedia.org/wiki/Conway%27s_Game_of_Life">wikipedia article</a>, it can be coded with only few rules. This was one of the problems which I never attacked because I thought it would be really hard.</p>
Other Recurser's solutions to CrackePop!2015-05-26T14:15:00+00:00http://pietro.menna.net.br/recurse-center/2015/05/26/more-crackle-pop-solutions<p>Some weeks ago a post about “CracklePop” in which I posted two implementations. The post can be found <a href="http://pietro.menna.net.br/recurse-center/2015/05/08/crackle-pop/">here</a>. After the post, other Recurser’s shared with three more solutions. I decided to post them here.</p>
<p><a href="https://twitter.com/mjdominus">Mark Dominus</a>’s solution in Perl.</p>
<div class="language-perl highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">my</span> <span class="nv">@num</span> <span class="o">=</span> <span class="p">("")</span> <span class="nv">x</span> <span class="mi">101</span><span class="p">;</span>
<span class="nv">$num</span><span class="p">[</span><span class="vg">$_</span><span class="o">*</span><span class="mi">3</span><span class="p">]</span> <span class="o">.=</span> <span class="p">"</span><span class="s2">Crackle</span><span class="p">"</span> <span class="k">for</span> <span class="mi">1</span><span class="o">..</span><span class="mi">33</span><span class="p">;</span>
<span class="nv">$num</span><span class="p">[</span><span class="vg">$_</span><span class="o">*</span><span class="mi">5</span><span class="p">]</span> <span class="o">.=</span> <span class="p">"</span><span class="s2">Pop</span><span class="p">"</span> <span class="k">for</span> <span class="mi">1</span><span class="o">..</span><span class="mi">20</span><span class="p">;</span>
<span class="nv">$num</span><span class="p">[</span><span class="vg">$_</span><span class="p">]</span> <span class="o">||=</span> <span class="vg">$_</span> <span class="k">for</span> <span class="mi">1</span><span class="o">..</span><span class="mi">100</span><span class="p">;</span>
<span class="nb">shift</span> <span class="nv">@num</span><span class="p">;</span> <span class="c1"># discard element 0</span>
<span class="k">print</span> <span class="nb">join</span> <span class="p">"</span><span class="se">\n</span><span class="p">",</span> <span class="nv">@num</span><span class="p">,</span> <span class="p">"";</span>
</code></pre></div></div>
<p><a href="https://twitter.com/_jak">James Keene</a>’s solution.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>def fizzbuzz(a):
return [a, "Fizz", "Buzz", "FizzBuzz"][(0x1241843 >> ((a % 15) * 2)) & 3]
map(fizzbuzz,xrange(1,100))
</code></pre></div></div>
<p>At last, with <a href="https://github.com/urthbound">Jeff Fowler</a>’s solution in Brain Fuck which can be found <a href="http://repl.it/mdb">here</a></p>
<p>I am really amazed to see how many different solutions can be to a very trivial problem.</p>
<p>Mark’s solution I could understand just by reading the code. In order to understand James’s solution I re-writed in a language I knew and debugged the code in order to understand how it worked.</p>
<p>Jeff’s solution I gave up! It is in Brain Fuck and I really do not understand it at all. I found really cool to get to know a really strange computer languaged which I never heard before.</p>
<p>A big thanks to all who shared their solution!</p>
My limited experience with Vagrant2015-05-13T13:34:00+00:00http://pietro.menna.net.br/recurse-center/2015/05/13/vagrant-experience<p>This week I wanted work on one of the issues from the <a href="https://community.recurse.com">Community App</a> from <a href="https://www.recurse.com">Recurse Center</a>. In order to be able to work on it, I had to pass through all the steps of installing a local version on my system.</p>
<p>The truth is it was a real pain to get the development environment working. I spent more than a full day focused to make it work on my local system. I could not make it work on my own.</p>
<p>Without the help from <a href="https://twitter.com/davidbalbert">David Albert</a> I think I would have still be stuck.</p>
<h2 id="setting-up-development-systems-in-some-cases-is-not-trivial">Setting up development systems in some cases is not trivial!</h2>
<p>I am sure there are a lot of more complex scenarios than the one I worked yesterday. The <a href="https://community.recurse.com">community app</a> requires to have installed (up to the date):</p>
<ul>
<li>Ruby 2.2.2 via <a href="https://rvm.io/">RVM</a></li>
<li><a href="http://www.postgresql.org/">Postgres</a></li>
<li><a href="http://leiningen.org/">Leiningen</a></li>
<li><a href="https://www.elastic.co/">Elasticsearch</a></li>
<li><a href="http://redis.io/">Redis</a></li>
<li>Bundler, Foreman, etc.</li>
</ul>
<p>In order to setup each of the parts, you need to at least know a bit of each. I never used Postgres, or Elasticsearch. So both of them was a pain for me. But I am sure it can be even harder than this scenario!</p>
<p>##I just wanted to work on a single issue ##</p>
<p>As a developer (or maye a future contributor) I want to read code, write some code, and test it! I should not be bothered by the installation steps.</p>
<p>The diagram below shows how I could describe yesterday: at each cycle in which the installation failed I just felt sader and sader. Maybe some people would quit in the middle of the process.</p>
<p><img src="/public/dev-inst-frustrating.png" alt="DEIF" title="DEIF Frustration" /></p>
<p>And I have to admit, I spent <strong>a full day</strong> just on the negative part of the cycle!</p>
<h2 id="nobody-else-should-spend-a-day-just-to-set-up-a-development-environment">Nobody else should spend a day just to set up a Development environment</h2>
<p>This is where <a href="https://www.vagrantup.com/">Vagrant</a> comes in. It allows to create scripts for setting up Virtual Machines. With these scripts you can automate the steps required to set up a Development Environment.</p>
<p>The idea is that only one person should pass the pain of setting up the environment, record the steps to re-create the environment and create the scripts.</p>
<p>Future developers should benefit from this automation.</p>
<h2 id="conclusion">Conclusion</h2>
<p>If you have an OSS Project and you want more contributors, it should be <strong>easy to install the development environment</strong>. One way of achieving this is to use Vagrant.</p>
<p>Regarding the <a href="https://community.recurse.com">Recurse Center Community App</a>, I have just sent a Pull Request which adds Vagrant support. Check it out <a href="https://github.com/recursecenter/community/pull/308">here</a>.</p>
CracklePop2015-05-08T15:50:00+00:00http://pietro.menna.net.br/recurse-center/2015/05/08/crackle-pop<p>I remember when I applied to <a href="http://www.recurse.com">Recurse Center</a>, I got asked to write a program called “Crackle Pop”. I just wonder, do all the solutions provided by all the applicants look really different? (I personally doubt it).</p>
<h2 id="how-i-wrote-it">How I wrote it</h2>
<p>I literally just copied the instructions and transformed it to code. I did not care if it was the best solution, or the most elegant, or even the most perfomance efficient. I actually wrote it in Ruby, but since I am learning Clojure, I will write in Clojure.</p>
<p>The specs:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Write a program that prints out the numbers 1 to 100 (inclusive). If the number is divisible by 3, print Crackle instead of the number. If it's divisible by 5, print Pop. If it's divisible by both 3 and 5, print CracklePop. You can use any language.
</code></pre></div></div>
<p>The code:</p>
<div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="k">defn</span><span class="w"> </span><span class="n">cracklepop</span><span class="w"> </span><span class="p">[</span><span class="n">x</span><span class="p">]</span><span class="w">
</span><span class="p">(</span><span class="k">cond</span><span class="w">
</span><span class="p">(</span><span class="nb">=</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="p">(</span><span class="nf">mod</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="mi">3</span><span class="p">)</span><span class="w"> </span><span class="p">(</span><span class="nf">mod</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="mi">5</span><span class="p">))</span><span class="w"> </span><span class="p">(</span><span class="nb">println</span><span class="w"> </span><span class="s">"CracklePop"</span><span class="p">)</span><span class="w">
</span><span class="p">(</span><span class="nb">=</span><span class="w"> </span><span class="p">(</span><span class="nf">mod</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="mi">3</span><span class="p">)</span><span class="w"> </span><span class="mi">0</span><span class="p">)</span><span class="w"> </span><span class="p">(</span><span class="nb">println</span><span class="w"> </span><span class="s">"Crackle"</span><span class="p">)</span><span class="w">
</span><span class="p">(</span><span class="nb">=</span><span class="w"> </span><span class="p">(</span><span class="nf">mod</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="mi">5</span><span class="p">)</span><span class="w"> </span><span class="mi">0</span><span class="p">)</span><span class="w"> </span><span class="p">(</span><span class="nb">println</span><span class="w"> </span><span class="s">"Pop"</span><span class="p">)</span><span class="w">
</span><span class="no">:else</span><span class="w"> </span><span class="p">(</span><span class="nb">println</span><span class="w"> </span><span class="n">x</span><span class="p">)))</span><span class="w">
</span><span class="p">(</span><span class="nb">map</span><span class="w"> </span><span class="n">cracklepop</span><span class="w"> </span><span class="p">(</span><span class="nb">range</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="mi">101</span><span class="p">))</span><span class="w">
</span></code></pre></div></div>
<h2 id="lets-try-to-write-it-different">Let`s try to write it different</h2>
<h3 id="do-not-use-conditionals">Do not use conditionals!!!</h3>
<p>It seems crazy, right? The spec already contains 3 <strong>ifs</strong> statements on its own. So it is so logical to write it using <em>ifs</em> or <em>conditional</em> (switch in other languages) statements.</p>
<div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="k">defn</span><span class="w"> </span><span class="n">cracklepop</span><span class="w"> </span><span class="p">[</span><span class="n">x</span><span class="p">]</span><span class="w">
</span><span class="p">(</span><span class="k">let</span><span class="w"> </span><span class="p">[</span><span class="n">solution-matrix</span><span class="w"> </span><span class="p">{</span><span class="mi">0</span><span class="w"> </span><span class="s">"CracklePop"</span><span class="w">
</span><span class="mi">3</span><span class="w"> </span><span class="s">"Crackle"</span><span class="w">
</span><span class="mi">5</span><span class="w"> </span><span class="s">"Pop"</span><span class="w">
</span><span class="mi">6</span><span class="w"> </span><span class="s">"Crackle"</span><span class="w">
</span><span class="mi">9</span><span class="w"> </span><span class="s">"Crackle"</span><span class="w">
</span><span class="mi">10</span><span class="w"> </span><span class="s">"Pop"</span><span class="w">
</span><span class="mi">12</span><span class="w"> </span><span class="s">"Crackle"</span><span class="p">}]</span><span class="w">
</span><span class="p">(</span><span class="nb">println</span><span class="w"> </span><span class="p">(</span><span class="nf">solution-matrix</span><span class="w"> </span><span class="p">(</span><span class="nf">mod</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="mi">15</span><span class="p">)</span><span class="w"> </span><span class="n">x</span><span class="p">))))</span><span class="w">
</span><span class="p">(</span><span class="nb">map</span><span class="w"> </span><span class="n">cracklepop</span><span class="w"> </span><span class="p">(</span><span class="nb">range</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="mi">101</span><span class="p">))</span><span class="w">
</span></code></pre></div></div>
<p>This solution does not use conditionals, but a “rotating matrix”.</p>
<h2 id="what-solution-is-better">What Solution is better?</h2>
<p><strong>I don’t know and I have not measured the runtimes of each solution.</strong> I just know that if I was asked during a job interview to write without conditionals, maybe I could have blanked for some minutes. This is because I never thought of the problem with that constrait until now. (Also the preasure of the interview would have added up).</p>
<p>But for sure, I still find the first solution more readable for being closer to the domain of the “requirements”.</p>
<h2 id="conclusions">Conclusions</h2>
<p>There are many solutions to a same problem. Deciding on a solution should depend on the contraints defined by the non-functional requirements.</p>
<p>I also still think that solutions should be written as close to as possible to the domain of the problem. This way the code keeps readable.</p>
Half Journey2015-05-07T14:00:00+00:00http://pietro.menna.net.br/recurse-center/2015/05/07/half-journey<p>Today is exactly the middle of my Batch at <a href="https://recurse.com">Recurce Center</a>. Six weeks has passed and I just realized that I learned some stuff, but I have still much to learn here.</p>
<p>I just set for myself the objectives for the rest of the my Batch which will be to try to contribute to a OSS project while continuing to learn <a href="http://clojure.org">Clojure</a>.</p>
<p>My plan is to post about what I learn (and my findings) but trying to avoid keeping too personal.</p>
<h1 id="so-what-i-learned-today">So what I learned today?</h1>
<h2 id="resources-for-closure">Resources for Closure</h2>
<p>The list below is a <strong>must have favorites</strong> links for every person how would like to learn Clojure or plans to use it.</p>
<ul>
<li><a href="http://conj.io/">Grimoire</a>: A Cheatsheet of many Clojure functions presented in a nice way!</li>
<li><a href="http://clojuredocs.org/">ClojureDocs</a>: Is the community-powered documentation and examples repository.</li>
<li><a href="http://clojurewerkz.org/">Clojure Werkz</a> A growing collection of open source Clojure libraries</li>
</ul>
<h2 id="closures">Closures</h2>
<p><strong>What are they? What does it mean to have a Closure?</strong></p>
<p>First, the definition by wikipedia:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>In programming languages, closures (also lexical closures or function closures) are a technique for implementing lexically scoped name binding in languages with first-class functions. Operationally, a closure is a data structure storing a function together with an environment.
</code></pre></div></div>
<p>An example, implementing Power of function using Closures.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>(defn pow [initial]
(fn [x] (reduce * (repeat initial x))))
</code></pre></div></div>
<p>Calling the code above in the REPL:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>user=> ((pow 2) 3)
9
user=> ((pow 6) 3)
729
user=> ((pow 3) 3)
27
</code></pre></div></div>
<p>So what just happened? We created a <strong>function</strong> which returns <strong>another function</strong> which happens to have an initial value stored on it’s instance in the memory.</p>
<p>I am not sure yet, but I can say that the <em>initial</em> variable, is now a “private attribute” of the instance of function <em>pow</em> which gets in the run time.</p>
<p>It seems a very powerful resource!</p>
Functional Programming2015-04-29T22:21:00+00:00http://pietro.menna.net.br/recurse-center/2015/04/29/functional-programming<p>#My limited experience with Functional Programming#</p>
<p>What I have been doing all this time at <a href="https://www.recurse.com">Recurse Center</a>? I have been trying to learn the <strong>all new & hot functional programming paradigm:</strong> by learning <a href="http://clojure.org">Clojure</a>. I also tried to understand why this paradigm is so popular these days.</p>
<p>##First, I felt in love##
Sometimes, a simple example is better then thousand explanations! I remember writing boring Java code like the one below in college classes:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>public static class SumOfSquaresHelper
{
public static int Square(int i)
{
return i * i;
}
public static int SumOfSquares(int n)
{
int sum = 0;
for (int i = 1; i <= n; i++)
{
sum += Square(i);
}
return sum;
}
}
</code></pre></div></div>
<p>Compare to:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>(defn square [x] (* x x))
(defn sum-of-squares [n] (reduce + (map square (range 0 (inc n)))
</code></pre></div></div>
<p>Unless you are paid by the number (of non-useful) lines of code you write, you will fall in love with the expresiveness and simplicity of <a href="https://www.youtube.com/watch?v=HM1Zb3xmvMc">LISP</a>.</p>
<p>By the way, yes, I used static which is <strong>ugly and bad</strong> in the example in Java, but LISP is so simple, and its syntax is also so compact, that programs are usually very readable (once you get used to the lots of parens).</p>
<p>##Then came the pain ##</p>
<p>I began with <a href="http://tryclj.org">tryclojure</a>, then I tried some <a href="http://www.4clojure.com">4clojure</a> problems, but my main source of learning was by trying to finish all the problems from <a href="http://iloveponies.github.io/120-hour-epic-sax-marathon/">120 hour epic sax marathon</a>. It was great, and I still plan to finish it all before finishing my batch, but it was exhausting. There are like 5 problems I did not finish yet.</p>
<p>I find it remarkable how hard it is to <strong>understand</strong> simple concepts in their extreme: <strong>recursion</strong>, <strong>reduce</strong> and <strong>map</strong>. The three of them are very simple ideas, but to learn these very simple ideas it is really painful, and a lot of exercises are required.</p>
<p>It reminded me of a phrase from <em>Uncle Bob Martin</em>, which is something like a programming paradigm is <em>subtracting and not adding something</em> to the way we program (<a href="http://cleancoders.com/episode/clean-code-the-last-programming-language/show">reference</a>). In the case of FP, direct assignments are subtracted. Okay, we can still do assignments in Clojure, it is just (def name value), but it is considered bad to do it unless it is a constant value!</p>
<p>Feeling the difficulty, I decided to try writing a bittorrent client in Clojure. It just reminded me of how I am used to <em>assignment statements</em>.</p>
<p>##Why functional programming?##
After browsing on the web, I found out that LISP is from <strong>1958</strong>! WHAT!?! This seems really <strong>OLD</strong>, and it’s a new trend? Why is it that we are only going in this direction now?</p>
<p>To answer the question, I think we have to understand what we gain by limiting the <em>assignment statements</em> we use while we program: we gain that we do not have modifications on “variables” on runtime, so it is easier to work with concurrency.</p>
<p>My guess is it happened just now because of the <a href="https://en.wikipedia.org/wiki/Moore%27s_law">Moore’s Law</a> problem. We don’t get faster processors anymore, but more cores per processor. Remember the age in which a 486 was like 2x slower than a Pentium? Now we have had the i3, i5 and i7 like 5 years?</p>
<h2 id="conclusion">Conclusion</h2>
<p>The functional programming paradigm is here to stay. I like it and I will continue trying more with it. But I am not sure if it is the right fit for all the problems we might face while coding. Maybe it is good for some domains, but not for all.</p>
7 Days at recurse.com2015-04-08T23:04:00+00:00http://pietro.menna.net.br/personal/2015/04/08/7-days-at-recurse-com<p>Today my seventh day at <a href="https://www.recurse.com">Recurse Center</a> is over. The idea of this postis to reflect what happened from 3rd day until today.</p>
<p>Many of the thinks I have said before I would have liked doing at the begining of RC I haven’t even touched: for example: I did not solve any other <a href="https://projecteuler.net">Euler Project</a> problem, did not work on <a href="http://eudyptula-challenge.org">Eudyptula Challenge</a> and haven’t participated in any Social Events.</p>
<p>My third and fourth day I spent trying to understand Functional Programming and to about <a href="http://clojure.org">Clojure</a>. <em>Without success.</em> I got stuck many times.</p>
<p><strong>Getting Stuck seems to be the way of learning that there is some basic knowledge missing</strong> to continue the current task. I learnt during these days that in order to advance, I must be humble and <strong>ask for help</strong>.</p>
<p>This week was way better. I had the change to pair with a <a href="http://insomn.io">colleague</a> that already knew Function Programming, just not Clojure. Luckily for me he wanted also to learn Clojure, so we went through <a href="http://tryclj.org">4clojure</a> together. I am really glad because it unlocked many of the problems I was experiecing. He was very patient to explain even the basics to me.</p>
<p>After pairing with my colleague, Clojure started flowing a lot better. I also started following a MOOC called <a href="http://mooc.fi/courses/2014/clojure/">Functional Programming in Clojure</a>, I strongly recommend it if you would like to learn Clojure.</p>
<p>Anyway, I think this will be the last post about myself at Recurse Center. I plan to start blogging in a different fashion from now on. I hope to see you in my next post, which will be available shortly. It will be about <strong>Functional Programming</strong>.</p>
2 Days at recurse.com2015-03-31T18:14:00+00:00http://pietro.menna.net.br/personal/recurse-center/2015/03/31/2-days-at-recurse-com<p>Today my second day at <a href="https://www.recurse.com">Recurse Center</a> is gone. The idea of this post is to be a reflection of what happened during these two days.</p>
<p>The first day began with an introduction of what Recurse Center is all about: the facilitators, the <a href="https://www.recurse.com/manual#sub-sec-social-rules">Social Rules</a> of the space and other details.</p>
<p>During this introduction session, each of the <em>veterans RC</em> from Spring 1 batch gave hints to the the Spring 2 batch participants. After the intro, the daily Check-ins occured. The truth is that there were many things I looked into this day, but nothing really deep. I just felt lost the entire day.</p>
<p>What I did yesterday:</p>
<ul>
<li>I got to know that there is a book about lock picking available here!</li>
<li>Subscribed to the <a href="http://eudyptula-challenge.org">Eudyptula Challenge</a> and fixed mutt in the virtual machine to try Linux Kernel.</li>
<li>Checked what other colleagues were working on.</li>
<li>Participated in a Trio Programming (Pair programming with 3 coders?) for an App written using Rails. The truth is that the other two programmers were really experient in Ruby and I was not.</li>
<li>Finished 2 problems of <a href="https://projecteuler.net">Project Euler</a>. I really felt lucky to do this since this was the only actual code I wrote.</li>
<li>Attended a Speach about Consistency in Databases and what is the meaning of Consistency. This was part of the Monday’s dinner.</li>
</ul>
<p>To close my day feeling “even more lost” I got <em>phisically lost</em> taking a train in the wrong direction back home. It took me 3 hours to get home in total.</p>
<p>Luckily, to heal a bit my ego from yesterday, I managed to feel more productive today. After the daily check-ins, I got to speak to a Facilitator (Mary Rose) who recommended me to do tic-tac-toe in <a href="http://clojure.org">Clojure</a>. In order to achieve this task I began by doing the entire tutorial at <a href="http://tryclj.org">tryclojure</a>.</p>
<p>I learned then how to setup a Clojure environment for <a href="http://www.sublimetext.com">Sublime Text</a> by following this <a href="https://www.youtube.com/watch?v=wBl0rYXQdGg">presentation</a>. I also learned about <a href="http://leiningen.org">leiningen</a> which for my understanding is the packaging tool for Clojure.</p>
<p>I also prepared a presentation about the Template Method for tomorrow and got to write this blog. Unfortunately, no progress yet on the game. Hopefully tomorrow I start with it.</p>
<p>To close this post it is imposible not to mention that <em>Recursers</em> are all very open people, and very polite. This makes a great environment for learning and try to pair.</p>
Getting anxious and scared. 18 days to HS2015-03-12T23:07:00+00:00http://pietro.menna.net.br/personal/recurse-center/2015/03/12/really-ansious-and-scared<p>I am officially going to <a href="https://www.hackerschool.com">Hacker School</a>. I must accept that some days ago I started to get anxious because of everything I need to do, in order to get set to go to NYC. But this is actually the easy part.</p>
<p>The hard part is that I do not know what I will do there, and this really scares me. I just know I will be sorrounded by a lot of smart people, who really knows a lot about programming. I should pair with as many as possible to learn from different topics, but I have no clear objective.</p>
<p>Worse to all of this, is that I code during my day-to-day work on <a href="http://en.wikipedia.org/wiki/ABAP">ABAP</a>. This is not useful there, so I have the language barrier in two places: English and programming.</p>
<p>Since I will be allowed to be self-directed, I will ask if they think possible to try two very different things.</p>
<p>First, try something as low lever as a Kernel Hacking (First Half?). To my doom, I have not written a single line of C code since 2004?</p>
<p>Second, try something or functional (Julia?), or NojeJS/Web (Second Half?). Again, I only tried some JS for the application to HS, but the truth is I have no real experience on it.</p>
<p>Well, I better get reading about C and maybe try the <a href="http://eudyptula-challenge.org">Eudyptula Challengue</a>.</p>
Going for Improvements2014-12-02T23:05:00+00:00http://pietro.menna.net.br/personal/2014/12/02/going-for-improvements<p>Browsing through the internet we can realize some good guides for Jekyll blogs. Some of them contain really good ideas:</p>
<ul>
<li>Adding comments capabilities (Be able to form a community and receive feedback)</li>
<li>Adding Google Analytics (Know how is visiting you)</li>
<li>Adding Social Media Sharing Capabilities (Facebook Like, Twitter, etc)</li>
<li>Constructing an Archive from Jekyll (Better navigation for users)</li>
</ul>
<p>A great guide can be found <a href="http://joshualande.com/jekyll-github-pages-poole/">here</a>. In this guide, <a href="https://twitter.com/joshualande">Joshua</a> breifly describes how to add comments by using <a href="https://disqus.com">Disqus</a>, how to create the archive page, how to add Google Analytics, and at last how integrate with Twitter.</p>
<p>I will do some adjustments to this blog using this guide and latter on comment on it. There are other guides on the Internet, I read some others but I found this <a href="http://joshualande.com/jekyll-github-pages-poole/">one</a> to be the most straight to the point.</p>
<p><strong>Update</strong> I followed the guide and all which was commented is now on the site and working.</p>
Next Iteration2014-11-08T10:06:00+00:00http://pietro.menna.net.br/personal/2014/11/08/next-iteration<p>I started coding tic-tac-toe in a very iterative way, until now there were only two sessions of one hour or so each.</p>
<p>During each interaction, first I wrote some test code (using an xUnit like framework called <a href="http://qunitjs.com/">Qunit</a>), and then wrote some “productive code”.</p>
<p>In some cases, I skipped the sequence: wrote first code, then the test code. But in the iteraction I will try to stick to red-green-refactor.</p>
<p>Until now, all code written is useless: none other than the tests can use it.</p>
<p>In order to fix this, next iteraction of code will be different. I will do some HTML and the UI. A quick mock up can be seen in the image below:</p>
<p><img src="/public/tic-tac-toe-mockup1.png" alt="tic-tac-toe" title="Tic Tac Toe Mockup for UI" /></p>
<p>About the code: I am not really happy with the code I have currently, therefore I think some refactors may be needed. Luckily I have written tests which will ensure everything keeps working.</p>
<p>Wish me good luck!</p>
Many delays2014-10-19T22:31:00+00:00http://pietro.menna.net.br/personal/2014/10/19/many-delays<p>It is amazing how to find time to do something is really scarce when you have a child! I could not use my computer in like 6 days.</p>
<p>I tried to start the course at <a href="http://www.codecademy.com/">Codecademy</a> for Javascript on the 13th this month, but could only start it today. Anyway, I found it very basic and I think it will take some time to finish it.</p>
<p>I think I should start thinking on how to do the tic-tac-toe. Here is my plan:</p>
<p><img src="/public/tic-tac-toe-plan.png" alt="tic-tac-toe" title="Tic Tac Toe Image" /></p>
<p>Now, I have been thinking on what would be the issues I would have:</p>
<ul>
<li>First would be to identify the region the user clicked, but this can also be solved using the simpler solution of just using plain html buttons and it’s events.</li>
<li>Second problem: identify when someone has won the game.</li>
<li>Shall I implement the AI?</li>
<li>Shall I try Unit Testing?</li>
</ul>
<p>Well, I shall better continue reading about JS!</p>
<p>Cheers!</p>
<p><strong>29-10-2014 Update:</strong> Started actually doing the Codeacademy course. Only could do 25% so far.</p>
<p><strong>31-10-2014 Update:</strong> Continuing the CodeCademy course. It is very slow, but education wise seems good! (65 %) I hope I get to finish it in this weekend!</p>
<p><strong>03-11-2014 Update:</strong> Finished the course on CodeCademy!</p>
<p><strong>04-11-2014 Update:</strong> Started the repo, meanwhile not in <a href="http://github.com/">GitHub</a>, but in <a href="http://bitbucket.org/">BitBucket</a>. Check it <a href="http://bitbucket.org/pietromenna/tic-tac-toe/">here</a>.</p>
<p><strong>05-11-2014 Update:</strong> Still no GUI. Let’s think about it for a while, and then try to put into the next post!</p>
Trying to show some code2014-10-13T22:38:00+00:00http://pietro.menna.net.br/hacker_school/2014/10/13/trying-to-show-some-code<p>I would really like to go to <a href="https://www.hackerschool.com" title="Hacker School">Hacker School</a>. I think it is a life experience which may add a lot to me, but I do not know where to start to get there.</p>
<p>I am currently working for a large company, but I cannot disclose code I write there. I think this can slow me down on the selection process. Therefore this post has two intents, first to announce that I will try to apply for Hacker School, and the second is that I am planning to write a simple game here in Github so it can be seen by others.</p>
<p>The game will probably not be big thing, first of all it will be the first game I will ever write. I will think on what I can do and then post it here.</p>
<p>My first thought is the hackerschool suggestion of a tic-tac-toe. Let’s go for it!</p>
<p>Wish me good luck!</p>
Hello World!2014-05-04T18:37:56+00:00http://pietro.menna.net.br/hello_world/2014/05/04/hello-world<p>Hello World, this is my first post in the blogging world. I believe I took really long to get into it. My plan is to write some thoughts regarding what I read, do and sometimes about my hobbies.
I have no previous experience as a writer nor even as a technical writer, but I hope this is ok.
I hope you enjoy.</p>