Jun 22 2017

Преместих блога в Google Cloud

Category: Dev,WebLucho @ 17:45

Преди 8 години, когато създадох този блог, избрах сравнително най-евтиния и качествен споделен хостинг, който се предлага от българска фирма. Тогава цената беше около 40 лева на година, като от тогава всяка година тя расте. В днешно време фирмите, които предлагат хостинг в България изглеждат по-малко, но по-големи и вероятно с по-добро качество на услугата. Цената съответно варира, но най-скромният план на месец излиза по около 8-9 лева ($5), а за година около 100+ лева.

Това ме подтикна да разгледам други хостинг опции и също така cloud платформи, които предлагат виртуални машини. Оказва се, че най-минималната конфигурация, която може да се наеме от Google Cloud излиза около $5 на месец (прогнозна цена) и включва 20% от едно ядро с опцията да се използва цялото ядро в кратък интервал, 0.6 GB оперативна памет и твърд диск до 30GB. Цената е еквивалентна на споделения хостинг, но параметрите на услугата са много различни.

  1. Хостингът има набор от полезен софтуер с графичен интерфейс, който позволява по-лесното му управление. От друга страна виртуалната машина има шел и няма никакви ограничения в това какво може да се инсталира на нея, което понякога е сериозен минус на хостинг решенията.
  2. Софтуерът и хардуерът на хостинг решението се поддържа от фирмата, от която е нает, докато в cloud платформите инсталирането, конфигурацията и обновлението на софтуера е персонална отговорност.
  3. Фирмите, които предлагат споделен хостинг рядко уточняват какви системни ресурси разполага наетият при тях хостинг, за това е трудно да се направи сравнение с виртуалната машина със споделено процесорно време и 0.6GB RAM. Ако приложенията, които ще вървят не консумират повече от ресурсите, които виртуалната машина предлага, тогава едва ли има видима разлика за крайния потребител в това отношение.
  4. Редовното създаването на backup на файловата система и/или базата данни е включена услуга в плана на споделения хостинг, докато при cloud платформите може да е отговорност на потребителя или да се таксува допълнително.

Моят блог и приложенията, които вървят на текущия ми хостинг не са популярни и заемат малко ресурси, което наклони везната в полза на наета виртуална машина в Google Cloud. Преместването отне около ден, като най-трудно беше инсталирането на WordPress и плъгините му, тъй като реших да направя нова инсталация, защото старата wordpress инсталация на хостинга беше компроментирана преди време. Като бонус към миграцитя реших да инсталирам и безплатен TLS сертификат чрез https://letsencrypt.org/, което май е платена опция при споделния хостинг.

Free Tier Google Cloud VM

Free Tier Google Cloud VM

Google Cloud предлага $300 безплатен кредит в рамиките на 12 месеца, за да може новите потребители да тестват платформата им. Това беше и сериозна причина да опитам техните услуги, като текущата конфигурация е споделено процесорно време на едно ядро (50%), 1.7GB RAM, 15GB SSD за прогнозна цена от $15 на месец. След изтичането на периода мога да мигрирам машината към по-скромния вариант, който излиза около $5 на месец. От март месец Google имат и нова “Free Tier” оферта, която позволява наем на най-ниския им клас виртуална машина вместо за $5 за 0!  Единственият недостатък е че виртуалната машина трябва да се намира в data center в САЩ, вместо в Европа и да използва твърд диск вместо SSD (иначе се заплаща). Тук има повече по темата: https://news.ycombinator.com/item?id=13832519

Възможно е след година да преместя инсталацията в нисък клас виртуална машина (безплатна), защото все пак този блог не е особено оживено място и може би ще се справи с минимални ресурси 😉


Apr 01 2013

Easter Rail 4 todo app

Category: Dev,HTML5,WebLucho @ 14:33

