<?xml version="1.0" encoding="UTF-8"?>
<feed xml:lang="en-US" xmlns="http://www.w3.org/2005/Atom">
  <id>tag:blog.astrails.com,2016:mephisto/</id>
  <link rel="alternate" type="text/html" href="http://astrails.com"/>
  <link rel="self" type="application/atom+xml" href="http://astrails.com/blog/atom.xml"/>
  <title>Astrails - We create awesome web applications.</title>
  <updated>2024-04-04T01:44:48+00:00</updated>
  
  <entry>
    <id>tag:blog.astrails.com,2019-10-09:why-printing-business-cards</id>
    <link rel="alternate" type="text/html" href="http://astrails.com/blog/2019/10/09/why-printing-business-cards"/>
    <author>
      <name>boris</name>
    </author>
    <published>2019-10-09T09:53:44+00:00</published>
    <updated>2019-10-09T09:53:44+00:00</updated>
    
    <category term="business"/>
    <title>Why printing business cards when you can use an app</title>
    <summary type="html">&lt;p&gt;When it time came to print a new batch of business cards. I tried to find the latest design we’ve used a few years back and update them.&lt;/p&gt;

&lt;p&gt;Than, suddenly, I though: what if I had an app that allows sharing a business card. I searched App Store and found a few not trivial apps that probably only engineers can use.&lt;/p&gt;

&lt;p&gt;I had strong vision of how the app should look like and what should it do.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;It should allow having as many cards as I need. Well, I hold a few positions in a few companies Astrails work with.&lt;/li&gt;
  &lt;li&gt;It should not keep my personal information somewhere on remote servers, who knows how well the data is protected there.&lt;/li&gt;
  &lt;li&gt;And most important: it should be super easy to the receiving party to save the card, no extra apps should be required for that.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Imagine that you’re starting a meeting with 3 participants.&lt;/p&gt;

&lt;p&gt;Asking their phone numbers/emails and sharing your contact from a phone is not an option. It will take a lot of time and introduce an unnecessary hustle. The sharing should be as simple as passing a printed card.&lt;/p&gt;

&lt;p&gt;So, the answer for the last question is QR code with embedded vCard, default camera app since iOS 12 and Android 9 recognizes QR codes. And &lt;strong&gt;you should only show your phone to participants&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That’s how &lt;a href=&quot;https://www.virtual-business-card.co&quot;&gt;Virtual Business Card&lt;/a&gt; was built. There is a video there, so feel free to check it out.&lt;/p&gt;

&lt;p&gt;Right now it only works on iOS, Android version is coming soon.&lt;/p&gt;

    </summary>
    <content type="html">&lt;p&gt;When it time came to print a new batch of business cards. I tried to find the latest design we’ve used a few years back and update them.&lt;/p&gt;

&lt;p&gt;Than, suddenly, I though: what if I had an app that allows sharing a business card. I searched App Store and found a few not trivial apps that probably only engineers can use.&lt;/p&gt;

&lt;p&gt;I had strong vision of how the app should look like and what should it do.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;It should allow having as many cards as I need. Well, I hold a few positions in a few companies Astrails work with.&lt;/li&gt;
  &lt;li&gt;It should not keep my personal information somewhere on remote servers, who knows how well the data is protected there.&lt;/li&gt;
  &lt;li&gt;And most important: it should be super easy to the receiving party to save the card, no extra apps should be required for that.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Imagine that you’re starting a meeting with 3 participants.&lt;/p&gt;

&lt;p&gt;Asking their phone numbers/emails and sharing your contact from a phone is not an option. It will take a lot of time and introduce an unnecessary hustle. The sharing should be as simple as passing a printed card.&lt;/p&gt;

&lt;p&gt;So, the answer for the last question is QR code with embedded vCard, default camera app since iOS 12 and Android 9 recognizes QR codes. And &lt;strong&gt;you should only show your phone to participants&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That’s how &lt;a href=&quot;https://www.virtual-business-card.co&quot;&gt;Virtual Business Card&lt;/a&gt; was built. There is a video there, so feel free to check it out.&lt;/p&gt;

&lt;p&gt;Right now it only works on iOS, Android version is coming soon.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <id>tag:blog.astrails.com,2018-04-18:engineering-perspective-a-brief-history-of-web-development-part-4</id>
    <link rel="alternate" type="text/html" href="http://astrails.com/blog/2018/04/18/engineering-perspective-a-brief-history-of-web-development-part-4"/>
    <author>
      <name>boris</name>
    </author>
    <published>2018-04-18T15:04:16+00:00</published>
    <updated>2018-04-18T15:04:16+00:00</updated>
    
    <category term="business"/>
    <category term="technology"/>
    <title>The Engineering Perspective: A Brief History of Web Development. Part 4.</title>
    <summary type="html">&lt;p&gt;This is the 4rd and a last post of the series, &lt;a href=&quot;/blog/2018/04/18/engineering-perspective-a-brief-history-of-web-development-part-1&quot;&gt;Part 1&lt;/a&gt;, &lt;a href=&quot;/blog/2018/04/18/engineering-perspective-a-brief-history-of-web-development-part-2&quot;&gt;Part 2&lt;/a&gt;, &lt;a href=&quot;/blog/2018/04/18/engineering-perspective-a-brief-history-of-web-development-part-3&quot;&gt;Part 3&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The initial release of &lt;a href=&quot;https://angularjs.org/&quot;&gt;AngularJS&lt;/a&gt; happened just one week after the release of Backbone.JS, but was pretty much ignored for a while. It took some time to understand that in addition to Javascript, HTML and CSS, frontend developers that wanted to succeed with Angular had to learn ng-extensions too. Within a few years, Angular became very popular among developers. The only problem was that it was very easy to get started with it, but pretty complicated for more advanced things.&lt;/p&gt;

&lt;p&gt;Exactly one year later, ex-Rails core engineer Yehuda Katz released &lt;a href=&quot;https://www.emberjs.com/&quot;&gt;Ember&lt;/a&gt;. The first version was super opinionated and had a high entry barrier. Instead of trying to solve some small tactical issues, Ember directly targeted full-featured client-side web applications.&lt;/p&gt;

&lt;p&gt;Two years after that, Facebook released the first version of &lt;a href=&quot;https://reactjs.org/&quot;&gt;React&lt;/a&gt; - a breath of fresh air for frontend development. No monolithic applications, no misplaced MV (whatever) patterns, no extensions. Yes to Daft Punk’s &lt;a href=&quot;http://www.randomaccessmemories.com/&quot;&gt;Random Access Memories&lt;/a&gt;, album released that same year. The concept of React was very simple: representation is a function of an application state. Just implement the render function as a function of a state, include optional lifecycle callbacks, and React will take care of the rest.&lt;/p&gt;

&lt;p&gt;Later, Facebook introduced &lt;a href=&quot;https://github.com/facebook/flux&quot;&gt;Flux&lt;/a&gt;, frontend application architecture with unidirectional data flow. Dan Abramov’s react-redux based on &lt;a href=&quot;https://redux.js.org/&quot;&gt;Redux&lt;/a&gt; is probably the best implementation of the same concept of unidirectional data flow. It took about a year and a half for the community to catch up and by the end of 2014, React became extremely popular.&lt;/p&gt;

&lt;p&gt;And at the beginning of 2015, Facebook released React Native, a framework for building native apps with React that introduced the concept of “learn once write many”. iOS and Android applications will not share 100% of the code, but it is possible to reach 60-90% depending on the requirements. Compared with 0% code sharing when developing ObjectiveC/Swift for iOS and Java for Android, this is quite an achievement. Especially when taking into account that development is mostly done using React and Javascript.&lt;/p&gt;

&lt;p&gt;Angular 2 entered the beta stage in late 2015 and was released in September 2016. Its breaking changes and a few concept shifts deprecated most of the knowledge and experience that developers had accumulated while working with Angular. Some developers were angry about these changes because they had to re-invest time to basically writing everything again from scratch using Angular 2. But some were happy because the new version was better engineered and more fun to work with.&lt;/p&gt;

&lt;p&gt;Initially released in 2014, &lt;a href=&quot;https://vuejs.org&quot;&gt;Vue&lt;/a&gt; gained popularity around the same time that Angular 2 was released. It was what Angular JS should have been from the beginning.&lt;/p&gt;

&lt;p&gt;At the end of 2015 and most of 2016 there was a popular joke: two new Javascript frameworks were probably released while you were reading this sentence. And another three have just died.&lt;/p&gt;

&lt;p&gt;Q&amp;amp;A&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;So, what should I use now?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;React. Unless you have someone on board who is familiar with Angular, then use Angular or Vue and consider React anyway.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What should I learn if I am just entering this field?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;React. It will allow you to develop desktop/mobile web apps, native mobile apps, and even Windows applications using &lt;a href=&quot;https://github.com/Microsoft/react-native-windows&quot;&gt;react-native-windows&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What’s next?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Progressive_Web_Apps&quot;&gt;Progressive Web Apps&lt;/a&gt; are the next stage in web frontends. It deserves its own series of posts.&lt;/p&gt;

    </summary>
    <content type="html">&lt;p&gt;This is the 4rd and a last post of the series, &lt;a href=&quot;/blog/2018/04/18/engineering-perspective-a-brief-history-of-web-development-part-1&quot;&gt;Part 1&lt;/a&gt;, &lt;a href=&quot;/blog/2018/04/18/engineering-perspective-a-brief-history-of-web-development-part-2&quot;&gt;Part 2&lt;/a&gt;, &lt;a href=&quot;/blog/2018/04/18/engineering-perspective-a-brief-history-of-web-development-part-3&quot;&gt;Part 3&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The initial release of &lt;a href=&quot;https://angularjs.org/&quot;&gt;AngularJS&lt;/a&gt; happened just one week after the release of Backbone.JS, but was pretty much ignored for a while. It took some time to understand that in addition to Javascript, HTML and CSS, frontend developers that wanted to succeed with Angular had to learn ng-extensions too. Within a few years, Angular became very popular among developers. The only problem was that it was very easy to get started with it, but pretty complicated for more advanced things.&lt;/p&gt;

&lt;p&gt;Exactly one year later, ex-Rails core engineer Yehuda Katz released &lt;a href=&quot;https://www.emberjs.com/&quot;&gt;Ember&lt;/a&gt;. The first version was super opinionated and had a high entry barrier. Instead of trying to solve some small tactical issues, Ember directly targeted full-featured client-side web applications.&lt;/p&gt;

