It couldn’t take more than a few minutes, right? Actually, you may want to think again!
Monterey Bay Aquarium
tumblr dot com
One Nice Bug Per Day

Discoholic 🪩
Cosimo Galluzzi
we're not kids anymore.
occasionally subtle

oozey mess

No title available
AnasAbdin

@theartofmadeline

No title available
Aqua Utopia|海の底で記憶を紡ぐ
No title available

★

titsay

Love Begins
almost home
TVSTRANGERTHINGS
$LAYYYTER
seen from United States

seen from France

seen from Malaysia

seen from Germany
seen from United States
seen from United States

seen from South Korea

seen from Angola
seen from Canada

seen from Canada
seen from United States
seen from United States
seen from Ukraine
seen from United States
seen from United States
seen from United States

seen from United States
seen from United States

seen from United States
seen from United States
@hosamaly-tech
It couldn’t take more than a few minutes, right? Actually, you may want to think again!
A friend asked why they shouldn’t promote their docker test image to production. Scalability costs and attack surface area spring to mind.
Should a back-end component be fully encapsulated, including user messages?
A friend asked about the encapsulation of components in their project.
Suppose I'm creating a component to manage database interaction. Let's say there is a method to save an entity. This method needs to return something that indicates success. Now, I can make it return a success message. That would save me from having to add the success message at every callsite. Would you recommend doing this?
In my opinion, as long as your component is part of a programmatic API, it should return values that are easy to use programmatically.
Those values should not change based on requirements outside the core functionality of the component.
The component you're describing should return something that indicates success. The return value is not meant to be presented to the user. It is meant for your program to know that the operation was successful and act upon that knowledge.
Messages shown to the user are subject to requirements that are very different from those of your component. They need to be localised, internationalised, etc.
How hard could it be to change a message that is shown to the user? I tried to answer this question in the article How long does it take to change a text label?. I hope you'll find it useful!
Legacy software: update or rewrite?
A friend asked about an old project that his company is considering replacing. It would take about two years to rewrite it in full, he said. But it’s 10 years old, and it’s hard to make meaningful updates to it. How would you recommend approaching this situation?
If the project is built on top of a good platform where the updates are usually backwards-compatible, then I'd suggest the following.
Start with automating end-to-end acceptance tests. There are tools like cypress.io that make this relatively easy. Those tests should be runnable on production, staging, and development environments. If the system requirements are known, then building this test suite shouldn't take too long.
Additionally, we should set up a reliable development environment. You may wish to use solutions like docker-compose to enable developers to run the project locally. Combine this with a continuous integration pipeline that automates the process of running tests and deploying to your environments. Let the tests developed in the first step run against production whenever you deploy a change.
With the two steps above, I'd start injecting error detection and performance monitoring tools, such as Sentry.io or New Relic. I want to know the existing issues with the system before making changes. I also want to know whenever I introduce a new issue.
With a comprehensive set of acceptance tests, I would start updating the system platform and dependencies, step by step. Start by updating each of your dependencies to the latest patch versions (e.g. update Ruby 2.2.0 to 2.2.10). Move one patch version in every commit and let your CI run your tests against all commits. Do this to your platforms, libraries, operating system packages, etc. Then follow the same approach with minor versions.
With a detailed review of release notes and changelogs, you should be able to follow the same approach to update major versions of your dependencies and platforms. You may have to make more changes while doing this, but your test suite should tell you if you break anything.
With up-to-date platforms and dependencies, it's now easier to update the system. Some components can be rewritten in place, while others can be extracted out of the system. Either way, you have a usable system all the time. You can still fix bugs and introduce features without having to wait months for a full rewrite.
Where should I implement validation logic?
A friend asked about where they should implement their validation logic.
I know that client-side validation is indispensible. It's necessary to improve user experience and to reduce unnecessary load on the server. However, it's not sufficient because it can be easily bypassed. So I must implement server-side validation, but should I implement it in the application or in the database?
As he said, we should validate in the client to improve UX and to reduce unnecessary load on the server.
In my opinion, we should validate in the server-side application to ensure proper application of business rules, to have a clear codebase that expresses the full requirements, to report clear (and possibly translated) errors to the client side and in the logs, and to reduce unnecessary load on the database.
We should avoid validation in the database (using stored procedures or triggers) because the business logic becomes fragmented between the app and the database. It becomes harder to change business rules, requires more migrations (which may require downtime), and reduces performance (especially in the case of triggers). We may have to use them if multiple apps write to the same database and you can't control them (e.g. the billing database in telecom operators), but they often cause more problems than they solve.
We should make good use of valuable database constraints that can help the database improve performance and maintain referential integrity, especially foreign key constraints. We should use uniqueness constraints so that we don't have to lock the table from the app.
Use Docker images for stability, reproducibility, and scalability
A friend asked why they shouldn’t promote their test docker image to production. He mentioned that the test image contains some development tools that they use to investigate issues, and they typically build a separate image to production. I don’t think that this is the right approach, so I wrote this post.
Why do we use docker (or containerd) images? Because, among other things, we want:
Stability
Reproducibility
Scalability
Security
---
1. Stability: It works on my machine... and on every other machine, in the exact same way.
We may run some unit tests on specialised images (e.g. with test dependencies), but we should run acceptance tests against production images. That's the only way to guarantee that the tests are representative of production. Many teams use a staging environment that is a replica of their production environment.
---
2. Reproducibility: It was working yesterday... so it's safe to roll back.
We want to be able to reproduce issues using the same code, dependencies, and configuration. We also want to be able to roll back to a previous version knowing that it will work in the same way that it did previously. We want to avoid surprises resulting from any changes to the environment because of newer deployments. In other words, we want an immutable infrastructure.
---
3. Scalability: It works on one machine... it should work on ten.
We want to be able to scale rapidly on demand. It would be useless if we needed 15 minutes to scale to bursts of 5 minutes. Therefore, we want to minimise the time it takes to scale our application.
Container-based cloud infrastructure relies on sharing multiple hot machines between applications, assuming that some applications will scale down at times when others need to scale up. Given an image that fully describes the application's environment, we can deploy it to any machine with available resources.
However, this process is not effortless. Images have to be stored somewhere. They have to be downloaded to every new machine. Storage and bandwidth cost money (and environmental costs as well). They are also limited resources: any apps running on the machine will have less bandwidth while an image is being downloaded. And when the container runs, it consumes memory.
The smaller the image is, the less storage and bandwidth it will cost, the less time it will take to be downloaded and decompressed, and thus the quicker it will be ready for use. Additionally, its file system will be easier to cache, and the container may consume less memory in total.
---
4. Security: The less you know... the sounder you sleep.
We want to minimise the surface area exposed to attack. Security issues are usually caused by exploiting a chain of vulnerabilities, often in unexpected ways. To minimise this possibility, we should remove anything that is not necessary for our application. That's why we remove development dependencies from production images.
---
One may ask about the need for development tools in test environments.
If we need some tools to investigate issues on staging, then we need them even more on production. That's because we can choose to investigate issues on staging in our own time, but we'll have to investigate production issues under the pressure of an incident.
We have to choose our tools carefully to avoid introducing security issues, so maximise the use of distributed logging, request tracing, and metric visualisation, and keep your staging and production images the same.
Use of common HTTP status codes
In almost every HTTP application I work on, I manage to get into a discussion about which subset of HTTP status codes to use. The following describes how I generally like to handle the subject.
HTTP Status Codes should have common meanings. When multiple codes have a common meaning, then the server should only return the first code, and the client should handle all of them in the same way:
400, 406, 411, 414: bad request due to programming errors, including missing required headers or required parameters.
401, 419: When the auth token is required but missing
402: Skipped
403: You're authenticated, but not permitted.
404, 405: Not found
407: Skipped
408: A request to an external service timed out
409, 410, 412, 413, 415, 416, 417: Skipped
422: semantic errors
A very nice set of tutorials introducing akka
Changing the resolution of Ubuntu Server terminal (TTY)
After installing Ubuntu 12.04 Server, you get to log in using the TTY terminal. The resolution is fixed, but it can be changed. Use your favorite editor (e.g. vim or nano) to edit the file "/etc/default/grub" (you'll need sudo permissions), and uncomment the line to set GRUB_GFXMODE to the resolution you prefer. For example:
GRUB_GFXMODE=1024x768
The resolution must be one that is acceptable by your graphics card. For example, if you're running a VM inside VirtualBox, you have to use a VESA-compliant resolution. Then run the following command to update GRUB and to reboot:
sudo update-grub2 && sudo reboot
Programming Exercises for Beginners
I was looking for some programming exercises to help a friend who is just starting to learn how to program. I came across this set of exercises from different sources, and I found them useful.
http://basicprogrammingexercises.blogspot.com/ 28 problems divided into 7 exercise sets. Starting from the very basics.
http://www.sable.mcgill.ca/~clump/comp202/midterm/basic-problems.html 25 problems practicing your skills at using loops. Many problems can be solved using the solutions of earlier problems. A great resource for learning loops and code reuse!
http://codingbat.com/ Various problems categorized by topic and experience level. Includes solutions for some problems, and can check the correctness of your solution.
http://www.codechef.com/problems/easy?sort_by=Accuracy&sorting_order=desc If you really want to train hard, these are intermediate level problems that need some programming skill, but are not so hard for an experienced beginner. I sorted the problems with easiest first. You can submit your solution and the website will check its correctness. However, you will need to be able to read input and write output comfortably, and be confident of your looping skills.
As a general note, I'd suggest that you read the description of each problem, and write a function that returns the requested output without formatting, and then write another function that formats the output as required. This is a much better way for learning programming. And whenever possible, try to use your solutions to previous problems as building blocks to the solution of the current problem you're trying to solve (i.e. call your previously defined functions). Some exercise sets would ask you to create a class for every problem. This is usually unnecessary; a function for each problem would suffice. Some would ask you to create a 'main' method; if you're using a language that doesn't need one (e.g. python or ruby) then just ignore this instruction. Don't worry about the language of the exercise set; every problem can be solved with any programming language.
The Technology Radar for October 2012 is now ready. This is an analysis produced by ThoughtWorks twice a year. It is an assessment of the most important new technologies, which ones are ready to be used for production and which ones to wait for. It is a very useful guide for us to get to know about valuable new technologies. There are 107 technologies in this month's report, out of which 23 are ready to be adopted, 47 should be tried to prepare for their adoption later, 23 can be assessed to see whether they are suitable for you, and 14 should be avoided for now. I find this report a helpful guide to be aware of the important technologies all year round. It's easy to get to know about all of them throughout the coming 6 months. Just learn about one technology every working day. That should take just 5-15 minutes as long as you don't dive into the details (unless you find it really interesting).
Compass improves the SASS experience by providing useful mixins, functions, and more. You will also learn how to make CSS sprites with it in this episode.
If you’re tired of typing vendor-specific prefixes for CSS properties you should take a look at the Bourbon library which includes several SASS mixins and functions to make working with CSS more convenient. In this episode Ryan Bates shows you how to use it in a Rails application.
Sass extends CSS with variables, nesting, mixins and more. Watch as Ryan Bates shows how to convert plain CSS to SCSS in a Rails application.
Initializr is an HTML5 templates generator to help you getting started with a new project based on HTML5 Boilerplate. It generates for you a clean customizable template with just what you need to start!
Finding the Version of a running OpenERP Server
One of my customers needed to find out which version of OpenERP Server they were running. I couldn't find a way of knowing such information using the OpenERP GTK Client or the web client. But I found the version in two different ways according to the operating system:
On Linux, or if you are running from uncompiled source, you can find the current version of the server in the file bin/release.py.
$ cat bin/release.py | grep version version = '6.0.3'
On Windows, check the version of the OpenERP executable, which is typically in the path C:\Program Files\Server\6.0\openerp-server.exe. Right-Click it and choose Properties, then open the Version tab.