So, it is that time of the year when you have 4 free days, because it is Easter and at the same time Rails 4 and Ruby 2 got out recently and you have not touched Ruby and Rails in ages. As we all know, when the life throws at you new Ruby and new Rails you must make a lemonade or at least a hello world-ish todo app out of this (also it helps to refresh your lost rails-fu points).

The result of my efforts is on github and the application is demoed on heroku.

This time I was clever enough to write down all important steps and obstacles on my way, so I have a “lessons learned” section for future me (if future me is going to start a bigger project on Rails 4 any day).

I also had the chance to pick up on HTML5 Boilerplate, jQuery 2 and Giphy API, which just boost indefinitely the awesomeness of the todo app. The only bad thing was that Giphy’s API seems very undergroundish, or at least I could not find any official documentation about it, so I just followed examples from other github repos.

One last thing – heroku deployment is still a serious pain in the arse1!!12 I MEAN IT!! The only positive thing out of this is that I learned how to git rebase –interactive and squash 14 heroku-should-work-now commits in one – I leveled up in git.

nyan

 

Tags: , , ,


Jul 24 2011

Game of Life (javascript + html5’s canvas)

Category: Dev,HTML5,WebLucho @ 23:55

Тези дни отново ме загриза съвестта, че не работя по някакъв сайд-проект – мой собствен или open source и за това днес реших да почета и понапиша Game of Life.

Оказа се доста прост алгоритъм с доста интересна история, която и сами може да си прочетете 🙂

Демо може да видите тук: http://dailyffs.com/life/

Сорсът е тук: https://gist.github.com/1102964

Коментарът към сорса от страна на @skanev е тук: https://twitter.com/skanev/status/95213748092026880

Това, което искам да кажа в тази статия е, че колкото и да са бързи съвремените Javascript engine-и и колкото и разни светила и икони на браузър вендорите да се хвалят, че производителността скача многократно от версия до версия, това не значи че не може да забързате всичко още малко много. Цената на “забързването” е “угрозняване” и оптимизиране на кода. В моя конкретен случай – на една функция, която се вика 60000 пъти на преизчисление.

Въпросната фунцкия:


function getLiveNeighbours(id, data) {
  var x = id % canvas.width;
  var y = parseInt(id / canvas.width);

  var cnt = 0;
  for (var i = -1; i < 2; i++) {
    for (var j = -1; j < 2; j++) {
      if ((i != 0 || j != 0) &&
        !(x+i < 0 || x+i >= canvas.width || y+j < 0 || y+j >= canvas.height) &&
        data.data[4*((y+j)*canvas.width+(x+i))] != THE_BLACK) {
        cnt++;
      }
    }
  }
  return cnt;
}

Простата оптимизация на кода включва:

  1. Премахване на извикването на функцията (тялото на функцията се ползва директно) – спестява 60000 извиквания и времето за изпълнение на една итерация пада от 500ms на 270ms
  2. Заменяне на двата вложени цикъла проверяващи за броя на съседни клетки – от 270ms на 150ms
  3. Опростяване на пресмятанията (премахване на умножения) – от 150ms на 60ms
  4. Създаване на локални референции към често използваните данни (вместо постоянни извиквания от типа “obj.data” при изчисленията се създава и използва локална променлива) – от 60ms на 50ms
// (4)
var width = canvas.width*4;
var d = data.data;
var nd = newdata.data;
var cw = canvas.width;
var ch = canvas.height;
var base = 0;