&lt;p&gt;Two years after that, Facebook released the first version of &lt;a href=&quot;https://reactjs.org/&quot;&gt;React&lt;/a&gt; - a breath of fresh air for frontend development. No monolithic applications, no misplaced MV (whatever) patterns, no extensions. Yes to Daft Punk’s &lt;a href=&quot;http://www.randomaccessmemories.com/&quot;&gt;Random Access Memories&lt;/a&gt;, album released that same year. The concept of React was very simple: representation is a function of an application state. Just implement the render function as a function of a state, include optional lifecycle callbacks, and React will take care of the rest.&lt;/p&gt;

&lt;p&gt;Later, Facebook introduced &lt;a href=&quot;https://github.com/facebook/flux&quot;&gt;Flux&lt;/a&gt;, frontend application architecture with unidirectional data flow. Dan Abramov’s react-redux based on &lt;a href=&quot;https://redux.js.org/&quot;&gt;Redux&lt;/a&gt; is probably the best implementation of the same concept of unidirectional data flow. It took about a year and a half for the community to catch up and by the end of 2014, React became extremely popular.&lt;/p&gt;

&lt;p&gt;And at the beginning of 2015, Facebook released React Native, a framework for building native apps with React that introduced the concept of “learn once write many”. iOS and Android applications will not share 100% of the code, but it is possible to reach 60-90% depending on the requirements. Compared with 0% code sharing when developing ObjectiveC/Swift for iOS and Java for Android, this is quite an achievement. Especially when taking into account that development is mostly done using React and Javascript.&lt;/p&gt;

&lt;p&gt;Angular 2 entered the beta stage in late 2015 and was released in September 2016. Its breaking changes and a few concept shifts deprecated most of the knowledge and experience that developers had accumulated while working with Angular. Some developers were angry about these changes because they had to re-invest time to basically writing everything again from scratch using Angular 2. But some were happy because the new version was better engineered and more fun to work with.&lt;/p&gt;

&lt;p&gt;Initially released in 2014, &lt;a href=&quot;https://vuejs.org&quot;&gt;Vue&lt;/a&gt; gained popularity around the same time that Angular 2 was released. It was what Angular JS should have been from the beginning.&lt;/p&gt;

&lt;p&gt;At the end of 2015 and most of 2016 there was a popular joke: two new Javascript frameworks were probably released while you were reading this sentence. And another three have just died.&lt;/p&gt;

&lt;p&gt;Q&amp;amp;A&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;So, what should I use now?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;React. Unless you have someone on board who is familiar with Angular, then use Angular or Vue and consider React anyway.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What should I learn if I am just entering this field?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;React. It will allow you to develop desktop/mobile web apps, native mobile apps, and even Windows applications using &lt;a href=&quot;https://github.com/Microsoft/react-native-windows&quot;&gt;react-native-windows&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What’s next?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Progressive_Web_Apps&quot;&gt;Progressive Web Apps&lt;/a&gt; are the next stage in web frontends. It deserves its own series of posts.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <id>tag:blog.astrails.com,2018-04-18:engineering-perspective-a-brief-history-of-web-development-part-3</id>
    <link rel="alternate" type="text/html" href="http://astrails.com/blog/2018/04/18/engineering-perspective-a-brief-history-of-web-development-part-3"/>
    <author>
      <name>boris</name>
    </author>
    <published>2018-04-18T15:04:16+00:00</published>
    <updated>2018-04-18T15:04:16+00:00</updated>
    
    <category term="business"/>
    <category term="technology"/>
    <title>The Engineering Perspective: A Brief History of Web Development. Part 3.</title>
    <summary type="html">&lt;p&gt;This is the 3rd post of the series, &lt;a href=&quot;/blog/2018/04/18/engineering-perspective-a-brief-history-of-web-development-part-1&quot;&gt;Part 1&lt;/a&gt;, &lt;a href=&quot;/blog/2018/04/18/engineering-perspective-a-brief-history-of-web-development-part-2&quot;&gt;Part 2&lt;/a&gt;, &lt;a href=&quot;/blog/2018/04/18/engineering-perspective-a-brief-history-of-web-development-part-4&quot;&gt;Part 4&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Ok, so now initially loaded web pages have almost no HTML code, but have tons of Javascript and CSS instead. This is good, because these assets could be served from CDN which in theory makes the whole page load much faster.&lt;/p&gt;

&lt;p&gt;But the page load time is not the optimization objective. What really matters is the time that it takes for the page to become usable, in other words - when users can start consuming the content on the page.&lt;/p&gt;

&lt;p&gt;So besides the time that it takes to load all of the assets, we also have to consider the time spent inside the Javascript to fetch relevant data using APIs and to render it on the client side by updating the DOM. It’s user CPU time that renders the content in this case. User CPU seems free from an application vendor perspective since the user pays for it and for the electricity to power it. But that’s not 100% true.&lt;/p&gt;

&lt;p&gt;The first iPhone was launched about 2 years after the original AJAX piece was published. And that triggered a new epoch of mobile browsers. But mobile browser CPU time is not free. It doesn’t cost money directly. The price is the user’s disappointment with battery life. Now users don’t blame lazy developers who wrote suboptimal code, they blame mobile device vendors for using bad batteries.&lt;/p&gt;

&lt;p&gt;Anyway, &lt;a href=&quot;http://prototypejs.org/&quot;&gt;Prototype JS&lt;/a&gt; was released in the same month as the AJAX article and attracted a lot of attention. It allowed direct DOM manipulation, contained cross-browser abstractions, and was bundled with its own Javascript effects library. Prototype JS was probably the most important advancement in frontend development since the invention of &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Learn/CSS&quot;&gt;CSS&lt;/a&gt; in 1996. In any case, the first version of &lt;a href=&quot;https://jquery.com/&quot;&gt;jQuery&lt;/a&gt; was released 18 months later. It becomes a de-facto standard for the next 9 years because it was direct DOM manipulation done right.&lt;/p&gt;

&lt;p&gt;A crazy mix of server-rendered HTML pages and lots of jQuery based mostly on spaghetti code to update these pages, plus a few JSON/XML APIs here and there, was characteristic of &lt;a href=&quot;https://en.wikipedia.org/wiki/Web_2.0&quot;&gt;Web 2.0&lt;/a&gt; development for many years. By that time, the prestige of frontend development had significantly declined. Backend engineers looked down on HTML/CSS/JS folks that spent most of their time showing and hiding divs and changing the colors of different elements.&lt;/p&gt;

&lt;p&gt;Barack Obama inaugurated as the 44th President of the United States of America just 4 months before the first release of &lt;a href=&quot;https://nodejs.org/en/&quot;&gt;Node.js&lt;/a&gt;. Node.js was accepted quite sceptically as a nice try to bring Javascript to server side, and there was no significant adoption of Node.js in web development. Probably a release of &lt;a href=&quot;https://expressjs.com/&quot;&gt;Express&lt;/a&gt; a year later became a trigger of a wide adoption of Node.js. Today Node.js is a quite popular choice for backend development, especially taking into account that modern frontend frameworks allow the same Javascript code to perform rendering on both sides: server and client.&lt;/p&gt;

&lt;p&gt;The state of frontend development was now where backend development had been in the late 1990s - a zoo of approaches and technologies. Different groups tried to come up with a frontend framework that would straighten out the mess. Jeremy Ashkenas came up with the most successful one at the time, &lt;a href=&quot;http://backbonejs.org/&quot;&gt;Backbone.JS&lt;/a&gt;. Released in 2010, this client-side MVC framework restored some order to jQuery-based frontend apps. A few years later, &lt;a href=&quot;https://marionettejs.com/&quot;&gt;Marionette&lt;/a&gt; came along to attempt to enhance the functionality of BackboneJS and to become a Rails-style opinionated frontend framework.&lt;/p&gt;

&lt;p&gt;Then more and more engineers began to develop frontend-based apps. And the fun was about to begin.&lt;/p&gt;

    </summary>
    <content type="html">&lt;p&gt;This is the 3rd post of the series, &lt;a href=&quot;/blog/2018/04/18/engineering-perspective-a-brief-history-of-web-development-part-1&quot;&gt;Part 1&lt;/a&gt;, &lt;a href=&quot;/blog/2018/04/18/engineering-perspective-a-brief-history-of-web-development-part-2&quot;&gt;Part 2&lt;/a&gt;, &lt;a href=&quot;/blog/2018/04/18/engineering-perspective-a-brief-history-of-web-development-part-4&quot;&gt;Part 4&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Ok, so now initially loaded web pages have almost no HTML code, but have tons of Javascript and CSS instead. This is good, because these assets could be served from CDN which in theory makes the whole page load much faster.&lt;/p&gt;

&lt;p&gt;But the page load time is not the optimization objective. What really matters is the time that it takes for the page to become usable, in other words - when users can start consuming the content on the page.&lt;/p&gt;

&lt;p&gt;So besides the time that it takes to load all of the assets, we also have to consider the time spent inside the Javascript to fetch relevant data using APIs and to render it on the client side by updating the DOM. It’s user CPU time that renders the content in this case. User CPU seems free from an application vendor perspective since the user pays for it and for the electricity to power it. But that’s not 100% true.&lt;/p&gt;

&lt;p&gt;The first iPhone was launched about 2 years after the original AJAX piece was published. And that triggered a new epoch of mobile browsers. But mobile browser CPU time is not free. It doesn’t cost money directly. The price is the user’s disappointment with battery life. Now users don’t blame lazy developers who wrote suboptimal code, they blame mobile device vendors for using bad batteries.&lt;/p&gt;

&lt;p&gt;Anyway, &lt;a href=&quot;http://prototypejs.org/&quot;&gt;Prototype JS&lt;/a&gt; was released in the same month as the AJAX article and attracted a lot of attention. It allowed direct DOM manipulation, contained cross-browser abstractions, and was bundled with its own Javascript effects library. Prototype JS was probably the most important advancement in frontend development since the invention of &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Learn/CSS&quot;&gt;CSS&lt;/a&gt; in 1996. In any case, the first version of &lt;a href=&quot;https://jquery.com/&quot;&gt;jQuery&lt;/a&gt; was released 18 months later. It becomes a de-facto standard for the next 9 years because it was direct DOM manipulation done right.&lt;/p&gt;

&lt;p&gt;A crazy mix of server-rendered HTML pages and lots of jQuery based mostly on spaghetti code to update these pages, plus a few JSON/XML APIs here and there, was characteristic of &lt;a href=&quot;https://en.wikipedia.org/wiki/Web_2.0&quot;&gt;Web 2.0&lt;/a&gt; development for many years. By that time, the prestige of frontend development had significantly declined. Backend engineers looked down on HTML/CSS/JS folks that spent most of their time showing and hiding divs and changing the colors of different elements.&lt;/p&gt;

&lt;p&gt;Barack Obama inaugurated as the 44th President of the United States of America just 4 months before the first release of &lt;a href=&quot;https://nodejs.org/en/&quot;&gt;Node.js&lt;/a&gt;. Node.js was accepted quite sceptically as a nice try to bring Javascript to server side, and there was no significant adoption of Node.js in web development. Probably a release of &lt;a href=&quot;https://expressjs.com/&quot;&gt;Express&lt;/a&gt; a year later became a trigger of a wide adoption of Node.js. Today Node.js is a quite popular choice for backend development, especially taking into account that modern frontend frameworks allow the same Javascript code to perform rendering on both sides: server and client.&lt;/p&gt;

&lt;p&gt;The state of frontend development was now where backend development had been in the late 1990s - a zoo of approaches and technologies. Different groups tried to come up with a frontend framework that would straighten out the mess. Jeremy Ashkenas came up with the most successful one at the time, &lt;a href=&quot;http://backbonejs.org/&quot;&gt;Backbone.JS&lt;/a&gt;. Released in 2010, this client-side MVC framework restored some order to jQuery-based frontend apps. A few years later, &lt;a href=&quot;https://marionettejs.com/&quot;&gt;Marionette&lt;/a&gt; came along to attempt to enhance the functionality of BackboneJS and to become a Rails-style opinionated frontend framework.&lt;/p&gt;

&lt;p&gt;Then more and more engineers began to develop frontend-based apps. And the fun was about to begin.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <id>tag:blog.astrails.com,2018-04-18:engineering-perspective-a-brief-history-of-web-development-part-2</id>
    <link rel="alternate" type="text/html" href="http://astrails.com/blog/2018/04/18/engineering-perspective-a-brief-history-of-web-development-part-2"/>
    <author>
      <name>boris</name>
    </author>
    <published>2018-04-18T15:04:16+00:00</published>
    <updated>2018-04-18T15:04:16+00:00</updated>
    
    <category term="business"/>
    <category term="technology"/>
    <title>The Engineering Perspective: A Brief History of Web Development. Part 2.</title>
    <summary type="html">&lt;p&gt;This is the 2nd post of the series, &lt;a href=&quot;/blog/2018/04/18/engineering-perspective-a-brief-history-of-web-development-part-1&quot;&gt;Part 1&lt;/a&gt;, &lt;a href=&quot;/blog/2018/04/18/engineering-perspective-a-brief-history-of-web-development-part-3&quot;&gt;Part 3&lt;/a&gt;, &lt;a href=&quot;/blog/2018/04/18/engineering-perspective-a-brief-history-of-web-development-part-4&quot;&gt;Part 4&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;So the main question is - what does the backend code do in order to render its output? Static assets aside, the response will most probably include data that was fetched from some sort of database. If the output is a full HTML page, it should also include proper HTML markup around the data. This is called server-side rendering because the content of the whole HTML page is rendered by the server.&lt;/p&gt;

&lt;p&gt;The bigger the HTML page the more expensive rendering will be.&lt;/p&gt;

&lt;p&gt;In earlier web applications, each request type was handled by a separate script file. The script was interpreted line by line to render a web page. Several approaches were introduced to make the code more maintainable and &lt;a href=&quot;https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller&quot;&gt;MVC&lt;/a&gt; was one of the most successful ones. It’s worth mentioning that &lt;a href=&quot;http://rubyonrails.org/&quot;&gt;Rails&lt;/a&gt;, a Ruby-based MVC implementation that was initially released the same year that Zuckerberg &lt;a href=&quot;https://www.theguardian.com/technology/2007/jul/25/media.newmedia&quot;&gt;launched&lt;/a&gt; Facebook, contributed significantly to the wide adoption of the MVC design pattern in web development. Model-View-Controller frameworks for many languages were released in the late 2000s.&lt;/p&gt;

&lt;p&gt;MVC separates the concerns of the backend code. Requests are handled by a controller, it uses models to fetch data. The data is passed to views which are responsible for rendering pages. It’s a much better solution than a single script file that does all of the above. But tons of CPU and memory are still used to prepare HTML pages that became bigger and bigger.&lt;/p&gt;

&lt;p&gt;And then along came &lt;a href=&quot;http://adaptivepath.org/ideas/ajax-new-approach-web-applications/&quot;&gt;Asynchronous JavaScript + XML&lt;/a&gt;, aka AJAX, almost nine years after the FastCGI specification was published and in the same year that the 3rd episode of Star Wars was released. The AJAX approach suggests fetching extra data from the server to update the current screen without reloading the entire page.&lt;/p&gt;

&lt;p&gt;Web servers can render many types of content in response to an &lt;a href=&quot;https://en.wikipedia.org/wiki/XMLHttpRequest&quot;&gt;XMLHttpRequest&lt;/a&gt; - including HTML segments that can replace an existing part of the web page, Javascript code that can do anything (including UI effects and replacing parts of the HTML page) once it is evaluated by the browser, and pure data that is serialized in XML/JSON format.&lt;/p&gt;

&lt;p&gt;Javascript code running in a browser uses XML/JSON data to update the content of a page. Beforehand, Javascript was used mostly for UI effects. This marked the beginning of a significant shift in the concept of web development. It was the beginning of client-side rendering.
This shift actually affects backends as well, that no longer have to render expensive HTML pages. Instead, their main function is serving APIs. It almost makes the V-portion of the MVC framework redundant, because JSON format doesn’t include anything but the data itself. Now server CPUs and memory can be used for better purposes.&lt;/p&gt;

    </summary>
    <content type="html">&lt;p&gt;This is the 2nd post of the series, &lt;a href=&quot;/blog/2018/04/18/engineering-perspective-a-brief-history-of-web-development-part-1&quot;&gt;Part 1&lt;/a&gt;, &lt;a href=&quot;/blog/2018/04/18/engineering-perspective-a-brief-history-of-web-development-part-3&quot;&gt;Part 3&lt;/a&gt;, &lt;a href=&quot;/blog/2018/04/18/engineering-perspective-a-brief-history-of-web-development-part-4&quot;&gt;Part 4&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;So the main question is - what does the backend code do in order to render its output? Static assets aside, the response will most probably include data that was fetched from some sort of database. If the output is a full HTML page, it should also include proper HTML markup around the data. This is called server-side rendering because the content of the whole HTML page is rendered by the server.&lt;/p&gt;

&lt;p&gt;The bigger the HTML page the more expensive rendering will be.&lt;/p&gt;

&lt;p&gt;In earlier web applications, each request type was handled by a separate script file. The script was interpreted line by line to render a web page. Several approaches were introduced to make the code more maintainable and &lt;a href=&quot;https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller&quot;&gt;MVC&lt;/a&gt; was one of the most successful ones. It’s worth mentioning that &lt;a href=&quot;http://rubyonrails.org/&quot;&gt;Rails&lt;/a&gt;, a Ruby-based MVC implementation that was initially released the same year that Zuckerberg &lt;a href=&quot;https://www.theguardian.com/technology/2007/jul/25/media.newmedia&quot;&gt;launched&lt;/a&gt; Facebook, contributed significantly to the wide adoption of the MVC design pattern in web development. Model-View-Controller frameworks for many languages were released in the late 2000s.&lt;/p&gt;

&lt;p&gt;MVC separates the concerns of the backend code. Requests are handled by a controller, it uses models to fetch data. The data is passed to views which are responsible for rendering pages. It’s a much better solution than a single script file that does all of the above. But tons of CPU and memory are still used to prepare HTML pages that became bigger and bigger.&lt;/p&gt;

&lt;p&gt;And then along came &lt;a href=&quot;http://adaptivepath.org/ideas/ajax-new-approach-web-applications/&quot;&gt;Asynchronous JavaScript + XML&lt;/a&gt;, aka AJAX, almost nine years after the FastCGI specification was published and in the same year that the 3rd episode of Star Wars was released. The AJAX approach suggests fetching extra data from the server to update the current screen without reloading the entire page.&lt;/p&gt;

&lt;p&gt;Web servers can render many types of content in response to an &lt;a href=&quot;https://en.wikipedia.org/wiki/XMLHttpRequest&quot;&gt;XMLHttpRequest&lt;/a&gt; - including HTML segments that can replace an existing part of the web page, Javascript code that can do anything (including UI effects and replacing parts of the HTML page) once it is evaluated by the browser, and pure data that is serialized in XML/JSON format.&lt;/p&gt;

&lt;p&gt;Javascript code running in a browser uses XML/JSON data to update the content of a page. Beforehand, Javascript was used mostly for UI effects. This marked the beginning of a significant shift in the concept of web development. It was the beginning of client-side rendering.
This shift actually affects backends as well, that no longer have to render expensive HTML pages. Instead, their main function is serving APIs. It almost makes the V-portion of the MVC framework redundant, because JSON format doesn’t include anything but the data itself. Now server CPUs and memory can be used for better purposes.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <id>tag:blog.astrails.com,2018-04-18:engineering-perspective-a-brief-history-of-web-development-part-1</id>
    <link rel="alternate" type="text/html" href="http://astrails.com/blog/2018/04/18/engineering-perspective-a-brief-history-of-web-development-part-1"/>
    <author>
      <name>boris</name>
    </author>
    <published>2018-04-18T15:04:16+00:00</published>
    <updated>2018-04-18T15:04:16+00:00</updated>
    
    <category term="business"/>
    <category term="technology"/>
    <title>The Engineering Perspective: A Brief History of Web Development. Part 1.</title>
    <summary type="html">&lt;p&gt;Two months after the end of WWII in Europe, Vannevar Bush published an essay called &lt;a href=&quot;https://www.w3.org/History/1945/vbush/vbush.shtml&quot;&gt;As We May Think&lt;/a&gt;. He introduced a concept called &lt;a href=&quot;https://en.wikipedia.org/wiki/Memex&quot;&gt;memex&lt;/a&gt;, which became the forerunner and inspiration for hypertext.&lt;/p&gt;

&lt;p&gt;Forty-six years later, Tim Berners-Lee released the very first web server, called &lt;a href=&quot;https://en.wikipedia.org/wiki/CERN_httpd&quot;&gt;CERN httpd&lt;/a&gt;, and a browser that worked on NeXT. Later that same year, Nicola Pellow developed a text mode browser for other platforms. At the same time, on the other side of the planet, Pablo Escobar &lt;a href=&quot;(http://articles.latimes.com/1991-06-20/news/mn-1456_1_united-states)&quot;&gt;surrendered&lt;/a&gt; himself to the police. CERN httpd’s latest version 3.0 &lt;a href=&quot;https://github.com/tjgillies/cern-httpd&quot;&gt;is available&lt;/a&gt; on GitHub.&lt;/p&gt;