for (var i = 0; i < d.length/4; i++) {
  var x = i % cw;
  var y = parseInt(i / cw);

  var cnt = 0;
  // (1), (2), (3)
  if (x > 0 && d[base-4] != THE_BLACK) cnt++;
  if (x < cw-1 && d[base+4] != THE_BLACK) cnt++;
  if (x > 0 && y > 0 && d[base-4-width] != THE_BLACK) cnt++;
  if (y > 0 && d[base-width] != THE_BLACK) cnt++;
  if (x < cw-1 && y > 0 && d[base+4-width] != THE_BLACK) cnt++;
  if (x > 0 && y < ch-1 && d[base-4+width] != THE_BLACK) cnt++;
  if (y < ch-1 && d[base+width] != THE_BLACK) cnt++;
  if (x < cw-1 && y < ch-1 && d[base+4+width] != THE_BLACK) cnt++;
  ...

В крайна сметка производителността скочи 10 пъти, макар логиката на кода да изглежда по-зле от преди. Не, че преди изглеждаше много красива, но все пак 😀

Разбира се има и още един доста по-умен начин за техническа оптимизация – Web Workers. Те са панацеята на всички проблеми, началото и края, давид и голиат, содом и гомор, ин и ян… за тях може да почетете тази статия – Mandelbrot + Web Workers

Забележка:

  • става дума за проста техническа оптимизация на кода, а не за подобрения на алгоритъма!
  • вероятно оптимизациите в javascript engine-ите не се фокусират върху случаи на извикване на функция 60 хиляди пъти… а би трябвало.

Tags: , , ,


Jul 23 2011

Прозрение

Category: Dev,WebLucho @ 15:17

Преди няколко дни започнах да пиша малко плъгинче (първия ми плъгин акшуъли) за Django, което да филтрира браузъри в зависимост от useragent-а им. Идеята ми беше филтрирането да става в зависимост от версията на браузъра… идея, която работеше преди 5 години. Останах си с тази идея до момента, в който видях няколко useragent-a от мобилни устройства и таблети. Накратко един с един нямат общо, но това което си остава при всички е версията на layout engine-a.

Това е хора. Забравете за IE X или Firefox Y и  т.н., това което ще направи сайта ви да работи на десктоп, телефон и таблет е версията на layout engine-a в комбинация с данните от тези таблички: http://en.wikipedia.org/wiki/Comparison_of_layout_engines_%28Cascading_Style_Sheets%29 и http://caniuse.com/

 

 


Jul 14 2011

Upload на blob като файл чрез AJAX

Category: Dev,WebLucho @ 10:10

Заглавието и на мен не ми говори нищо, за това ще се опитам да обясня с прости думи казуса.

Наскоро забелязах, че при изпращането на голям скрийншот в http://screenshoot.me се случват някакви неприятни неща. По-точно грешка 413 Request entity too large. Оказа се, че хостингът ми не позволява изпращане на POST заявки с параметри по-големи от 1-2мб. За сметка на това пък позволява качване на файлове до 20мб. До тук единственото нещо, което ме притесняваше е дали може да “симулирам” изпращане на файл чрез AJAX. Оказа се че може. FUCK YEAH!

Всъщност може да си префасонирате цялата заявка както ви скимне, което е много готино и същевремено много жалко, защото десетките хиляди фронт-енд дивелъпъри, ползващи jQuery и нямащи понятие от javascript никога няма да узнаят за този факт.

Вероятно бъркам, просто се опитвам да си обясня защо на всяко интервю винаги питат “а ти с jQuery знаеш ли как да работиш” все едно манюъла е 500 страници и ти трябва висше :).

Та реших да разширя леката библиотечка (“парче код” е правилната дума), която ползвам за AJAX обаждания и съответно резултата е тук – https://github.com/lucho870601/ajax-blob-upload

Накратко:

jx.generateBoundary = function(fieldsData) { // Функция, която генерира уникален разделител валиден за всеки фрагмент
  var boundary = parseInt(Math.random()*Math.pow(10, 16)).toString(36) + '' + parseInt(Math.random()*Math.pow(10, 16)).toString(36);
  for (var i = 0; i < fieldsData.length; i++) {
    if (fieldsData[i].indexOf(boundary) > -1) {
      // generate new boundary and check all fields again
      boundary = parseInt(Math.random()*Math.pow(10, 16)).toString(36) + '' + parseInt(Math.random()*Math.pow(10, 16)).toString(36);
      i = 0;
    }
  }
  return boundary;
};