&lt;p&gt;Two years later, &lt;a href=&quot;http://www.ncsa.illinois.edu/&quot;&gt;NCSA&lt;/a&gt; published a &lt;a href=&quot;http://1997.webhistory.org/www.lists/www-talk.1993q4/0485.html&quot;&gt;specification&lt;/a&gt; for calling command line executables. The output of these executables could be rendered back via the web server over an HTTP protocol as a response. This was basically the birth of the dynamic web and ultimately resulted in a formal &lt;a href=&quot;https://tools.ietf.org/html/rfc3875&quot;&gt;CGI&lt;/a&gt; standard.&lt;/p&gt;

&lt;p&gt;Three years of extensive use of this solution showed that launching a separate process for each request and tearing it down at the end of the request was a waste of resources. Let’s ignore the forgotten Netscape server API for a minute and note that &lt;a href=&quot;https://web.archive.org/web/20160119141816/http://www.fastcgi.com/drupal/node/6?q=node%2F22&quot;&gt;Fast CGI&lt;/a&gt; was the greatest achievement since CERN httpd. Requests from the web server could be routed to a FastCGI server (via a socket, TCP or named pipe). The FastCGI server keeps data-rendering processes running for a series of requests, so that responses are returned to the web server and then to the client. This approach significantly reduced server load and response time.&lt;/p&gt;

&lt;p&gt;Another popular approach that was actively developed during that time is called embedded interpreters. Some well-known examples are Apache’s mod_perl (released in 1996) and mod_php. They basically keep the interpreter running constantly in order to save launch/tear down overhead and to transfer the script code to the interpreter process, which in return renders back the response body. Interpreters usually have access to the web server’s internal APIs and act as extensions of the web server.&lt;/p&gt;

&lt;p&gt;CGI, FastCGI and embedded interpreters are still widely used today (Apr 2018).&lt;/p&gt;

&lt;p&gt;But all this has nothing to do with frontends. I just mentioned it to give you an overview of how backends render their outputs to a browser. Of course I skipped some basic things like sessions, caching, reverse proxies, database connections because they are less relevant to the big picture.&lt;/p&gt;

&lt;p&gt;The big picture is quite simple. A request is received by a web server, which somehow gets the output of the backend application code and renders it back to a client application. In most cases that client application is a browser. As for static HTML / CSS / Javascript assets, the backend application code just reads content from a file (database, Redis, Memcache, tape, &lt;a href=&quot;https://whatis.techtarget.com/reference/History-of-the-punch-card&quot;&gt;punch card&lt;/a&gt; or whatever storage is used) and sends the content back.&lt;/p&gt;

&lt;p&gt;This is the 1st post of the series, &lt;a href=&quot;/blog/2018/04/18/engineering-perspective-a-brief-history-of-web-development-part-2&quot;&gt;Part 2&lt;/a&gt;, &lt;a href=&quot;/blog/2018/04/18/engineering-perspective-a-brief-history-of-web-development-part-3&quot;&gt;Part 3&lt;/a&gt;, &lt;a href=&quot;/blog/2018/04/18/engineering-perspective-a-brief-history-of-web-development-part-4&quot;&gt;Part 4&lt;/a&gt;.&lt;/p&gt;

    </summary>
    <content type="html">&lt;p&gt;Two months after the end of WWII in Europe, Vannevar Bush published an essay called &lt;a href=&quot;https://www.w3.org/History/1945/vbush/vbush.shtml&quot;&gt;As We May Think&lt;/a&gt;. He introduced a concept called &lt;a href=&quot;https://en.wikipedia.org/wiki/Memex&quot;&gt;memex&lt;/a&gt;, which became the forerunner and inspiration for hypertext.&lt;/p&gt;

&lt;p&gt;Forty-six years later, Tim Berners-Lee released the very first web server, called &lt;a href=&quot;https://en.wikipedia.org/wiki/CERN_httpd&quot;&gt;CERN httpd&lt;/a&gt;, and a browser that worked on NeXT. Later that same year, Nicola Pellow developed a text mode browser for other platforms. At the same time, on the other side of the planet, Pablo Escobar &lt;a href=&quot;(http://articles.latimes.com/1991-06-20/news/mn-1456_1_united-states)&quot;&gt;surrendered&lt;/a&gt; himself to the police. CERN httpd’s latest version 3.0 &lt;a href=&quot;https://github.com/tjgillies/cern-httpd&quot;&gt;is available&lt;/a&gt; on GitHub.&lt;/p&gt;

&lt;p&gt;Two years later, &lt;a href=&quot;http://www.ncsa.illinois.edu/&quot;&gt;NCSA&lt;/a&gt; published a &lt;a href=&quot;http://1997.webhistory.org/www.lists/www-talk.1993q4/0485.html&quot;&gt;specification&lt;/a&gt; for calling command line executables. The output of these executables could be rendered back via the web server over an HTTP protocol as a response. This was basically the birth of the dynamic web and ultimately resulted in a formal &lt;a href=&quot;https://tools.ietf.org/html/rfc3875&quot;&gt;CGI&lt;/a&gt; standard.&lt;/p&gt;

&lt;p&gt;Three years of extensive use of this solution showed that launching a separate process for each request and tearing it down at the end of the request was a waste of resources. Let’s ignore the forgotten Netscape server API for a minute and note that &lt;a href=&quot;https://web.archive.org/web/20160119141816/http://www.fastcgi.com/drupal/node/6?q=node%2F22&quot;&gt;Fast CGI&lt;/a&gt; was the greatest achievement since CERN httpd. Requests from the web server could be routed to a FastCGI server (via a socket, TCP or named pipe). The FastCGI server keeps data-rendering processes running for a series of requests, so that responses are returned to the web server and then to the client. This approach significantly reduced server load and response time.&lt;/p&gt;

&lt;p&gt;Another popular approach that was actively developed during that time is called embedded interpreters. Some well-known examples are Apache’s mod_perl (released in 1996) and mod_php. They basically keep the interpreter running constantly in order to save launch/tear down overhead and to transfer the script code to the interpreter process, which in return renders back the response body. Interpreters usually have access to the web server’s internal APIs and act as extensions of the web server.&lt;/p&gt;

&lt;p&gt;CGI, FastCGI and embedded interpreters are still widely used today (Apr 2018).&lt;/p&gt;

&lt;p&gt;But all this has nothing to do with frontends. I just mentioned it to give you an overview of how backends render their outputs to a browser. Of course I skipped some basic things like sessions, caching, reverse proxies, database connections because they are less relevant to the big picture.&lt;/p&gt;

&lt;p&gt;The big picture is quite simple. A request is received by a web server, which somehow gets the output of the backend application code and renders it back to a client application. In most cases that client application is a browser. As for static HTML / CSS / Javascript assets, the backend application code just reads content from a file (database, Redis, Memcache, tape, &lt;a href=&quot;https://whatis.techtarget.com/reference/History-of-the-punch-card&quot;&gt;punch card&lt;/a&gt; or whatever storage is used) and sends the content back.&lt;/p&gt;

&lt;p&gt;This is the 1st post of the series, &lt;a href=&quot;/blog/2018/04/18/engineering-perspective-a-brief-history-of-web-development-part-2&quot;&gt;Part 2&lt;/a&gt;, &lt;a href=&quot;/blog/2018/04/18/engineering-perspective-a-brief-history-of-web-development-part-3&quot;&gt;Part 3&lt;/a&gt;, &lt;a href=&quot;/blog/2018/04/18/engineering-perspective-a-brief-history-of-web-development-part-4&quot;&gt;Part 4&lt;/a&gt;.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <id>tag:blog.astrails.com,2018-03-21:noname-ai-based-names-generator</id>
    <link rel="alternate" type="text/html" href="http://astrails.com/blog/2018/03/21/noname-ai-based-names-generator"/>
    <author>
      <name>boris</name>
    </author>
    <published>2018-03-21T12:12:12+00:00</published>
    <updated>2018-03-21T12:12:12+00:00</updated>
    
    <category term="AI"/>
    <category term="React"/>
    <category term="ML"/>
    <title>Astrails noname - AI-based names generator</title>
    <summary type="html">&lt;p&gt;AI-based names generator.&lt;/p&gt;

&lt;p&gt;Earlier this months we released &lt;a href=&quot;https://noname.astrails.com&quot;&gt;noname&lt;/a&gt;, an AI-based project names generator.&lt;/p&gt;

&lt;p&gt;It uses a neural language model trained on CrunchBase data.&lt;/p&gt;

&lt;p&gt;There will be a separate post(s) covering the whole flow of preparing a data set, training a model, serving a model, etc.&lt;/p&gt;

&lt;p&gt;The backend is a &lt;a href=&quot;http://cherrypy.org/&quot;&gt;CherryPy&lt;/a&gt;-based server serving JSON API to make predictions based on models implemented in &lt;a href=&quot;https://keras.io/&quot;&gt;Keras&lt;/a&gt; with &lt;a href=&quot;https://www.tensorflow.org/&quot;&gt;TensorFlow&lt;/a&gt; backend.&lt;/p&gt;

&lt;p&gt;The webapp is implemented in &lt;a href=&quot;https://reactjs.org/&quot;&gt;React&lt;/a&gt; obviously ;-)&lt;/p&gt;

    </summary>
    <content type="html">&lt;p&gt;AI-based names generator.&lt;/p&gt;

&lt;p&gt;Earlier this months we released &lt;a href=&quot;https://noname.astrails.com&quot;&gt;noname&lt;/a&gt;, an AI-based project names generator.&lt;/p&gt;

&lt;p&gt;It uses a neural language model trained on CrunchBase data.&lt;/p&gt;

&lt;p&gt;There will be a separate post(s) covering the whole flow of preparing a data set, training a model, serving a model, etc.&lt;/p&gt;

&lt;p&gt;The backend is a &lt;a href=&quot;http://cherrypy.org/&quot;&gt;CherryPy&lt;/a&gt;-based server serving JSON API to make predictions based on models implemented in &lt;a href=&quot;https://keras.io/&quot;&gt;Keras&lt;/a&gt; with &lt;a href=&quot;https://www.tensorflow.org/&quot;&gt;TensorFlow&lt;/a&gt; backend.&lt;/p&gt;

&lt;p&gt;The webapp is implemented in &lt;a href=&quot;https://reactjs.org/&quot;&gt;React&lt;/a&gt; obviously ;-)&lt;/p&gt;
</content>
  </entry>
  <entry>
    <id>tag:blog.astrails.com,2017-06-14:building-and-deploying-react-applications</id>
    <link rel="alternate" type="text/html" href="http://astrails.com/blog/2017/06/14/building-and-deploying-react-applications"/>
    <author>
      <name>boris</name>
    </author>
    <published>2017-06-14T12:12:12+00:00</published>
    <updated>2017-06-14T12:12:12+00:00</updated>
    
    <category term="React"/>
    <category term="speaking"/>
    <title>Building and deploying React applications</title>
    <summary type="html">&lt;p&gt;Building and deploying React applications.&lt;/p&gt;

&lt;p&gt;Another presentation I was giving at Applied Materials office about React applications.&lt;/p&gt;

&lt;p&gt;It’s trivial today to start writing and debugging some React code, but it’s not 100% clear how
to properly deploy the application, manage versions and what implications that has on the build configurations.
Especially if you want to allow different versions for different users in order to perform some A/B testing,
testing new features in production environment, come up with some UI experiments, or gradually roll out new
features for a subset of users.&lt;/p&gt;

&lt;p&gt;In this presentation I hopefully covered all that.&lt;/p&gt;

&lt;iframe src=&quot;//www.slideshare.net/slideshow/embed_code/key/3SHccPVSKHXjVU&quot; width=&quot;595&quot; height=&quot;485&quot; frameborder=&quot;0&quot; marginwidth=&quot;0&quot; marginheight=&quot;0&quot; scrolling=&quot;no&quot; style=&quot;border:1px solid #CCC; border-width:1px; margin-bottom:5px; max-width: 100%;&quot; allowfullscreen=&quot;&quot;&gt; &lt;/iframe&gt;
&lt;div style=&quot;margin-bottom:5px&quot;&gt; &lt;strong&gt; &lt;a href=&quot;//www.slideshare.net/astrails/building-and-deploying-react-applications&quot; title=&quot;Building and deploying React applications&quot; target=&quot;_blank&quot;&gt;Building and deploying React applications&lt;/a&gt; &lt;/strong&gt; from &lt;strong&gt;&lt;a href=&quot;https://www.slideshare.net/astrails&quot; target=&quot;_blank&quot;&gt;Astrails&lt;/a&gt;&lt;/strong&gt; &lt;/div&gt;

&lt;p&gt;Code is &lt;a href=&quot;https://github.com/astrails/rails_react_webpack&quot;&gt;here&lt;/a&gt;. It shows the Rails example but it’s super easy to
do the same in Node or Python, slides cover the differences.&lt;/p&gt;

    </summary>
    <content type="html">&lt;p&gt;Building and deploying React applications.&lt;/p&gt;

&lt;p&gt;Another presentation I was giving at Applied Materials office about React applications.&lt;/p&gt;

&lt;p&gt;It’s trivial today to start writing and debugging some React code, but it’s not 100% clear how
to properly deploy the application, manage versions and what implications that has on the build configurations.
Especially if you want to allow different versions for different users in order to perform some A/B testing,
testing new features in production environment, come up with some UI experiments, or gradually roll out new
features for a subset of users.&lt;/p&gt;

&lt;p&gt;In this presentation I hopefully covered all that.&lt;/p&gt;

&lt;iframe src=&quot;//www.slideshare.net/slideshow/embed_code/key/3SHccPVSKHXjVU&quot; width=&quot;595&quot; height=&quot;485&quot; frameborder=&quot;0&quot; marginwidth=&quot;0&quot; marginheight=&quot;0&quot; scrolling=&quot;no&quot; style=&quot;border:1px solid #CCC; border-width:1px; margin-bottom:5px; max-width: 100%;&quot; allowfullscreen=&quot;&quot;&gt; &lt;/iframe&gt;
&lt;div style=&quot;margin-bottom:5px&quot;&gt; &lt;strong&gt; &lt;a href=&quot;//www.slideshare.net/astrails/building-and-deploying-react-applications&quot; title=&quot;Building and deploying React applications&quot; target=&quot;_blank&quot;&gt;Building and deploying React applications&lt;/a&gt; &lt;/strong&gt; from &lt;strong&gt;&lt;a href=&quot;https://www.slideshare.net/astrails&quot; target=&quot;_blank&quot;&gt;Astrails&lt;/a&gt;&lt;/strong&gt; &lt;/div&gt;

&lt;p&gt;Code is &lt;a href=&quot;https://github.com/astrails/rails_react_webpack&quot;&gt;here&lt;/a&gt;. It shows the Rails example but it’s super easy to
do the same in Node or Python, slides cover the differences.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <id>tag:blog.astrails.com,2016-12-08:machine-learning-make-your-ruby-code-smarter</id>
    <link rel="alternate" type="text/html" href="http://astrails.com/blog/2016/12/08/machine-learning-make-your-ruby-code-smarter"/>
    <author>
      <name>boris</name>
    </author>
    <published>2016-12-08T12:12:12+00:00</published>
    <updated>2016-12-08T12:12:12+00:00</updated>
    
    <category term="ML"/>
    <category term="speaking"/>
    <title>Machine Learning: Make Your Ruby Code Smarter</title>
    <summary type="html">&lt;p&gt;Machine Learning: Make Your Ruby Code Smarter.&lt;/p&gt;

&lt;p&gt;I was giving this presentation at &lt;a href=&quot;https://railsisrael2016.events.co.il/home&quot;&gt;RailsIsrael 2016&lt;/a&gt; conference. I covered the basics of all major algorithms for supervised and unsupervised learning without a lot of math just to give the idea of what’s possible to do with them.&lt;/p&gt;

&lt;p&gt;There is also a demo and ruby code of Waze/Uber like suggested destinations prediction with fast neural networks on Ruby.&lt;/p&gt;

&lt;p&gt;Slides are &lt;a href=&quot;https://assets.astrails.com/machine-learning.pdf&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Code is &lt;a href=&quot;https://github.com/borisnadion/suggested-destination-demo&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Video and screen cast should be published at &lt;a href=&quot;https://railsisrael2016.events.co.il/pages/video-gallery&quot;&gt;here&lt;/a&gt; shortly.&lt;/p&gt;

    </summary>
    <content type="html">&lt;p&gt;Machine Learning: Make Your Ruby Code Smarter.&lt;/p&gt;

&lt;p&gt;I was giving this presentation at &lt;a href=&quot;https://railsisrael2016.events.co.il/home&quot;&gt;RailsIsrael 2016&lt;/a&gt; conference. I covered the basics of all major algorithms for supervised and unsupervised learning without a lot of math just to give the idea of what’s possible to do with them.&lt;/p&gt;

&lt;p&gt;There is also a demo and ruby code of Waze/Uber like suggested destinations prediction with fast neural networks on Ruby.&lt;/p&gt;

&lt;p&gt;Slides are &lt;a href=&quot;https://assets.astrails.com/machine-learning.pdf&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Code is &lt;a href=&quot;https://github.com/borisnadion/suggested-destination-demo&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Video and screen cast should be published at &lt;a href=&quot;https://railsisrael2016.events.co.il/pages/video-gallery&quot;&gt;here&lt;/a&gt; shortly.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <id>tag:blog.astrails.com,2016-06-17:migrating-from-flux-to-redux</id>
    <link rel="alternate" type="text/html" href="http://astrails.com/blog/2016/06/17/migrating-from-flux-to-redux"/>
    <author>
      <name>boris</name>
    </author>
    <published>2016-06-17T12:12:12+00:00</published>
    <updated>2016-06-17T12:12:12+00:00</updated>
    
    <category term="React"/>
    <category term="speaking"/>
    <title>Migrating from Flux to Redux</title>
    <summary type="html">&lt;p&gt;Migrating from Flux to Redux.&lt;/p&gt;

&lt;p&gt;I was talking about migrating from Flux to Redux last Wednesday at Reacts Israel meetup.&lt;/p&gt;

&lt;p&gt;Video and screen cast should be published at &lt;a href=&quot;http://www.meetup.com/ReactJS-IL/events/231710615/&quot;&gt;ReactJS-IL&lt;/a&gt; shortly.&lt;/p&gt;

&lt;p&gt;TL;DR:
When I started to work with React back in Apr-2015 there were many libraries to manage the application flow. I decided to start with classical FB’s Flux implementation to understand what’s missed there. Eventually react-redux and redux solved most of issues I had with Flux. This talk is about practical aspects of migration from Flux to Redux.&lt;/p&gt;

&lt;p&gt;Slides are &lt;a href=&quot;https://assets.astrails.com/flux-and-redux.pdf&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Code is &lt;a href=&quot;https://github.com/astrails/react-presentation-flux-redux&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Start with tag #flux, then #redux, then switch to master branch.&lt;/p&gt;

    </summary>
    <content type="html">&lt;p&gt;Migrating from Flux to Redux.&lt;/p&gt;

&lt;p&gt;I was talking about migrating from Flux to Redux last Wednesday at Reacts Israel meetup.&lt;/p&gt;

&lt;p&gt;Video and screen cast should be published at &lt;a href=&quot;http://www.meetup.com/ReactJS-IL/events/231710615/&quot;&gt;ReactJS-IL&lt;/a&gt; shortly.&lt;/p&gt;

&lt;p&gt;TL;DR:
When I started to work with React back in Apr-2015 there were many libraries to manage the application flow. I decided to start with classical FB’s Flux implementation to understand what’s missed there. Eventually react-redux and redux solved most of issues I had with Flux. This talk is about practical aspects of migration from Flux to Redux.&lt;/p&gt;

&lt;p&gt;Slides are &lt;a href=&quot;https://assets.astrails.com/flux-and-redux.pdf&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Code is &lt;a href=&quot;https://github.com/astrails/react-presentation-flux-redux&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Start with tag #flux, then #redux, then switch to master branch.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <id>tag:blog.astrails.com,2015-12-07:one-huge-timesaver</id>
    <link rel="alternate" type="text/html" href="http://astrails.com/blog/2015/12/07/one-huge-timesaver"/>
    <author>
      <name>boris</name>
    </author>
    <published>2015-12-07T20:30:32+00:00</published>
    <updated>2015-12-07T20:30:32+00:00</updated>
    
    <category term="business"/>
    <title>One Huge Timesaver</title>
    <summary type="html">&lt;p&gt;Content Creation Flow (5 mins reading time).&lt;/p&gt;

&lt;p&gt;Today we’re going to talk about an effective way of defining new product features.&lt;/p&gt;

&lt;p&gt;A product feature can be defined in two ways – from either a marketing or engineering perspective. The marketing approach means explaining how the feature benefits the customer, and the engineering perspective means explaining how that feature works.&lt;/p&gt;

&lt;p&gt;Some product managers may miss this distinction and explain a new feature to their engineering team from a marketing perspective. As a result, engineering may work really hard and possibly proceed in the wrong direction, losing time and money for the company.&lt;/p&gt;


    </summary>
    <content type="html">&lt;p&gt;Content Creation Flow (5 mins reading time).&lt;/p&gt;

&lt;p&gt;Today we’re going to talk about an effective way of defining new product features.&lt;/p&gt;

&lt;p&gt;A product feature can be defined in two ways – from either a marketing or engineering perspective. The marketing approach means explaining how the feature benefits the customer, and the engineering perspective means explaining how that feature works.&lt;/p&gt;

&lt;p&gt;Some product managers may miss this distinction and explain a new feature to their engineering team from a marketing perspective. As a result, engineering may work really hard and possibly proceed in the wrong direction, losing time and money for the company.
READMORE&lt;/p&gt;

&lt;p&gt;For example, let’s take the well-known concept of an online marketplace that sells several products and describe an exciting new feature from a marketing perspective. Our marketplace will now display a list of 10 featured products on its home page.&lt;/p&gt;

&lt;p&gt;Well, engineering will have lots of questions. Who will feature the products? How will they be featured? How long will they be featured? Who will un-feature the products? All of these issues have to be clarified.&lt;/p&gt;

&lt;p&gt;At Astrails, we’ve come up with the concept of Content Creation Flow. It’s a way of first explaining how data is created in the system and then understanding how it’s consumed, instead of vice-versa. Also, at any given time we can only use terms that were defined beforehand (i.e. objects that have already been created). It makes the concept a little harder to define, but so much easier to understand.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;p&gt;Facts - application admin users moderate the products; a products back office UI is used to edit/update the products.&lt;/p&gt;

&lt;p&gt;Flow - application admins should be able to mark a product as “featured” through the back office UI. The ten most recently featured products should appear on the home page.&lt;/p&gt;

&lt;p&gt;In this example, the creation process is described before the consumption process.&lt;/p&gt;

&lt;p&gt;This makes it easier for engineering to understand and implement the feature. In our example, each product will have a featured timestamp. In order to feature a product, application admins will trigger the timestamp to be set to the current time. The 10 most recent products should appear on the home page in descending order of those timestamps. We’ll cache these 10 products and invalidate the cache when any product is changed or when a different  product is featured by the application administrator. Crystal clear. For engineering.&lt;/p&gt;

&lt;p&gt;This concept can and should be applied to wireframing and designing user interfaces as well.&lt;/p&gt;

&lt;p&gt;Let’s assume again that we’re building a new online marketplace. The designer starts by designing a home page instead of starting with the inner pages, and presents a first draft showing 10 featured product boxes. Each box has a product image, product name and a short description.&lt;/p&gt;

&lt;p&gt;Engineering then receives the homepage design and discovers that there is no short product description field at all. So, what now? Engineering can add this field, but they don’t have a UI for the seller to provide a short description. The web designer can remove the field and use the seller’s name instead. In either case, precious time has been wasted.&lt;/p&gt;

&lt;p&gt;A better way to develop the product would be to design the seller’s product-editing page first. Once that is ready, designers will know that the only fields supported are product name and long product description. Long descriptions can obviously not be used in a small product display box, so the designer will use the seller’s name in the homepage design in the first place.&lt;/p&gt;

&lt;p&gt;Everything is clear from the engineering perspective - the data to be consumed has already been created and the engineers know how to query it.&lt;/p&gt;

&lt;p&gt;So, we discovered that feature specs are described more clearly using Content Creation Flow. Designs and UI can also be produced more efficiently according to this flow.&lt;/p&gt;

&lt;p&gt;It turns out that engineering can use the same flow as well and save lots of time.&lt;/p&gt;

&lt;p&gt;How? Let’s imagine the following situation. Engineering got specs for some new exciting feature. The specs are 90% complete. The engineers are ready to start coding but there’s an editing screen that hasn’t been designed yet. They decide not to wait. They’ll just seed some data, render other pages that use seed data and get back to that editing screen later. After a while, it turns out that the editing screen has more fields then they expected, with complex relations between them and seeds are not good enough. Now engineering needs to refactor the code and throw away lots of their work before they even start adding the new fields. Result: time wasted.&lt;/p&gt;

&lt;p&gt;If they had started with the editing screens, all of the fields and relations that will be used later would have already been defined.&lt;/p&gt;

&lt;p&gt;There’s nothing wrong with seeding some data for development, but it’s probably not a good idea to do so before it becomes clear what the data will look like. So, creation before consumption. Always.&lt;/p&gt;

&lt;p&gt;If you have any questions about content creation flow, or any questions at all, feel free to email me at &lt;a href=&quot;mailto:boris@astrails.com&quot;&gt;boris@astrails.com&lt;/a&gt;.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <id>tag:blog.astrails.com,2014-12-04:homebrew-yosemite-issues</id>
    <link rel="alternate" type="text/html" href="http://astrails.com/blog/2014/12/04/homebrew-yosemite-issues"/>
    <author>
      <name>vitaly</name>
    </author>
    <published>2014-12-04T17:09:17+00:00</published>
    <updated>2014-12-04T17:09:17+00:00</updated>
    
    <category term="gcc"/>
    <category term="osx"/>
    <category term="yosemite"/>
    <category term="homebrew"/>
    <title>Homebrew Yosemite Issues</title>
    <summary type="html">&lt;p&gt;There seems to be quite a few issues with Homebrew compilation after upgrade to
Yosemite.&lt;/p&gt;

&lt;p&gt;While some of them are easily fixed by upgrading relevant GCC packages, one
problem kept me from upgrading my macvim for a while.&lt;/p&gt;

&lt;p&gt;Short version: if after upgrading all the gcc related packages you still get
errors on Yosemite, try upgrading python as well.&lt;/p&gt;

&lt;p&gt;Read more for details…&lt;/p&gt;


    </summary>
    <content type="html">&lt;p&gt;There seems to be quite a few issues with Homebrew compilation after upgrade to
Yosemite.&lt;/p&gt;

&lt;p&gt;While some of them are easily fixed by upgrading relevant GCC packages, one
problem kept me from upgrading my macvim for a while.&lt;/p&gt;

&lt;p&gt;Short version: if after upgrading all the gcc related packages you still get
errors on Yosemite, try upgrading python as well.&lt;/p&gt;

&lt;p&gt;Read more for details…
READMORE&lt;/p&gt;

&lt;p&gt;There seems to be quite a few issues with Homebrew compilation after upgrade to
Yosemite.&lt;/p&gt;

&lt;p&gt;While some of them are easily fixed by upgrading relevant GCC packages, one
problem kept me from upgrading my macvim for a while.&lt;/p&gt;

&lt;p&gt;Short version: if after upgrading all the gcc related packages you still get
errors on Yosemite, try upgrading python as well.&lt;/p&gt;

&lt;p&gt;Compiling macvim produced the following error:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;✗ brew upgrade macvim                                                                                                                                                                             ruby-2.1.2
&lt;span class=&quot;o&quot;&gt;==&amp;gt;&lt;/span&gt; Upgrading 1 outdated package, with result:
macvim 7.4-73_1
&lt;span class=&quot;o&quot;&gt;==&amp;gt;&lt;/span&gt; Upgrading macvim
&lt;span class=&quot;o&quot;&gt;==&amp;gt;&lt;/span&gt; Downloading https://github.com/b4winckler/macvim/archive/snapshot-73.tar.gz
Already downloaded: /Library/Caches/Homebrew/macvim-7.4-73.tar.gz
&lt;span class=&quot;o&quot;&gt;==&amp;gt;&lt;/span&gt; ./configure &lt;span class=&quot;nt&quot;&gt;--with-features&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;huge &lt;span class=&quot;nt&quot;&gt;--enable-multibyte&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--with-macarchs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;x86_64 &lt;span class=&quot;nt&quot;&gt;--enable-perlinterp&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--enable-rubyinterp&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--enable-tclinterp&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--with-tlib&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;ncurses &lt;span class=&quot;nt&quot;&gt;--with-compiledby&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;Homebrew &lt;span class=&quot;nt&quot;&gt;--with-local-dir&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/usr/l
checking &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;gcc... clang
checking whether the C compiler works... no
configure: error: &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;sb&quot;&gt;`&lt;/span&gt;/private/tmp/macvim-YQsceV/macvim-snapshot-73/src&lt;span class=&quot;s1&quot;&gt;':
configure: error: C compiler cannot create executables
See `config.log'&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;more details

READ THIS: http://git.io/brew-troubleshooting

These open issues may also &lt;span class=&quot;nb&quot;&gt;help&lt;/span&gt;:
macvim failed to build on 10.9 because of x11 &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;https://github.com/Homebrew/homebrew/issues/30253&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;That issue #30253 turned out not to be relevant.&lt;/p&gt;

&lt;p&gt;On the surface it looked like its a common yosemite gcc problem, but even after
upgrading all to latest it didn’t work.&lt;/p&gt;

&lt;p&gt;Next I tried ‘brew upgrade -v macvim’&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;✗ brew upgrade &lt;span class=&quot;nt&quot;&gt;-v&lt;/span&gt; macvim
...
&lt;span class=&quot;o&quot;&gt;==&amp;gt;&lt;/span&gt; ENV
HOMEBREW_CC: clang
...
LDFLAGS: &lt;span class=&quot;nt&quot;&gt;-L&lt;/span&gt;/usr/local/Cellar/python/2.7.3/Frameworks/Python.framework/Versions/2.7/lib/python2.7/config &lt;span class=&quot;nt&quot;&gt;-ldl&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-framework&lt;/span&gt; CoreFoundation &lt;span class=&quot;nt&quot;&gt;-lpython2&lt;/span&gt;.7 &lt;span class=&quot;nt&quot;&gt;-u&lt;/span&gt; _PyMac_Error Python.framework/Versions/2.7/Python
...
Error: macvim 7.4-73 did not build
Logs:
     /Users/vitaly/Library/Logs/Homebrew/macvim/01.configure
     /Users/vitaly/Library/Logs/Homebrew/macvim/01.configure.cc
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Looking in the &lt;code class=&quot;highlighter-rouge&quot;&gt;01.configure.cc&lt;/code&gt; I found the following:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;clang called with: -I/usr/local/Cellar/python/2.7.3/Frameworks/Python.framework/Versions/2.7/include/python2.7 -I/usr/local/Cellar/python/2.7.3/Frameworks/Python.framework/Versions/2.7/include/python2.7 -fno-strict-aliasing -fno-common -dynamic -I/usr/local/include -DNDEBUG -g -O3 -Wall -Wstrict-prototypes -arch x86_64 -L/usr/local/Cellar/python/2.7.3/Frameworks/Python.framework/Versions/2.7/lib/python2.7/config -ldl -framework CoreFoundation -lpython2.7 -u _PyMac_Error Python.framework/Versions/2.7/Python conftest.c
superenv executed: clang -pipe -Os -march=native -I/usr/local/Cellar/python/2.7.3/Frameworks/Python.framework/Versions/2.7/include/python2.7 -I/usr/local/Cellar/python/2.7.3/Frameworks/Python.framework/Versions/2.7/include/python2.7 -fno-strict-aliasing -fno-common -dynamic -I/usr/local/include -DNDEBUG -g -O3 -Wall -Wstrict-prototypes -arch x86_64 -L/usr/local/Cellar/python/2.7.3/Frameworks/Python.framework/Versions/2.7/lib/python2.7/config -ldl -framework CoreFoundation -lpython2.7 -u _PyMac_Error Python.framework/Versions/2.7/Python conftest.c -isystem/usr/local/include -isystem/usr/include/libxml2 -isystem/System/Library/Frameworks/OpenGL.framework/Versions/Current/Headers -L/usr/local/lib -L/System/Library/Frameworks/OpenGL.framework/Versions/Current/Libraries -Wl,-headerpad_max_install_names
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;so I just created a very simple &lt;code class=&quot;highlighter-rouge&quot;&gt;foo.c&lt;/code&gt; file and tried to compile it with the
same gcc arguments:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;✗ clang &lt;span class=&quot;nt&quot;&gt;-I&lt;/span&gt;/usr/local/Cellar/python/2.7.3/Frameworks/Python.framework/Versions/2.7/include/python2.7 &lt;span class=&quot;nt&quot;&gt;-I&lt;/span&gt;/usr/local/Cellar/python/2.7.3/Frameworks/Python.framework/Versions/2.7/include/python2.7 &lt;span class=&quot;nt&quot;&gt;-fno-strict-aliasing&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-fno-common&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-dynamic&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-I&lt;/span&gt;/usr/local/include &lt;span class=&quot;nt&quot;&gt;-DNDEBUG&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-g&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-O3&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-Wall&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-Wstrict-prototypes&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-arch&lt;/span&gt; x86_64 &lt;span class=&quot;nt&quot;&gt;-L&lt;/span&gt;/usr/local/Cellar/python/2.7.3/Frameworks/Python.framework/Versions/2.7/lib/python2.7/config &lt;span class=&quot;nt&quot;&gt;-ldl&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-framework&lt;/span&gt; CoreFoundation &lt;span class=&quot;nt&quot;&gt;-lpython2&lt;/span&gt;.7 &lt;span class=&quot;nt&quot;&gt;-u&lt;/span&gt; _PyMac_Error Python.framework/Versions/2.7/Python foo.c
clang: error: no such file or directory: &lt;span class=&quot;s1&quot;&gt;'Python.framework/Versions/2.7/Python'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Note the &lt;code class=&quot;highlighter-rouge&quot;&gt;Python.framework/Versions/2.7/Python&lt;/code&gt; part. it seems to be relative
and not the full path. Digging a bit on the internet python turned out to be
the problem.&lt;/p&gt;

&lt;p&gt;After removing and re-installing python all turned out to work. The same part
&lt;code class=&quot;highlighter-rouge&quot;&gt;01.configure.cc&lt;/code&gt; after python upgrade:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;clang called with: -I/usr/local/Cellar/python/2.7.8_2/Frameworks/Python.framework/Versions/2.7/include/python2.7 -I/usr/local/Cellar/python/2.7.8_2/Frameworks/Python.framework/Versions/2.7/include/python2.7 -fno-strict-aliasing -fno-common -dynamic -I/usr/local/include -I/usr/local/opt/sqlite/include -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -L/usr/local/Cellar/python/2.7.8_2/Frameworks/Python.framework/Versions/2.7/lib/python2.7/config -ldl -framework CoreFoundation -lpython2.7 conftest.c
superenv executed: clang -pipe -Os -march=native -I/usr/local/Cellar/python/2.7.8_2/Frameworks/Python.framework/Versions/2.7/include/python2.7 -I/usr/local/Cellar/python/2.7.8_2/Frameworks/Python.framework/Versions/2.7/include/python2.7 -fno-strict-aliasing -fno-common -dynamic -I/usr/local/include -I/usr/local/opt/sqlite/include -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -L/usr/local/Cellar/python/2.7.8_2/Frameworks/Python.framework/Versions/2.7/lib/python2.7/config -ldl -framework CoreFoundation -lpython2.7 conftest.c -isystem/usr/local/include -isystem/usr/include/libxml2 -isystem/System/Library/Frameworks/OpenGL.framework/Versions/Current/Headers -L/usr/local/lib -L/System/Library/Frameworks/OpenGL.framework/Versions/Current/Libraries -Wl,-headerpad_max_install_names
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Have fun!&lt;/p&gt;
</content>
  </entry>
  <entry>
    <id>tag:blog.astrails.com,2014-07-28:dragonfly-imagemagick-and-memory-bloat</id>
    <link rel="alternate" type="text/html" href="http://astrails.com/blog/2014/07/28/dragonfly-imagemagick-and-memory-bloat"/>
    <author>
      <name>boris</name>
    </author>
    <published>2014-07-28T06:16:23+00:00</published>
    <updated>2014-07-28T06:16:23+00:00</updated>
    
    <category term="development"/>
    <category term="rails"/>
    <category term="imagemagick"/>
    <category term="dragonfly"/>
    <category term="tips"/>
    <title>Dragonfly, ImageMagick and memory bloat</title>
    <summary type="html">&lt;p&gt;We usually use &lt;a href=&quot;https://github.com/markevans/dragonfly/&quot;&gt;dragonfly&lt;/a&gt; to handle user generated assets in almost all the projects.
But sometimes dragonfly with ImageMagick doesn’t play nicely in a limited environments like &lt;a href=&quot;http://heroku.com/&quot;&gt;heroku&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We were getting tons of &lt;a href=&quot;https://devcenter.heroku.com/articles/error-codes#r14-memory-quota-exceeded&quot;&gt;R14 - Memory quota exceeded&lt;/a&gt;
errors after analyzing even small images using &lt;a href=&quot;http://www.imagemagick.org/&quot;&gt;ImageMagick&lt;/a&gt;’s identify command.&lt;/p&gt;

&lt;p&gt;Here is how we solved it.&lt;/p&gt;


    </summary>
    <content type="html">&lt;p&gt;We usually use &lt;a href=&quot;https://github.com/markevans/dragonfly/&quot;&gt;dragonfly&lt;/a&gt; to handle user generated assets in almost all the projects.
But sometimes dragonfly with ImageMagick doesn’t play nicely in a limited environments like &lt;a href=&quot;http://heroku.com/&quot;&gt;heroku&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We were getting tons of &lt;a href=&quot;https://devcenter.heroku.com/articles/error-codes#r14-memory-quota-exceeded&quot;&gt;R14 - Memory quota exceeded&lt;/a&gt;
errors after analyzing even small images using &lt;a href=&quot;http://www.imagemagick.org/&quot;&gt;ImageMagick&lt;/a&gt;’s identify command.&lt;/p&gt;

&lt;p&gt;Here is how we solved it.
READMORE&lt;/p&gt;

&lt;p&gt;First of all the context.&lt;/p&gt;

&lt;p&gt;We use direct S3 upload on the client side in order to reduce the heroku servers load.
Client goes to the Rails server with a sign request and gets back a policy, a signature and a key (aka path) of the resource to be uploaded to S3.
There are more details about &lt;a href=&quot;https://github.com/blueimp/jQuery-File-Upload&quot;&gt;jQuery-File-Upload&lt;/a&gt; flow &lt;a href=&quot;https://github.com/blueimp/jQuery-File-Upload/wiki/Upload-directly-to-S3&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Once the file is uploaded client goes to ImagesController and creates a record for the image.&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;My::ImagesController&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;InheritedResources&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Base&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;before_filter&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:authenticate_user!&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;actions&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:create&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;#...&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;respond_to&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:json&lt;/span&gt;

  &lt;span class=&quot;c1&quot;&gt;# ...&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;“create” action receives the only parameter original_image_uid which is passed to the model.&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Image&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;ActiveRecord&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Base&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;belongs_to&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:user&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;dragonfly_accessor&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:original_image&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;original_uid&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;original_image_uid&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;original_image_width&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;original_image&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;analyse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:width&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;original_image_height&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;original_image&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;analyse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:height&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;original_image_size&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;original_image&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;size&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This is where all the (image-) magic happens. Before the model is saved we analyze the image width, height and the file size in order to use later according to the application business needs.&lt;/p&gt;

&lt;p&gt;First call to the original_image will download the file from S3, files can be upto a few megabytes, so it takes about a second in the production environment.
Than original_image.analyse calls the ImageMagick’s identify command and cache its results.&lt;/p&gt;

&lt;p&gt;So everything is quite straightforward. But, we started to get R14 errors on heroku after the images#create requests.
We were under impression that some huge memory leak eats up all the memory, but it turned out that it was not garbage collected memory bloat that happens right after the identify command returns.&lt;/p&gt;

&lt;p&gt;It looks like ImageMagick’s identify tries to get as much memory as possible with no particular reason from my perspective. So we had to fight these bloats in a few different ways.&lt;/p&gt;

&lt;p&gt;First is to run garbage collection. Check out &lt;a href=&quot;https://github.com/tmm1/gctools&quot;&gt;gctools&lt;/a&gt;, the only thing we had to do is to add these lines to config.ru&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'gctools/oobgc'&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;defined?&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Unicorn&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;HttpRequest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;GC&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;OOB&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;UnicornMiddleware&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;It works with unicorn running on ruby 2.1. Learn &lt;a href=&quot;http://tmm1.net/ruby21-oobgc/&quot;&gt;more&lt;/a&gt; about it in the Aman Gupta’s blog.&lt;/p&gt;

&lt;p&gt;And everything got back to normal, no R14 any more because the memory was cleaned up properly after each request.&lt;/p&gt;

&lt;p&gt;But, why should we allow identify to take so much memory at the first place? And here comes the solution: passing limits to the identify command.&lt;/p&gt;

&lt;p&gt;Another line of code added to initializers/dragonfly.rb&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;no&quot;&gt;Dragonfly&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;configure&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;plugin&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:imagemagick&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;identify_command: &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;identify -limit memory 0 -limit map 0&quot;&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;#...&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;So, the ImageMagick doesn’t eat so much memory any more, and even if it does the bloat will be garbage collected after the request.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <id>tag:blog.astrails.com,2014-07-20:a-few-things-worth-mentioning</id>
    <link rel="alternate" type="text/html" href="http://astrails.com/blog/2014/07/20/a-few-things-worth-mentioning"/>
    <author>
      <name>boris</name>
    </author>
    <published>2014-07-20T21:53:50+00:00</published>
    <updated>2014-07-20T21:53:50+00:00</updated>
    
    <category term="business"/>
    <category term="development"/>
    <category term="design"/>
    <title>A few things worth mentioning</title>
    <summary type="html">&lt;p&gt;I’m going to start a series of short digest blog posts that will cover a few
things worth mentioning. I sumble upon a lot of things reading different
sources, here I will share the most interesting ones. Well, at least most
intersting for me.&lt;/p&gt;


    </summary>
    <content type="html">&lt;p&gt;I’m going to start a series of short digest blog posts that will cover a few
things worth mentioning. I sumble upon a lot of things reading different
sources, here I will share the most interesting ones. Well, at least most
intersting for me.
READMORE&lt;/p&gt;

&lt;p&gt;Here we go.&lt;/p&gt;

&lt;h3&gt;Tools.&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;http://breach.cc/&quot;&gt;http://breach.cc/&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;A browser for the HTML5 era Entirely written in Javascript. Free. Modular. Hackable.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The browser is really nice especially its minimalistic design. Chrome Development Console
works as usual, so it can really be an alternative for Incognito Tabs/Windows when
debugging web applications that require to work on flows involving different
logged in users.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/google/ios-webkit-debug-proxy/&quot;&gt;https://github.com/google/ios-webkit-debug-proxy/&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;The ios_webkit_debug_proxy allows developers to inspect MobileSafari and UIWebViews on real and simulated iOS devices via the DevTools UI and WebKit Remote Debugging Protocol.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I’m really an Apple fun, but Google’s DevTools rock.&lt;/p&gt;

&lt;p&gt;[http://macdown.uranusjr.com/] (http://macdown.uranusjr.com/)&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;MacDown. The open source Markdown editor for OS X.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I used MarkdownPro for a while, but this one is really cool and free.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://iterm2.com/&quot;&gt;http://iterm2.com/&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;iTerm2 is a replacement for Terminal and the successor to iTerm.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;2.0 is released.&lt;/p&gt;

&lt;h3&gt;Security.&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;http://words.zemn.me/csp&quot;&gt;http://words.zemn.me/csp&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Detecting login state for almost any website on the internet&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I’m not sure if it worths it to re-implement Location-based redirects in all
the projects I participated but big guys probably have to consider this.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://minilock.io/&quot;&gt;http://minilock.io/&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;File encryption software that does more with less.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In short, users have only remember the passphrase, keys pair will be generated
automatically based on the passphrase.&lt;/p&gt;

&lt;h3&gt;Development.&lt;/h3&gt;

&lt;p&gt;Where were a lot of buz about 2 charting libraries recently: &lt;a href=&quot;http://fastly.github.io/epoch/&quot;&gt;http://fastly.github.io/epoch/&lt;/a&gt; and &lt;a href=&quot;http://www.chartjs.org/&quot;&gt;http://www.chartjs.org/&lt;/a&gt;. Both are cool, I’m looking forward to testing both of them in a next project that will require charting.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://component.kitchen/&quot;&gt;http://component.kitchen/&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Component Kitchen - Great ingredients for your web apps&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Tons of useful code, all searchable.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://customelements.io/&quot;&gt;http://customelements.io/&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Custom Elements  - a web components gallery for modern web apps&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;More or less the same.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://www.polymer-project.org/&quot;&gt;http://www.polymer-project.org/&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Welcome to the future - Web Components usher in a new era of web development based on encapsulated and interoperable custom elements that extend HTML itself.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Most exciting thing for front end development ever happened since Backbone.js.
I’m trying to use it in the mobile verion of
&lt;a href=&quot;http://isratracker.com&quot;&gt;http://isratracker.com&lt;/a&gt; which will comes out shortly.&lt;/p&gt;

&lt;h3&gt;Design.&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;http://www.google.com/get/noto/&quot;&gt;http://www.google.com/get/noto/&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Google Noto Fonts - Beautiful and free fonts for all languages&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Beautiful indeed, looks even better then Roboto.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://designairs.com/inside-brand-evolution/&quot;&gt;http://designairs.com/inside-brand-evolution/&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Inside our Brand Evolution&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;An interesting reading about airbnb rebranding.&lt;/p&gt;

&lt;h3&gt;Reading&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;http://venturebeat.com/2014/07/18/how-yo-became-one-of-the-most-viral-apps-of-all-time-step-by-step/&quot;&gt;http://venturebeat.com/2014/07/18/how-yo-became-one-of-the-most-viral-apps-of-all-time-step-by-step/&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;How Yo became one of the most viral apps of all time — step by step&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href=&quot;http://www.logolounge.com/article/2013logotrends/&quot;&gt;http://www.logolounge.com/article/2013logotrends/&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;2013 Logo Trends&lt;/p&gt;
&lt;/blockquote&gt;
</content>
  </entry>
  <entry>
    <id>tag:blog.astrails.com,2013-08-12:writing-markdown-with-style-in-vim</id>
    <link rel="alternate" type="text/html" href="http://astrails.com/blog/2013/08/12/writing-markdown-with-style-in-vim"/>
    <author>
      <name>vitaly</name>
    </author>
    <published>2013-08-12T08:03:25+00:00</published>
    <updated>2013-08-12T08:03:25+00:00</updated>
    
    <category term="vim"/>
    <title>Writing Markdown With Style in Vim</title>
    <summary type="html">&lt;p&gt;Boris recently purchased &lt;a href=&quot;http://www.iawriter.com/mac/&quot;&gt;iA Writer&lt;/a&gt; to edit
&lt;a href=&quot;http://daringfireball.net/projects/markdown/&quot;&gt;Markdown&lt;/a&gt;, which is our primary
format used internally for readmes, proposal documents, contracts etc.&lt;/p&gt;

&lt;p&gt;iA Writer looks very nice indeed. The typography is beautiful, and I especially
like how it outdents headings and lists:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://assets.astrails.com/blog/assets/2013/08/08/ai-writer-formatting-example.png&quot; alt=&quot;Ai Writer Formatting Example&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Still, I can’t help but find it impossible to do any serious text editing
without the full Vim power by my side.&lt;/p&gt;


    </summary>
    <content type="html">&lt;p&gt;Boris recently purchased &lt;a href=&quot;http://www.iawriter.com/mac/&quot;&gt;iA Writer&lt;/a&gt; to edit
&lt;a href=&quot;http://daringfireball.net/projects/markdown/&quot;&gt;Markdown&lt;/a&gt;, which is our primary
format used internally for readmes, proposal documents, contracts etc.&lt;/p&gt;

&lt;p&gt;iA Writer looks very nice indeed. The typography is beautiful, and I especially
like how it outdents headings and lists:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://assets.astrails.com/blog/assets/2013/08/08/ai-writer-formatting-example.png&quot; alt=&quot;Ai Writer Formatting Example&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Still, I can’t help but find it impossible to do any serious text editing
without the full Vim power by my side.
READMORE&lt;/p&gt;

&lt;p&gt;So I decided to try to at least approximate the experience of using iA
Writer with Vim.&lt;/p&gt;

&lt;p&gt;It turned out you can make the text look pretty decent by using a good
font and bigger linespace. The “outdent” is out of the question of course
(if anyone knows how to accomplish it I’d be very glad to hear that), but
the rest is actually pretty good, with some extra formatting for lists, links
etc.&lt;/p&gt;

&lt;p&gt;I don’t like the ‘focus mode’ in iA Writer, so I didn’t try to replicate any of
this, and not sure if its possible. Instead I use a different background color
for the current line. Here is the result:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://assets.astrails.com/blog/assets/2013/08/08/vim-formatting-example.png&quot; alt=&quot;Vim Formatting Example&quot; /&gt;&lt;/p&gt;

&lt;p&gt;As you can see its not bad ;), and its Vim!&lt;/p&gt;

&lt;p&gt;I’ve put the config into &lt;code class=&quot;highlighter-rouge&quot;&gt;~/.vim/writer.vim&lt;/code&gt; file that I can ‘:source
~/.vim/writer.vim’ when I’m working with Markdown:&lt;/p&gt;

&lt;div class=&quot;language-vim highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;background&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;light&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;nonu&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;laststatus&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;colorscheme&lt;/span&gt; default
&lt;span class=&quot;k&quot;&gt;hi&lt;/span&gt; FoldColumn guibg&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;white
&lt;span class=&quot;k&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;foldcolumn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;12&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;linespace&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;8&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;guifont&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;Source\ Code\ Pro\ Light&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;h20
&lt;span class=&quot;k&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;tw&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;80&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;hi&lt;/span&gt; Normal guibg&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;gray95
&lt;span class=&quot;k&quot;&gt;hi&lt;/span&gt; NonText guifg&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;gray95
&lt;span class=&quot;k&quot;&gt;hi&lt;/span&gt; FoldColumn guibg&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;gray95
&lt;span class=&quot;k&quot;&gt;hi&lt;/span&gt; CursorLine guibg&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;gray90
&lt;span class=&quot;k&quot;&gt;hi&lt;/span&gt; Title &lt;span class=&quot;k&quot;&gt;gui&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;bold&lt;/span&gt; guifg&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;gray25
&lt;span class=&quot;k&quot;&gt;hi&lt;/span&gt; MarkdownHeadingDelimiter &lt;span class=&quot;k&quot;&gt;gui&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;bold&lt;/span&gt; guifg&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;gray25
&lt;span class=&quot;k&quot;&gt;hi&lt;/span&gt; htmlSpecialChar guifg&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;black
&lt;span class=&quot;k&quot;&gt;hi&lt;/span&gt; markdownBold &lt;span class=&quot;k&quot;&gt;gui&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;bold&lt;/span&gt; guifg&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;gray25
&lt;span class=&quot;k&quot;&gt;hi&lt;/span&gt; markdownItalic guifg&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;gray25 &lt;span class=&quot;k&quot;&gt;gui&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;underline&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;hi&lt;/span&gt; markdownUrl guifg&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;#2fb3a6&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;hi&lt;/span&gt; markdownAutomaticLink guifg&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;#2fb3a6&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;hi&lt;/span&gt; markdownLinkText guifg&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;#317849&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;hi&lt;/span&gt; markdownUrlTitle guifg&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;#317849&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;hi&lt;/span&gt; markdownBlockquote guifg&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;#317849&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;gui&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;bold&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;hi&lt;/span&gt; markdownId guifg&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;#2fb3a6&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;hi&lt;/span&gt; markdownIdDeclaration guifg&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;#317849&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;gui&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;bold&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;hi&lt;/span&gt; markdownListMarker guifg&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;#317849&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;highlight&lt;/span&gt; Cursor guibg&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;#15abdd&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
</content>
  </entry>
</feed>