jx.loadFile = function(url, fileData, fileName, callback, opt) {
  var http = this.init(); //The XMLHttpRequest object is recreated at every call - to defeat Cache problem in IE
  if(!http||!url) return;
  var parts = url.split('?');
  var url = parts[0];
  var parameters = parts[1] ? parts[1].split('&') : [];

  var fieldsData = [fileData];
  for (var i = 0; i < parameters.length; i++) {
    fieldsData.push(parameter[i][1]);
  }

  var boundary = this.generateBoundary(fieldsData);
  var body = '';
  for (var i = 0; i < parameters.length; i++) {
    // строим фрагментите за данни
    var p = parameters[i].split('=');
    body += "--" + boundary + "\r\n\
Content-Disposition: form-data; name='"+p[0]+"'\r\n\
\r\n\
"+(p[1] || '')+"\r\n";
  }

  // фрагмента за псевдо-файла
  body += "--" + boundary + "\r\n\
Content-Disposition: form-data; name='" + fileName + "'; filename='" + fileName + "'\r\n\
Content-Type: application/octet-stream\r\n\
\r\n\
"+ fileData + "\r\n\
--" + boundary + "--\r\n";

  http.open("POST", url, true);
  http.setRequestHeader("Content-Type", "multipart/form-data; boundary="+boundary);
  http.setRequestHeader("Content-Length", body.length);
  http.setRequestHeader("Connection", "close");
  ...
  http.send(body);
};

… и получавате данните си като файл накрая.

Кофтито в цялата история е, че не мога да убедя браузъра ми да не слага “charset” и вероятно заради това blob-а пристига в съвсем друг вид. За това пък решението е доста лесно – кодиране на бинарните данни в base64. Неприятно е, че request-а ще набъбне с 1/3 повече и ще трябва да отворите и decode-нете файла сами. На теория декодирането на файла трябва да стане автоматично с Content-Transfer-Encoding директива, но на практика не стана 😀

Удачно е да ползвате този подход не само при гореописания проблем, но и винаги, когато пращате индустриални количества бинарни данни, защото получаването на файл е по-бързо и ангажира по-малко ресурси отколкото получаването на данните като параметър.  Поне така ми се струва 😛

П.П. Преди да имплементирам алтернативното решение се помъчих да увелича лимита на размера на POST заявките с конфигуриране на .htaccess и ini_set на разни магически PHP параметри, но непотръгна.

Tags: , ,


Jun 13 2011

Mandelbrot + Web Workers

Category: Dev,Firefox,HTML5,WebLucho @ 22:28

Обичам фрактална графика и поради липса на по-смислено занимание тези дни, реших да напиша визуализатор за Mandelbrot. Имплементацията ползва готините Web Workers, за да се справи с тоновете сметки и Canvas за да изобрази резултатът на екрана.

48 web worker-a се борят да запълнят 800х600 пиксела пространство и да си призная се справят по-добре от очакваното… е, все още си е бавно, но е 48 пъти по-добре отколкото без възможност за паралелно изпълнение на алгоритъма :D.

Резултатът може да видите тук – http://dailyffs.com/mandelbrot/

А кодът е достъпен тук – https://gist.github.com/1023445

Забележка: работи само с Firefox, защото другите браузъри или нямат web workers или не поддържат предаването на по-сложни обекти от/към worker-ите.

Tags: , , ,


May 17 2011

jslinux

Category: Dev,WebLucho @ 16:56

How cool is that…

Не съм сигурен как точно работи това, но очевидно javascript енджините вече са ненормално бързи, за да е възможно емиулирането на операционна система в браузър. Ако още не вярвате на очите си, най-добре го разгледайте сами – http://bellard.org/jslinux/

Let the time of browser-based VMs begin!

Tags: , ,


Next Page »