<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Механический мир</title>
	<atom:link href="http://kuroikaze85.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://kuroikaze85.wordpress.com</link>
	<description>Прибежище техножреца</description>
	<lastBuildDate>Fri, 27 Jan 2012 07:40:02 +0000</lastBuildDate>
	<language>ru</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='kuroikaze85.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://1.gravatar.com/blavatar/b6882b384c701fa54a4711c58ed9db0b?s=96&#038;d=http%3A%2F%2Fs2.wp.com%2Fi%2Fbuttonw-com.png</url>
		<title>Механический мир</title>
		<link>http://kuroikaze85.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://kuroikaze85.wordpress.com/osd.xml" title="Механический мир" />
	<atom:link rel='hub' href='http://kuroikaze85.wordpress.com/?pushpress=hub'/>
		<item>
		<title>AI, Minecraft и Node.js</title>
		<link>http://kuroikaze85.wordpress.com/2011/10/14/ai-minecraft-and-node-js/</link>
		<comments>http://kuroikaze85.wordpress.com/2011/10/14/ai-minecraft-and-node-js/#comments</comments>
		<pubDate>Fri, 14 Oct 2011 12:22:36 +0000</pubDate>
		<dc:creator>kuroikaze85</dc:creator>
				<category><![CDATA[Дневник программиста]]></category>
		<category><![CDATA[blackstone]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[minecraft]]></category>
		<category><![CDATA[node.js]]></category>
		<category><![CDATA[эксперименты]]></category>

		<guid isPermaLink="false">http://kuroikaze85.wordpress.com/?p=1457</guid>
		<description><![CDATA[Пару месяцев назад я записался на онлайн-курс Artificial Intellingence от Stanford University. И пока курс не начался (он начался только в понедельник 10 октября) пришла ко мне мысль сделать какую нибудь &#171;песочницу&#187; для тестирования разных алгоритмов, которые будут встречаться в курсе. Захотелось сделать такую песочницу из Minecraft. Вначале я думал о том чтобы просто модифицировать [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=kuroikaze85.wordpress.com&amp;blog=3649962&amp;post=1457&amp;subd=kuroikaze85&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><a href="https://plus.google.com/113094886364217274430/posts"><img src="https://lh5.googleusercontent.com/-raNL5HGR138/Tpd891r-HoI/AAAAAAAAEjo/8iTJ3WgYUt0/w402/2011-10-14_00.31.27.png" title="Первый моб на сервере" /></a></p>
<p>Пару месяцев назад я записался на онлайн-курс <a href="http://ai-class.com">Artificial Intellingence</a> от Stanford University. И пока курс не начался (он начался только в понедельник 10 октября) пришла ко мне мысль сделать какую нибудь &laquo;песочницу&raquo; для тестирования разных алгоритмов, которые будут встречаться в курсе. Захотелось сделать такую песочницу из Minecraft.</p>
<p>Вначале я думал о том чтобы просто модифицировать клиент или написать к нему плагин. Но т.к. при модификации пришлось бы работать с декомпилированным (плохо читаемым) Java-кодом, а система плагинов пока оставляет желать лучшего, я переключил своё внимание на сервер. Тут дела были несколько лучше. Для Minecraft есть несколько серверов с открытым исходным кодом на разных языках &mdash; C, Java, Python, .NET и т.д. Покопавшись в них, а также покопавшись в <a href="https://github.com/welterde/nodecraft">nodecraft</a> &mdash; заброшенной попытке написать minecraft-сервер на JavaScript, я решил все таки попробовать написать сервер самостоятельно, благо опыт работы с двоичными протоколами после разработки <a href="http://github.com/kurokikaze/limestone">limestone</a> у меня есть, да и во внутренности Minecraft я уже немного <a href="/2010/11/19/minecraft-python-cartograph/">забирался</a> (правда с Питоном). Протокол Minecraft описан (пусть даже немного неточно) в <a href="http://mc.kev009.com/Main_Page">Minecraft Coalition wiki</a>.</p>
<p>За первые пару дней я разобрался с последовательностью авторизации клиента и перешёл непосредственно к логину. Для логина сервер должен выслать клиенту местность вокруг места появления и всякие стартовые параметры типа времени сервера, содержимого инвентаря, точки респауна в случае если игрок погибнет и т.д. В IRC на канале #mcdevs меня сразу предупредили что отправка чанков клиенту это довольно сложная часть разработки и многие авторы серверов срезаются именно здесь. В результате двухдневных попыток подбора библиотеки сжатия и экспериментов с порядком пакетов отправить местность всё таки получилось. На следующий день после этого я прикрутил отправку keepalive-пакетов (без этого время пребывания на сервере ограничивалось одной минутой) и добавил респаун мобов и их движение. Теперь осталось только добавить определение столкновений, чтобы делать лабиринты, и можно приступать к заданиям второй главы курса &mdash; алгоритмам поиска пути.</p>
<p>Когда доделаю сервер будет видимо отдельный большой пост о протоколе Minecraft, написании сервера и насколько он на самом деле подходит для тестирования AI-алгоритмов. Пока мои наработки можно найти на Github. Сервер я назвал <a href="http://github.com/kurokikaze/blackstone">blackstone</a> (на #mcdevs предлагали node-minecraft, но по моему это скорее название для какой нибудь библиотеки утилит).</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/kuroikaze85.wordpress.com/1457/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/kuroikaze85.wordpress.com/1457/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/kuroikaze85.wordpress.com/1457/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/kuroikaze85.wordpress.com/1457/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/kuroikaze85.wordpress.com/1457/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/kuroikaze85.wordpress.com/1457/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/kuroikaze85.wordpress.com/1457/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/kuroikaze85.wordpress.com/1457/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/kuroikaze85.wordpress.com/1457/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/kuroikaze85.wordpress.com/1457/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/kuroikaze85.wordpress.com/1457/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/kuroikaze85.wordpress.com/1457/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/kuroikaze85.wordpress.com/1457/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/kuroikaze85.wordpress.com/1457/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=kuroikaze85.wordpress.com&amp;blog=3649962&amp;post=1457&amp;subd=kuroikaze85&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://kuroikaze85.wordpress.com/2011/10/14/ai-minecraft-and-node-js/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/6e18f1f7becbfe66248caa034417b759?s=96&#38;d=&#38;r=X" medium="image">
			<media:title type="html">kuroikaze85</media:title>
		</media:content>

		<media:content url="https://lh5.googleusercontent.com/-raNL5HGR138/Tpd891r-HoI/AAAAAAAAEjo/8iTJ3WgYUt0/w402/2011-10-14_00.31.27.png" medium="image">
			<media:title type="html">Первый моб на сервере</media:title>
		</media:content>
	</item>
		<item>
		<title>Яндекс.Метрика</title>
		<link>http://kuroikaze85.wordpress.com/2011/07/26/yandex-metrika/</link>
		<comments>http://kuroikaze85.wordpress.com/2011/07/26/yandex-metrika/#comments</comments>
		<pubDate>Tue, 26 Jul 2011 13:55:40 +0000</pubDate>
		<dc:creator>kuroikaze85</dc:creator>
				<category><![CDATA[Дневник программиста]]></category>
		<category><![CDATA[Заметки]]></category>

		<guid isPermaLink="false">http://kuroikaze85.wordpress.com/?p=1451</guid>
		<description><![CDATA[Последнее время с интересом слежу за развитием истории с проиндексированными смс, заказами (а теперь ещё и билетами). На Хабре (да и в Интернете вообще, по моему) все горой стоят за Яндекс &#8212; дескать, кто не закрыл нужные страницы с помощью robots.txt, тот сам себе злобный Буратино. Я не совсем согласен с такой точкой зрения. Как [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=kuroikaze85.wordpress.com&amp;blog=3649962&amp;post=1451&amp;subd=kuroikaze85&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Последнее время с интересом слежу за развитием истории с проиндексированными смс, заказами (а теперь ещё и билетами). На Хабре (да и в Интернете вообще, по моему) все горой стоят за Яндекс &mdash; дескать, кто не закрыл нужные страницы с помощью <tt>robots.txt</tt>, тот сам себе злобный Буратино. Я не совсем согласен с такой точкой зрения. Как пользователь Яндекс.Метрики лично я пропустил момент когда она начала по тихому сдавать страницы в очередь краулера (и, соответственно, в индекс). Я использую кое где Метрику для статистики, и для меня такое открытие было неприятной неожиданностью. Причём я сейчас проверил в <a href="http://metrika.yandex.ru/news/">новостях метрики</a> &mdash; о таком нововведении там ни слова. Хотя мне скрывать какие то страницы смысла не имеет, подобное изменение всё равно вызывает вопросы. Имхо, раз уж метрика привязывается к почтовому аккаунту, могли бы и разослать предупреждение.</p>
<p>Впрочем, это не означает что владельцы сайтов тут совсем ни при чём. При защите пользовательских данных подход <a href="http://en.wikipedia.org/wiki/Security_through_obscurity">security through obscurity</a> ни к чему хорошему привести не может. Особенно если данные действительно личные (номера телефонов, адреса + состав заказа, данные о поездке), лучше защищать их явно, чем просто надеяться на то что никто и никогда этих страниц не увидит. И неожиданно изменившиеся правила игры не обернулись бы такими конфузами.</p>
<p>В общем, этот случай &mdash; хороший повод задуматься о безопасности пользовательских данных в своих проектах, не полагаясь на поведение поисковиков &laquo;по умолчанию&raquo;. Обновить robots.txt, поставить авторизацию на страницах, которые содержат личные данные.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/kuroikaze85.wordpress.com/1451/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/kuroikaze85.wordpress.com/1451/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/kuroikaze85.wordpress.com/1451/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/kuroikaze85.wordpress.com/1451/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/kuroikaze85.wordpress.com/1451/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/kuroikaze85.wordpress.com/1451/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/kuroikaze85.wordpress.com/1451/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/kuroikaze85.wordpress.com/1451/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/kuroikaze85.wordpress.com/1451/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/kuroikaze85.wordpress.com/1451/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/kuroikaze85.wordpress.com/1451/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/kuroikaze85.wordpress.com/1451/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/kuroikaze85.wordpress.com/1451/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/kuroikaze85.wordpress.com/1451/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=kuroikaze85.wordpress.com&amp;blog=3649962&amp;post=1451&amp;subd=kuroikaze85&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://kuroikaze85.wordpress.com/2011/07/26/yandex-metrika/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/6e18f1f7becbfe66248caa034417b759?s=96&#38;d=&#38;r=X" medium="image">
			<media:title type="html">kuroikaze85</media:title>
		</media:content>
	</item>
		<item>
		<title>Kue — очереди с приоритетами на основе Redis</title>
		<link>http://kuroikaze85.wordpress.com/2011/07/05/kue/</link>
		<comments>http://kuroikaze85.wordpress.com/2011/07/05/kue/#comments</comments>
		<pubDate>Tue, 05 Jul 2011 20:20:43 +0000</pubDate>
		<dc:creator>kuroikaze85</dc:creator>
				<category><![CDATA[Дневник программиста]]></category>
		<category><![CDATA[Kue]]></category>
		<category><![CDATA[node.js]]></category>
		<category><![CDATA[Redis]]></category>

		<guid isPermaLink="false">http://kuroikaze85.wordpress.com/?p=1441</guid>
		<description><![CDATA[Если в Вашем проекте необходимо выполнять какие то задачи в фоновом режиме, будь то отправка почты или перекодирование видео, Вам следует присмотреться к Kue &#8212; инструменту для управления очередями задач с поддержкой приоритетов, метаданных и удобным веб-интерфейсом. Установка Для работы Kue требуется Redis версии не меньше чем 2 (с поддержкой команды WATCH). Я использовал 2.2.11, [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=kuroikaze85.wordpress.com&amp;blog=3649962&amp;post=1441&amp;subd=kuroikaze85&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Если в Вашем проекте необходимо выполнять какие то задачи в фоновом режиме, будь то отправка почты или перекодирование видео, Вам следует присмотреться к <a href="http://learnboost.github.com/kue/">Kue</a> &mdash; инструменту для управления очередями задач с поддержкой приоритетов, метаданных и удобным веб-интерфейсом.</p>
<p><span id="more-1441"></span></p>
<h2>Установка</h2>
<p>Для работы Kue требуется Redis версии не меньше чем 2 (с поддержкой команды <tt>WATCH</tt>). Я использовал 2.2.11, последнюю стабильную версию. Об установке и настройке Redis можно подробнее прочитать в <a href="/2010/08/10/node-js-redis/">другой статье</a>.</p>
<p>Сам Kue ставится из npm:</p>
<p><pre class="brush: bash;">
npm install kue
</pre></p>
<p>Ничего настраивать после установки не нужно &mdash; Kue сам подключится к Redis по стандартному порту. Если Redis у Вас настроен на нестандартный порт, нужные параметры можно передать при подключении модуля в коде.</p>
<h2>Использование</h2>
<p>Попробуем сразу создать задачу:</p>
<p><pre class="brush: jscript;">
var kue = require('kue'),
    jobs = kue.createQueue();

jobs.create('email', {
    title: 'welcome email for tj'
  , to: 'tj@learnboost.com'
  , template: 'welcome-email'
}).save();
</pre></p>
<p>Здесь <tt>"email"</tt> это тип задачи, объект содержит метаданные, которые будут доступны при выполнении. Свойство <tt>title</tt> особое: оно будет использоваться в веб-интерфейсе как имя задачи. Если требуется указать приоритет задачи, перед <tt>save()</tt> в цепочку идёт <tt>.priority()</tt> с указанием приоритета.</p>
<p>Приоритет может быть задан либо числом (чем меньше, тем раньше задача попадёт в очередь), либо строкой. Строки служат указателями наиболее типичных приоритетов:</p>
<ul>
<li><tt>low</tt>: 10</li>
<li><tt>normal</tt>: 0</li>
<li><tt>medium</tt>: -5</li>
<li><tt>high</tt>: -10</li>
<li><tt>critical</tt>: -15</li>
</ul>
<p>Получить задачу для выполнения можно с помощью <tt>jobs.process</tt>:</p>
<p><pre class="brush: jscript;">
jobs.process('email', function(job, done) {
  console.log('Processing &quot;' + job.data.title + '&quot;');
  done();
});
</pre></p>
<p>При выполнении в обработчик передаётся объект задачи <tt>job</tt> (метаданные доступны в свойстве <tt>data</tt>) и callback <tt>done</tt> &mdash; если он будет вызван без передачи ошибки, задача будет отмечена как успешно выполненная.</p>
<p>Маленькие задачи, которые нет смысла выполнять поодиночке, можно обрабатывать по несколько штук параллельно. Для этого после типа задачи надо передать количество задач для одновременного выполнения. Например, чтобы отправить сразу 20 писем, можно использовать такой код:</p>
<p><pre class="brush: jscript;">
jobs.process('email', 20, function(job, done) {
  console.log('Processing &quot;' + job.data.title + '&quot;');
  done();
});
</pre></p>
<p>Если надо следить за выполнением отдельных задач, можно использовать индикаторы выполнения и индивидуальные логи. Чтобы отметить степень выполнения долгой задачи, используйте <tt>job.progress</tt>:</p>
<p><pre class="brush: jscript;">
job.progress(done, total);
</pre></p>
<p>Здесь <tt>total</tt> это общее количество шагов выполнения (или элементов для обработки), done &mdash; количество уже выполненных шагов. Если при выполнении что то пойдет не так, можно записать сообщение в лог задачи:</p>
<p><pre class="brush: jscript;">
job.log('Error rendering slide %d: %s, slide.id, render.err);
</pre></p>
<h2>Веб-интерфейс</h2>
<p>У Kue есть веб-интерфейс, представляющий собой приложение на основе Express. Чтобы его запустить надо вызвать <tt>kue.app.listen</tt> и передать ему порт:</p>
<p><pre class="brush: jscript;">
kue.app.listen(3003);
</pre></p>
<p>В веб-интерфейсе можно следить за выполнением задач.</p>
<p><img src="http://learnboost.github.com/kue/images/ui.png" title="Веб-интерфейс Kue"></p>
<p>Также можно просматривать метаданные и индивидуальные логи задач.</p>
<p><img src="http://learnboost.github.com/kue/images/details.png" title="Метаданные и статистика задач в Kue"><br />
<img src="http://learnboost.github.com/kue/images/log.png" title="Индивидуальные логи задач в Kue"></p>
<p>Kue показывает индикаторы степени выполнения той или иной задачи, задаваемые <tt>job.progress</tt>.</p>
<p><img src="http://learnboost.github.com/kue/images/progress.png" title="Индикаторы выполнения задач"></p>
<h2>Ссылки по теме</h2>
<ul>
<li><a href="http://learnboost.github.com/kue/">Официальный сайт Kue</a></li>
<li><a href="http://github.com/learnboost/kue">Репозиторий Kue на Github</a></li>
</ul>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/kuroikaze85.wordpress.com/1441/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/kuroikaze85.wordpress.com/1441/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/kuroikaze85.wordpress.com/1441/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/kuroikaze85.wordpress.com/1441/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/kuroikaze85.wordpress.com/1441/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/kuroikaze85.wordpress.com/1441/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/kuroikaze85.wordpress.com/1441/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/kuroikaze85.wordpress.com/1441/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/kuroikaze85.wordpress.com/1441/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/kuroikaze85.wordpress.com/1441/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/kuroikaze85.wordpress.com/1441/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/kuroikaze85.wordpress.com/1441/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/kuroikaze85.wordpress.com/1441/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/kuroikaze85.wordpress.com/1441/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=kuroikaze85.wordpress.com&amp;blog=3649962&amp;post=1441&amp;subd=kuroikaze85&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://kuroikaze85.wordpress.com/2011/07/05/kue/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/6e18f1f7becbfe66248caa034417b759?s=96&#38;d=&#38;r=X" medium="image">
			<media:title type="html">kuroikaze85</media:title>
		</media:content>

		<media:content url="http://learnboost.github.com/kue/images/ui.png" medium="image">
			<media:title type="html">Веб-интерфейс Kue</media:title>
		</media:content>

		<media:content url="http://learnboost.github.com/kue/images/details.png" medium="image">
			<media:title type="html">Метаданные и статистика задач в Kue</media:title>
		</media:content>

		<media:content url="http://learnboost.github.com/kue/images/log.png" medium="image">
			<media:title type="html">Индивидуальные логи задач в Kue</media:title>
		</media:content>

		<media:content url="http://learnboost.github.com/kue/images/progress.png" medium="image">
			<media:title type="html">Индикаторы выполнения задач</media:title>
		</media:content>
	</item>
		<item>
		<title>Случайная находка — dev-сервер Хабрахабра</title>
		<link>http://kuroikaze85.wordpress.com/2011/07/05/habrahabr-dev-server/</link>
		<comments>http://kuroikaze85.wordpress.com/2011/07/05/habrahabr-dev-server/#comments</comments>
		<pubDate>Tue, 05 Jul 2011 13:00:25 +0000</pubDate>
		<dc:creator>kuroikaze85</dc:creator>
				<category><![CDATA[Заметки]]></category>
		<category><![CDATA[Хабрахабр]]></category>

		<guid isPermaLink="false">http://kuroikaze85.wordpress.com/?p=1432</guid>
		<description><![CDATA[Сегодня совершенно случайно обнаружил один из development-серверов Хабрахабра. Так получилось что как раз сегодня прошло 3 года с моей регистрации на ресурсе. Узнал я об этом, зайдя с утра в почту и увидев письмо от Хабрахабра с темой &#171;Вам доступен значок &#8216;Старожил&#8217;&#171;. Точнее, таких писем было два. При более внимательном рассмотрении оказалось что во втором [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=kuroikaze85.wordpress.com&amp;blog=3649962&amp;post=1432&amp;subd=kuroikaze85&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Сегодня совершенно случайно обнаружил один из development-серверов <a href="http://habrahabr.ru">Хабрахабра</a>. Так получилось что как раз сегодня прошло 3 года с моей регистрации на ресурсе. Узнал я об этом, зайдя с утра в почту и увидев письмо от Хабрахабра с темой &laquo;<em>Вам доступен значок &#8216;Старожил&#8217;</em>&laquo;.</p>
<p>Точнее, таких писем было два.</p>
<p><span id="more-1432"></span></p>
<p>При более внимательном рассмотрении оказалось что во втором письме ссылки ведут не на основной сайт Хабра, а на другой домен (хотя в самом письме написано что отправлено оно от mailer@habrahabr.ru). Немного пошарившись по второму сайту, сделал вывод что это какая то dev или staging площадка для ремонта багов. Никакого нового функционала там нет, зато например с утра не открывались топики если я был залогинен (я смог зайти, да), в обед это уже починили, зато потом снова сломали. И в собственный либо чей нибудь другой хабрацентр зайти невозможно. Кстати, самой новой фичи Хабра (возможности подписаться на комментарии к топику/отписаться от них) я там тоже не увидел.</p>
<p>Судя по топикам и комментариям, база в проекте актуальна на 4 июня 2011, время последнего комментария 18:29. Соответственно, срок голосования за всё уже истёк, так что проверить систему патронов не получилось. Из исследовательских побуждений сделал комментарий к одному из топиков. Комментарий появился на dev-сайте, но не на основном.</p>
<p>Очевидно что база используется настоящая (иначе я не смог бы зайти со своим паролем, да и почта бы не пришла), и крон работает исправно. Ради эксперимента попробовал зайти под неправильным паролем/другим пользователем — не получается. Судя по всему, оба сайта по крону проверили мою дату регистрации, убедились что я зарегистрирован более 3-х лет назад и сижу без значка, и оба выслали мне по письму (автоматически сформированному со ссылками).</p>
<p>Что подводит меня к интересной мысли что и на нашем проекте может быть такая же засада. Мы тоже используем частичную живую базу, крон тоже работает и данные пользователям периодически рассылаются. Правда у нас все dev/stage сервера закрыты HTTP Auth, так что просто так туда не зайти. Но проверить на всякий случай надо.</p>
<p>Ради ещё одного эксперимента (да и просто из интереса) запостил этот топик на Dev-Хабр. Хотя при публикации топика мне выдало 500 ошибку, он тем не менее появился в &laquo;новых&raquo;. В пост вставил картинку для отслеживания посещаемости — нашёл фотографию по запросу dev server, залил на habrastorage и сократил URL через <a href="http://bit.ly">bit.ly</a>. В bit.ly есть простенькая статистика по переходам (в нашем случае — по просмотрам картинки). В результате топик пока не получил ни просмотров, ни оценок.</p>
<p>В конце концов отписал Чипу и Дейлу по этому поводу. Пришёл ответ, но dev-сайт так и не закрыли (поэтому домен из записи я убрал).</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/kuroikaze85.wordpress.com/1432/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/kuroikaze85.wordpress.com/1432/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/kuroikaze85.wordpress.com/1432/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/kuroikaze85.wordpress.com/1432/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/kuroikaze85.wordpress.com/1432/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/kuroikaze85.wordpress.com/1432/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/kuroikaze85.wordpress.com/1432/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/kuroikaze85.wordpress.com/1432/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/kuroikaze85.wordpress.com/1432/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/kuroikaze85.wordpress.com/1432/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/kuroikaze85.wordpress.com/1432/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/kuroikaze85.wordpress.com/1432/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/kuroikaze85.wordpress.com/1432/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/kuroikaze85.wordpress.com/1432/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=kuroikaze85.wordpress.com&amp;blog=3649962&amp;post=1432&amp;subd=kuroikaze85&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://kuroikaze85.wordpress.com/2011/07/05/habrahabr-dev-server/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/6e18f1f7becbfe66248caa034417b759?s=96&#38;d=&#38;r=X" medium="image">
			<media:title type="html">kuroikaze85</media:title>
		</media:content>
	</item>
		<item>
		<title>Операции с однородными потоками данных</title>
		<link>http://kuroikaze85.wordpress.com/2011/05/03/uniform-streams-operations/</link>
		<comments>http://kuroikaze85.wordpress.com/2011/05/03/uniform-streams-operations/#comments</comments>
		<pubDate>Tue, 03 May 2011 17:11:08 +0000</pubDate>
		<dc:creator>kuroikaze85</dc:creator>
				<category><![CDATA[Дневник программиста]]></category>
		<category><![CDATA[потоки]]></category>
		<category><![CDATA[node.js]]></category>
		<category><![CDATA[эксперименты]]></category>

		<guid isPermaLink="false">http://kuroikaze85.wordpress.com/?p=1422</guid>
		<description><![CDATA[Недавно задумал написать вспомогательный модуль для node.js, чтобы облегчить работу с потоками для чтения. Например, быстро собрать по кускам ответ от сервера и представить в виде одной строки или JSON. То, есть, чтобы вместо вот этого: &#8230;можно было писать как нибудь так: В результате получился модуль streamops (Stream Operations) в таком монадическом стиле а-ля jQuery. [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=kuroikaze85.wordpress.com&amp;blog=3649962&amp;post=1422&amp;subd=kuroikaze85&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Недавно задумал написать вспомогательный модуль для node.js, чтобы облегчить работу с потоками для чтения. Например, быстро собрать по кускам ответ от сервера и представить в виде одной строки или JSON.</p>
<p><span id="more-1422"></span></p>
<p>То, есть, чтобы вместо вот этого:</p>
<p><pre class="brush: jscript;">
var call = http.request(options, function(res) {
	var data = '';
	res.on('data', function(chunk) {
		data += chunk;
	});
	
	res.on('end', function(chunk) {
		data += chunk;
		// Сделать что нибудь с полным ответом сервера
	});
});
call.end();
</pre></p>
<p>&#8230;можно было писать как нибудь так:</p>
<p><pre class="brush: jscript;">
var call = http.request(options, function(res) {
	s(res).collect().on('data', function(data)
		// Сделать что нибудь с полным ответом сервера
	});
});
call.end();
</pre></p>
<p>В результате получился модуль <a href="https://github.com/kurokikaze/streamops">streamops</a> (Stream Operations) в таком монадическом стиле а-ля jQuery. Потихоньку модуль оброс (и продолжает обрастать) разными полезными функциями, например: разрезание потока по разделителю, фильтрация событий по регулярному выражению и т.д.</p>
<p><pre class="brush: jscript;">
var test = new events.EventEmitter();

// Преобразуем текст входящих событий в JSON, оставляем только поле test
// и отфильтровываем все значения которые не начинаются на &quot;a&quot;
sop.sop(test).json().only('test').filter(/a.+/).log();

test.emit('data', JSON.stringify({&quot;test&quot;: &quot;a1&quot;}));
test.emit('data', JSON.stringify({&quot;test&quot;: &quot;b1&quot;}));
test.emit('data', JSON.stringify({&quot;test&quot;: &quot;a2&quot;}));
test.emit('data', JSON.stringify({&quot;test&quot;: &quot;b2&quot;}));

test.emit('end');
</pre></p>
<p>В дальнейшем я хочу немного поэкспериментировать с представлением периодических соединений с сайтами как read-only потоков, чтобы можно было фильтровать результаты нескольких последовательных вызовов страницы (например, периодический опрос API). Также хочется посмотреть на потоковые JSON-парсеры.</p>
<p><b>P.S.:</b> нашёл похожий проект &mdash; <tt><a href="https://github.com/fjakobs/async.js">async.js</a></tt> от Fabian Jakobs</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/kuroikaze85.wordpress.com/1422/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/kuroikaze85.wordpress.com/1422/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/kuroikaze85.wordpress.com/1422/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/kuroikaze85.wordpress.com/1422/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/kuroikaze85.wordpress.com/1422/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/kuroikaze85.wordpress.com/1422/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/kuroikaze85.wordpress.com/1422/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/kuroikaze85.wordpress.com/1422/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/kuroikaze85.wordpress.com/1422/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/kuroikaze85.wordpress.com/1422/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/kuroikaze85.wordpress.com/1422/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/kuroikaze85.wordpress.com/1422/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/kuroikaze85.wordpress.com/1422/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/kuroikaze85.wordpress.com/1422/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=kuroikaze85.wordpress.com&amp;blog=3649962&amp;post=1422&amp;subd=kuroikaze85&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://kuroikaze85.wordpress.com/2011/05/03/uniform-streams-operations/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/6e18f1f7becbfe66248caa034417b759?s=96&#38;d=&#38;r=X" medium="image">
			<media:title type="html">kuroikaze85</media:title>
		</media:content>
	</item>
		<item>
		<title>Использование runit вместо Init и вывод логов в файл</title>
		<link>http://kuroikaze85.wordpress.com/2011/04/04/runit-nodejs/</link>
		<comments>http://kuroikaze85.wordpress.com/2011/04/04/runit-nodejs/#comments</comments>
		<pubDate>Mon, 04 Apr 2011 10:54:21 +0000</pubDate>
		<dc:creator>kuroikaze85</dc:creator>
				<category><![CDATA[Дневник программиста]]></category>
		<category><![CDATA[node.js]]></category>
		<category><![CDATA[управление сервером]]></category>

		<guid isPermaLink="false">http://kuroikaze85.wordpress.com/?p=1416</guid>
		<description><![CDATA[Я достаточно долгое время использовал связку Init+Monit для запуска скриптов node, но со временем стал натыкаться на минусы такой связки. Одна из самых серьёзных проблем &#8212; отсутствие возможности вывести лог в разные файлы в ранних версиях start-stop-daemon. Версия, поставляемая с Debian Lenny не поддерживает такой функционал, а сборка новой версии тянет за собой уйму непонятного [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=kuroikaze85.wordpress.com&amp;blog=3649962&amp;post=1416&amp;subd=kuroikaze85&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Я достаточно долгое время использовал связку Init+Monit для запуска скриптов node, но со временем стал натыкаться на минусы такой связки. Одна из самых серьёзных проблем &mdash; отсутствие возможности вывести лог в разные файлы в ранних версиях <tt>start-stop-daemon</tt>. Версия, поставляемая с Debian Lenny не поддерживает такой функционал, а сборка новой версии тянет за собой уйму непонятного барахла. В итоге, попробовав разные варианты, я остановился на runit как замене Init-скриптам.</p>
<p><span id="more-1416"></span></p>
<h2>Установка и настройка</h2>
<p>Для большинства систем runit ставится из стандартного менеджера пакетов (<tt>apt-get install runit</tt> для Debian). Если в Вашем менеджере нужного пакета нет, можно скачать исходники для сборки с <a href="http://smarden.org/runit/install.html" target="">официальной страницы</a>.</p>
<p>Каждому сервису в runit соответствует директория в <tt>/etc/sv</tt>. В этой директории создаём файл запуска <tt>run</tt>:</p>
<p><pre class="brush: bash;">
mkdir /etc/sv/testservice
vim /etc/sv/testservice/run
</pre></p>
<p>В файле <tt>run</tt> пишем строку для запуска нашего скрипта, с перенаправлениями ввода-вывода, <em>без</em> демонизации (<tt>&amp;</tt>), но с <tt>exec</tt>:</p>
<p><pre class="brush: bash;">
exec node /etc/mysite/server.js 1&gt;&gt;/var/log/mysite/output 2&gt;&gt;/var/log/mysite/error
</pre></p>
<p>Ставим этому файлу разрешение на выполнение:</p>
<p><pre class="brush: bash;">
chmod +x run
</pre></p>
<p>Теперь чтобы запустить сервис надо передать runit команду и имя директории внутри <tt>/etc/sv</tt>:</p>
<p><pre class="brush: bash;">
sv start testservice
</pre></p>
<p>Чтобы остановить сервис, вторым параметром передаётся <tt>stop</tt>, чтобы перезапустить — <tt>restart</tt>.</p>
<p>Чтобы проверить runit я использовал немного модифицированный &laquo;Hello World&raquo; с официального сайта:</p>
<p><pre class="brush: jscript;">
http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('Hello World\n');
  console.log('Log message #' + i);
  console.error('Err message #' + i);
  i++;
}).listen(8124, &quot;192.168.175.128&quot;);
console.log('Server running at http://127.0.0.1:8124/')
</pre></p>
<p><tt>console.log</tt> выводит строку в стандартный поток вывода (<tt>stdout</tt>), <tt>console.error</tt> выводит строку в <tt>stderr</tt>. Строки, переданные в <tt>console.log</tt> будут выводиться в <tt>/var/log/mysite/output</tt>, то что передано в <tt>console.error</tt> будет записано в <tt>/var/log/mysite/error</tt>.</p>
<p>(Кстати, если сделаете то же самое и увидите что с каждым обновлением в лог попадают сразу две строки с последовательными номерами, не спешите искать баг в коде. Скорее всего Ваш браузер запрашивает вместе со страницей файл <tt>favicon.ico</tt> для сайта.)</p>
<p>Чтобы прикрутить runit к monit&#8217;у, можно создать симлинк в директории /etc/init.d/ на /usr/bin/sv. При таком вызове runit будет запускать/останавливать сервис, соответствующий имени симлинка:</p>
<p><pre class="brush: bash;">
ln -s /usr/bin/sv /etc/init.d/testservice
</pre></p>
<p>Теперь при вызове <tt>/etc/init.d/testservice start</tt> Ваш скрипт будет запущен. Так проще будет перейти с Init на runit если Вы всё таки задумаете это сделать <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<h2>Ссылки по теме</h2>
<ul>
<li><a href="http://smarden.org/runit/" title="" target="_blank">Официальный сайт Runit</a></li>
<li><a href="http://habrahabr.ru/blogs/sysadm/83775/" title="" target="_blank">Руководство по установке и использованию runit (Хабрахабр)</a></li>
<li><a href="http://kuroikaze85.wordpress.com/2010/04/27/using-nodejs-with-init-and-monit/" title="" target="_blank">Использование node.js с Init + Monit</a></li>
</ul>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/kuroikaze85.wordpress.com/1416/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/kuroikaze85.wordpress.com/1416/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/kuroikaze85.wordpress.com/1416/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/kuroikaze85.wordpress.com/1416/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/kuroikaze85.wordpress.com/1416/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/kuroikaze85.wordpress.com/1416/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/kuroikaze85.wordpress.com/1416/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/kuroikaze85.wordpress.com/1416/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/kuroikaze85.wordpress.com/1416/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/kuroikaze85.wordpress.com/1416/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/kuroikaze85.wordpress.com/1416/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/kuroikaze85.wordpress.com/1416/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/kuroikaze85.wordpress.com/1416/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/kuroikaze85.wordpress.com/1416/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=kuroikaze85.wordpress.com&amp;blog=3649962&amp;post=1416&amp;subd=kuroikaze85&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://kuroikaze85.wordpress.com/2011/04/04/runit-nodejs/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/6e18f1f7becbfe66248caa034417b759?s=96&#38;d=&#38;r=X" medium="image">
			<media:title type="html">kuroikaze85</media:title>
		</media:content>
	</item>
		<item>
		<title>Mantis + GraphViz</title>
		<link>http://kuroikaze85.wordpress.com/2011/03/21/mantis-graphviz/</link>
		<comments>http://kuroikaze85.wordpress.com/2011/03/21/mantis-graphviz/#comments</comments>
		<pubDate>Mon, 21 Mar 2011 18:22:37 +0000</pubDate>
		<dc:creator>kuroikaze85</dc:creator>
				<category><![CDATA[Дневник программиста]]></category>
		<category><![CDATA[эксперименты]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://kuroikaze85.wordpress.com/?p=1399</guid>
		<description><![CDATA[После предыдущего эксперимента мне понравилось работать с GraphViz, к тому же я давно хотел понять как именно использовать его для отрисовки графов, поэтому я решил сделать небольшой скриптик с использованием dot. Получение данных Я решил найти API нашей системы багтрекинга Mantis чтобы взять оттуда список багов и построить граф зависимостей. Я помню что когда то [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=kuroikaze85.wordpress.com&amp;blog=3649962&amp;post=1399&amp;subd=kuroikaze85&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>После <a href="/2011/03/17/big-files-cachegrind/">предыдущего эксперимента</a> мне понравилось работать с GraphViz, к тому же я давно хотел понять как именно использовать его для отрисовки графов, поэтому я решил сделать небольшой скриптик с использованием <tt>dot</tt>.</p>
<p><span id="more-1399"></span></p>
<h2>Получение данных</h2>
<p>Я решил найти API нашей системы багтрекинга Mantis чтобы взять оттуда список багов и построить граф зависимостей. Я помню что когда то читал об этом API. Оказалось что Mantis предоставляет SOAP API для получения всей необходимой информации о багах (<a href="http://www.futureware.biz/mantisconnect/">MantisConnect</a>). Так как из Node работать с SOAP оказалось не очень удобно, я переключился на PHP. Я использовал класс <a href="http://sourceforge.net/projects/nusoap/">NuSOAP</a> чтобы не изобретать велосипед лишний раз. Обращение к Мантису с помощью NuSOAP делается примерно так:</p>
<p><pre class="brush: php;">
require_once('nusoap-0.9.5/lib/nusoap.php');
$WSDL_POINT = &quot;https://mantis.example.com/api/soap/mantisconnect.php&quot;;
$username = 'username';
$password = 'password';

$proxyhost = isset($_POST['proxyhost']) ? $_POST['proxyhost'] : '';
$proxyport = isset($_POST['proxyport']) ? $_POST['proxyport'] : '';
$proxyusername = isset($_POST['proxyusername']) ? $_POST['proxyusername'] : '';
$proxypassword = isset($_POST['proxypassword']) ? $_POST['proxypassword'] : '';
$useCURL = isset($_POST['usecurl']) ? $_POST['usecurl'] : '0';

$client = new nusoap_client($WSDL_POINT, false,
					$proxyhost, $proxyport, $proxyusername, $proxypassword);
</pre></p>
<p>Теперь можно вызывать методы. Я решил просто создать в Мантисе фильтр на нужные баги и получать его результаты:</p>
<p><pre class="brush: php;">
$params = array(
    'username' =&gt; $username,
    'password'         =&gt; $password,
    'project_id'         =&gt; 42, // Проект, который нас интересует (можно посмотреть в веб-интерейсе Mantis)
    'filter_id'          =&gt; 987, // ID фильтра, можно посмотреть на странице управления фильтрами
    'page_number'         =&gt; 1,
    'per_page'       =&gt; 400 // получить 400 записей
);
$result = $client-&gt;call('mc_filter_get_issues', $params,  'https://mantis.example.com:443/api/soap/mantisconnect.php', 'http://soap.amazon.com');
</pre></p>
<p>В <tt>$result</tt> окажется результат обращения к API &mdash; массив багов с соответствующими полями. Теперь надо перевести его в формат, подходящий для построения графика.</p>
<h2>Graphviz и DOT-файлы</h2>
<p>По примеру <a href="/2011/03/17/big-files-cachegrind/">cg2dot</a> я решил выводить данные в виде DOT-файла. <a href="http://en.wikipedia.org/wiki/DOT_language">Описание формата</a> можно найти в Wikipedia &mdash; он довольно простой. Я просто прошёл по массиву багов и вывел все описания в виде <tt>12345 [label="24430: example issue description"];</tt> и связи parent-child в виде <tt>12345 -&gt; 12346</tt>. К сожалению, я не нашёл способа одновременно рисовать направленные и ненаправленные ребра, потому для related to я использовал стрелки в обоих направлениях. Все строки записываются внутри конструкции <tt>digraph issues {</tt> / </tt>}</tt>. Я ещё добавил строку <tt>rankdir=LR</tt> чтобы узлы отрисовывались сверху вниз. По умолчанию dot отрисовывает их в строку, и с длинными описаниями багов получается довольно неудобная картина.</p>
<p>В результате у меня получился граф зависимостей багов. Я ещё немного дописал код чтобы баги разного приоритета выводились разными цветами (<tt>12345 [color="green"];</tt>). Получившийся код я запускаю прямо из командной строки:</p>
<p><pre class="brush: bash;">
C:\xampp\htdocs\issues&gt;php index.php | &quot;c:\Program Files\Graphviz2.24\bin\dot.exe&quot; -Tpng -o21-mar-11_19-41.png
</pre></p>
<p>В имя выходного файла я добавляю текущее время чтобы было удобно различать разные даты. В результате получается неплохое наглядное представление текущего положения дел в релизе. Я хочу запускать этот скрипт периодически чтобы потом можно было посмотреть прогресс по дням.</p>
<p><b>UPD:</b> испытал код на <a href="http://bay12games.com/dwarves/mantisbt/">мантисе для Dwarf Fortress</a>, получился <a href="http://zoom.it/pNiU">огромный граф</a>.</p>
<h2>Ссылки по теме</h2>
<ul>
<li><a href="http://www.futureware.biz/mantisconnect/">API MantisConnect</a></li>
<li><a href="http://en.wikipedia.org/wiki/DOT_language">Краткое описание формата DOT</a></li>
<li><a href="http://www.graphviz.org/content/documentation">Полное описание на сайте GraphViz</a></li>
<li><a href="https://gist.github.com/35722fd505f112facc01">Получившийся код</a></li>
</ul>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/kuroikaze85.wordpress.com/1399/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/kuroikaze85.wordpress.com/1399/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/kuroikaze85.wordpress.com/1399/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/kuroikaze85.wordpress.com/1399/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/kuroikaze85.wordpress.com/1399/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/kuroikaze85.wordpress.com/1399/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/kuroikaze85.wordpress.com/1399/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/kuroikaze85.wordpress.com/1399/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/kuroikaze85.wordpress.com/1399/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/kuroikaze85.wordpress.com/1399/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/kuroikaze85.wordpress.com/1399/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/kuroikaze85.wordpress.com/1399/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/kuroikaze85.wordpress.com/1399/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/kuroikaze85.wordpress.com/1399/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=kuroikaze85.wordpress.com&amp;blog=3649962&amp;post=1399&amp;subd=kuroikaze85&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://kuroikaze85.wordpress.com/2011/03/21/mantis-graphviz/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/6e18f1f7becbfe66248caa034417b759?s=96&#38;d=&#38;r=X" medium="image">
			<media:title type="html">kuroikaze85</media:title>
		</media:content>
	</item>
		<item>
		<title>Большие файлы cachegrind</title>
		<link>http://kuroikaze85.wordpress.com/2011/03/17/big-files-cachegrind/</link>
		<comments>http://kuroikaze85.wordpress.com/2011/03/17/big-files-cachegrind/#comments</comments>
		<pubDate>Thu, 17 Mar 2011 14:38:04 +0000</pubDate>
		<dc:creator>kuroikaze85</dc:creator>
				<category><![CDATA[Дневник программиста]]></category>
		<category><![CDATA[производительность]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[XDebug]]></category>

		<guid isPermaLink="false">http://kuroikaze85.wordpress.com/?p=1387</guid>
		<description><![CDATA[Сегодня пришлось столкнуться с необходимостью сделать профилирование для скрипта который исполнялся слишком долго. Для таких целей у меня стоит связка из XDebug + WinCacheGrind. XDebug отработал как положено, но файл cachegrind.out получился размером ~200 метров. WinCachegrind по каким то причинам каждый раз зависал, пытаясь его переварить (подозреваю что из за большого размера). В результате пришлось [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=kuroikaze85.wordpress.com&amp;blog=3649962&amp;post=1387&amp;subd=kuroikaze85&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Сегодня пришлось столкнуться с необходимостью сделать профилирование для скрипта который исполнялся слишком долго. Для таких целей у меня стоит связка из XDebug + WinCacheGrind. XDebug отработал как положено, но файл <tt>cachegrind.out</tt> получился размером ~200 метров. WinCachegrind по каким то причинам каждый раз зависал, пытаясь его переварить (подозреваю что из за большого размера). В результате пришлось пойти другим путём.</p>
<p>Проблема решилась с помощью <a href="http://code.google.com/p/xdebugtoolkit/">xdebugtoolkit</a> и <a href="http://www.graphviz.org/">Graphviz</a>. Graphviz и Python (необходимый для работы тулкита) у меня уже стояли. Оставалось скачать сам xdebugtoolkit. В него входит утилита <a href="http://code.google.com/p/xdebugtoolkit/wiki/cg2dot">cg2dot</a>, преобразующая cachegrind-файл в граф вызовов (с указанием какой вызов сколько времени занял). Потом по получившимся данным утилита dot из graphviz просто строит график в формате PNG, на котором неплохо видно где же застревает PHP. Сам вызов выглядит примерно так:</p>
<p><pre class="brush: bash;">
cg2dot.py &quot;D:\cachegrind\stage\cachegrind.out.16084&quot; | &quot;C:\Program Files\Graphviz2.24\bin\dot.exe&quot; -Tpng -ograph.png
</pre></p>
<p>Я ввел эту команду и ушёл на час гулять. В результате получился файл <tt><a href="http://i.imgur.com/8NG1p.png">graph.png</a></tt> по которому уже было понятно где и что работает медленно.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/kuroikaze85.wordpress.com/1387/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/kuroikaze85.wordpress.com/1387/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/kuroikaze85.wordpress.com/1387/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/kuroikaze85.wordpress.com/1387/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/kuroikaze85.wordpress.com/1387/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/kuroikaze85.wordpress.com/1387/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/kuroikaze85.wordpress.com/1387/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/kuroikaze85.wordpress.com/1387/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/kuroikaze85.wordpress.com/1387/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/kuroikaze85.wordpress.com/1387/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/kuroikaze85.wordpress.com/1387/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/kuroikaze85.wordpress.com/1387/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/kuroikaze85.wordpress.com/1387/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/kuroikaze85.wordpress.com/1387/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=kuroikaze85.wordpress.com&amp;blog=3649962&amp;post=1387&amp;subd=kuroikaze85&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://kuroikaze85.wordpress.com/2011/03/17/big-files-cachegrind/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/6e18f1f7becbfe66248caa034417b759?s=96&#38;d=&#38;r=X" medium="image">
			<media:title type="html">kuroikaze85</media:title>
		</media:content>
	</item>
		<item>
		<title>Задерживающий прокси а-ля xkcd</title>
		<link>http://kuroikaze85.wordpress.com/2011/02/25/delayed-proxy-xkcd-nodejs/</link>
		<comments>http://kuroikaze85.wordpress.com/2011/02/25/delayed-proxy-xkcd-nodejs/#comments</comments>
		<pubDate>Fri, 25 Feb 2011 18:15:44 +0000</pubDate>
		<dc:creator>kuroikaze85</dc:creator>
				<category><![CDATA[Дневник программиста]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[node.js]]></category>
		<category><![CDATA[эксперименты]]></category>

		<guid isPermaLink="false">http://kuroikaze85.wordpress.com/?p=1378</guid>
		<description><![CDATA[Неделю назад в замечательном комиксе xkcd была упомянута интересная тема: прокси, задерживающий запросы к определённым сайтам на 30 секунд, как средство борьбы с прокрастинацией. Естественно, мне захотелось реализовать такую штуку но время для этого нашлось только сейчас. Проксирование запросов Сделать обычный прокси в Node.js проще простого: Здесь я применяю метод pipe, позволяющий соединять два потока. [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=kuroikaze85.wordpress.com&amp;blog=3649962&amp;post=1378&amp;subd=kuroikaze85&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><img src="http://imgs.xkcd.com/comics/let_go.png" alt="" title="After years of trying various methods, I broke this habit by pitting my impatience against my laziness. I decoupled the action and the neurological reward by setting up a simple 30-second delay I had to wait through, in which I couldn't do anything else, before any new page or chat client would load (and only allowed one to run at once). The urge to check all those sites magically vanished--and my 'productive' computer use was unaffected." /></p>
<p>Неделю назад в замечательном комиксе xkcd <a href="http://xkcd.com/862/">была упомянута</a> интересная тема: прокси, задерживающий запросы к определённым сайтам на 30 секунд, как средство борьбы с прокрастинацией. Естественно, мне захотелось реализовать такую штуку но время для этого нашлось только сейчас.</p>
<p>	<span id="more-1378"></span></p>
<h2>Проксирование запросов</h2>
<p>Сделать обычный прокси в Node.js проще простого:</p>
<p><pre class="brush: jscript;">
var http = require('http');

http.createServer(function(request, response) {

  var proxy = http.createClient(80, request.headers['host'])
  var proxy_request = proxy.request(request.method, request.url, request.headers);
  proxy_request.on('response', function (proxy_response) {
    proxy_response.pipe(response);
    response.writeHead(proxy_response.statusCode, proxy_response.headers);
  });

  request.pipe(proxy_request);
}).listen(8080);
</pre></p>
<p>Здесь я применяю метод <a href="http://nodejs.ru/doc/v0.3.x/streams.html#stream.pipe" target=""><tt>pipe</tt></a>, позволяющий соединять два потока. Сначала мы соединяем запрос от пользователя с запросом к удалённому сайту, потом соединяем ответ от сайта с ответом нашему пользователю. Весь прокси-сервер укладывается в несколько строк. Здесь не учтены многие вещи, котоорые должен уметь прокси-сервер &mdash; например, перенаправление HTTPS-запросов &mdash; но для моих целей хватит и такого.</p>
<h2>Задержка для определённых сайтов</h2>
<p>Теперь надо сделать задержку для определённых сайтов. Сначала просто прочитаем список сайтов и преобразуем его в объект, чтобы было проще проверять присутствие домена в списке:</p>
<p><pre class="brush: jscript;">
var oc = function(a) {
  var o = {};
  for(var i=0;i&lt;a.length;i++) {
    o[a[i]]='';
  }
  return o;
}

var delayed_sites_raw = fs.readFileSync('timekillers', 'ascii');

var delayed_sites = oc(delayed_sites_raw.split(&quot;\n&quot;));
</pre></p>
<p>Функция <tt>oc</tt> (object converter) преобразует элементы массива в ключи объекта, чтобы можно было делать <tt>if ('domain' in delayed_sites) {</tt>.</p>
<p>Сами потоки можно задержать несколькими способами. Вообще у потока можно вызвать <a href="http://nodejs.ru/doc/v0.3.x/streams.html#stream.pause" target=""><tt>stream.pause</tt></a> (это остановит генерацию событий, но данные будут накапливатся в буфере) и потом продолжить обработку вызовом <a href="http://nodejs.ru/doc/v0.3.x/streams.html#stream.resume" target=""><tt>stream.resume</tt></a>. Я решил приостанавливать ответ от удалённого сервера &mdash; чтобы когда я вызову <tt>stream.resume</tt> ответ уже был получен и сохранён в буфере.</p>
<p>В результате получился вот такой код:</p>
<p><pre class="brush: jscript;">
var oc = function(a) {
  var o = {};
  for(var i=0;i&lt;a.length;i++) {
    o[a[i]]='';
  }
  return o;
}

var http = require('http'),
    url = require('url'),
    fs = require('fs');

var delayed_sites_raw = fs.readFileSync('timekillers', 'ascii');

var delayed_sites = oc(delayed_sites_raw.split(&quot;\n&quot;));

console.log('Delayed sites:' + delayed_sites);

http.createServer(function(request, response) {
  var delay = 0;

  if (host in delayed_sites) {
    delay = 30000;
  }

  var proxy = http.createClient(80, request.headers['host'])
  var proxy_request = proxy.request(request.method, request.url, request.headers);
  proxy_request.on('response', function (proxy_response) {
    proxy_response.pause();
    setTimeout(function() {
        proxy_response.resume();
    }, delay);
    proxy_response.pipe(response);
    response.writeHead(proxy_response.statusCode, proxy_response.headers);
  });

  request.pipe(proxy_request);
}).listen(8080);
</pre></p>
<p>Для тестов я использовал Firefox. Список доменов читается из файла <tt>timekillers</tt>, в котором они просто записаны по одному домену на строку:</p>
<pre>
www.reddit.com
twitter.com
news.ycombinator.com
habrahabr.ru
www.tumblr.com
</pre>
<p>Если через такой прокси открыть например Яндекс, он откроется сразу же. Но если попытаться зайти на Reddit, ответ от прокси придёт только через 30 секунд (это хорошо видно в консоли FireBug).</p>
<h2>Ссылки по теме</h2>
<ul>
<li><a href="http://xkcd.com/862/" title="" target="_blank">Комикс &laquo;Let Go&raquo; в xkcd</a></li>
<li><a href="http://nodejs.ru/doc/v0.3.x/streams.html" title="" target="_blank">Документация по потокам в Node.js</a></li>
<li><a href="http://www.catonmat.net/http-proxy-in-nodejs" title="" target="_blank">Руководство по написанию прокси в Node.js без соединения потоков (на английском)</a></li>
</ul>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/kuroikaze85.wordpress.com/1378/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/kuroikaze85.wordpress.com/1378/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/kuroikaze85.wordpress.com/1378/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/kuroikaze85.wordpress.com/1378/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/kuroikaze85.wordpress.com/1378/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/kuroikaze85.wordpress.com/1378/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/kuroikaze85.wordpress.com/1378/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/kuroikaze85.wordpress.com/1378/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/kuroikaze85.wordpress.com/1378/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/kuroikaze85.wordpress.com/1378/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/kuroikaze85.wordpress.com/1378/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/kuroikaze85.wordpress.com/1378/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/kuroikaze85.wordpress.com/1378/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/kuroikaze85.wordpress.com/1378/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=kuroikaze85.wordpress.com&amp;blog=3649962&amp;post=1378&amp;subd=kuroikaze85&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://kuroikaze85.wordpress.com/2011/02/25/delayed-proxy-xkcd-nodejs/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/6e18f1f7becbfe66248caa034417b759?s=96&#38;d=&#38;r=X" medium="image">
			<media:title type="html">kuroikaze85</media:title>
		</media:content>

		<media:content url="http://imgs.xkcd.com/comics/let_go.png" medium="image">
			<media:title type="html">After years of trying various methods, I broke this habit by pitting my impatience against my laziness. I decoupled the action and the neurological reward by setting up a simple 30-second delay I had to wait through, in which I couldn&#039;t do anything else, before any new page or chat client would load (and only allowed one to run at once). The urge to check all those sites magically vanished--and my &#039;productive&#039; computer use was unaffected.</media:title>
		</media:content>
	</item>
		<item>
		<title>Хостинг Node.js на Nodester</title>
		<link>http://kuroikaze85.wordpress.com/2011/02/16/node-js-nodester-hosting/</link>
		<comments>http://kuroikaze85.wordpress.com/2011/02/16/node-js-nodester-hosting/#comments</comments>
		<pubDate>Wed, 16 Feb 2011 12:12:46 +0000</pubDate>
		<dc:creator>kuroikaze85</dc:creator>
				<category><![CDATA[Дневник программиста]]></category>
		<category><![CDATA[CouchDB]]></category>
		<category><![CDATA[node.js]]></category>
		<category><![CDATA[хостинг]]></category>

		<guid isPermaLink="false">http://kuroikaze85.wordpress.com/?p=1370</guid>
		<description><![CDATA[Ну что ж, серия обзоров хостингов похоже приближается к концу Сегодня я посмотрю на последний найденный мной сервис: Nodester (бывший NodeFu). Как обычно, чтобы получить к нему доступ надо записаться на бета-тестирование через вызов API: Через некоторое время (2 дня в моём случае) на указанный адрес придёт код купона и инструкции по регистрации аккаунта. Чтобы [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=kuroikaze85.wordpress.com&amp;blog=3649962&amp;post=1370&amp;subd=kuroikaze85&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><a href="http://nodester.com"><img src="http://kuroikaze85.files.wordpress.com/2011/02/nodester_120.png?w=497" alt="" title="Лого Nodester"   class="alignleft size-full wp-image-1371" /></a>
<p>Ну что ж, серия обзоров хостингов похоже приближается к концу <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  Сегодня я посмотрю на последний найденный мной сервис: <b>Nodester</b> (бывший NodeFu). Как обычно, чтобы получить к нему доступ надо записаться на бета-тестирование через вызов API:</p>
<p><pre class="brush: bash;">
curl -X POST -d &quot;email=example@example.com&quot; http://nodester.com/coupon
</pre><br />
<span id="more-1370"></span></p>
<p>Через некоторое время (2 дня в моём случае) на указанный адрес придёт код купона и инструкции по регистрации аккаунта. Чтобы собственно зарегистрировать аккаунт есть два способа: простой и сложный. Простой: зайти на <a href="http://nodester.com/" target="">главную страницу</a> и нажать <b>Register</b>, в открывшемся окне ввести желаемые логин, пароль, полученный код купона и свой публичный ключ. Сложный способ — создать аккаунт через вызов API:</p>
<p><pre class="brush: bash;">
curl -X POST -d &quot;user=myusername&amp;password=mynewpassword&amp;email=example@example.com&amp;coupon=mycouponcode&amp;rsakey=ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEApRIZrAgJHwPKfJssLwsLpva3SNUNKPkjo4PfviKgTpzNdKVVy3g6ShCw2S381SLxtChg7c0uht04aRiVjyL61Aaigvd6RVWzVeUQjxNT/lguFHDzvHGf4lEh579aQLyUfKLzsbfqss2gIy56Al0Skk3buK871C3PlWZjUL6XkFaYjcfAJBjLVKi8LcNV25ivvKQeMeh2DA6/J36BS0CmB5wsaZbJqp4tDk/pA3ymvOZ/oaJPsMhKHUPxM9FHfkwoGzIUTBNcatsWIPsLL16bE/Jy7Aii3RSKp7tfjcSa5F6ngmXUwrlr%2BGV5hD2LWRc/YlxxKZWUrRU%2B8UdiEoJB6Q== root@debian&quot; http://nodester.com/user
</pre></p>
<p>Имейте в виду, при вставке публичного ключа в вызов curl необходимо заменить все вхождения <tt>+</tt> на <tt>%2B</tt>. К регистрации через сайт это не относится, туда ключ вставляется как есть. Проще всего произвести замену с помощью <tt>sed</tt>:</p>
<p><pre class="brush: bash;">
cat ~/.ssh/id_rsa.pub | sed s/'+'/'%2B'/g &gt; test-pub.rsa
</pre></p>
<p>Потом просто вставляете в вызов <tt>curl</tt> полученную строку из файла. После этих действий у Вас будет рабочий аккаунт.</p>
<h2>Установка и настройка</h2>
<p>Управлять аккаунтом на Nodester можно либо вызывая методы API с помощью <tt>curl</tt>, либо установив из npm утилиту для работы с хостингом из командной строки:</p>
<p><pre class="brush: bash;">
npm install nodester-cli
</pre></p>
<p>Методы API можно посмотреть на <a href="http://nodester.com/api.html" target="">этой странице</a>, а я воспользуюсь приложением. После установки надо добавить в приложение свои логин и пароль:</p>
<p><pre class="brush: bash;">
nodester user setup myusername mynewpassword
</pre></p>
<p>Теперь можно создавать приложение. В папке с файлом приложения делаем:</p>
<p><pre class="brush: bash;">
nodester app create myappname server.js
</pre></p>
<p>Здесь <tt>myappname</tt> — имя приложения, по которому потом можно будет к нему обращаться, <tt>server.js</tt> — файл, который требуется запускать для старта приложения (необязательный параметр). Удобно что файл можно указать сразу. После того как приложение создано, отправлять изменения на сервера можно так же как и с другими хостингами: командой <tt>git push</tt>. Правда, удалённый источник придётся добавить в репозиторий самостоятельно:</p>
<p><pre class="brush: bash;">
git remote add nodester url_from_api
</pre></p>
<p>URL, который здесь надо использовать, будет выдан при создании приложения.</p>
<h2>Другие возможности</h2>
<ul>
<li>Nodester тоже умеет работать с npm, но немного не так как Duostack. Необходимые Вашему приложению пакеты указываются командой <tt>nodester appnpm</tt> (либо соответствующим вызовом API).</li>
<li>Из хранилищ пока предлагается только облачный вариант CouchDB: <a href="http://www.couchone.com/" target="">CouchOne</a>.</li>
<li>Можно получать доступ к логам приложения</li>
<li>Можно повесить сайт на Nodester на собственный домен</li>
<li>На хостинге работает Socket.IO</li>
<li>Nodester можно развернуть на собственном сервере</li>
</ul>
<p>На последнем пункте я хочу остановиться поподробнее. В отличии от предыдущих хостингов Nodester предоставляет весь исходный код для создания собственного сервера с Node, апдейтами по git push, мониторингом, прокси для http-запросов собственной разработки и т.д. Скачать всё это можно <a href="https://github.com/nodester/nodester" target="">на Github</a>, инструкции по установке на Amazon/Rackspace (на английском) можно найти в <a href="https://github.com/nodester/nodester/blob/master/install.txt" target="">этом файле</a>.</p>
<h2>Ссылки по теме</h2>
<ul>
<li><a href="http://nodester.com" title="" target="_blank">Сайт Nodester</a></li>
<li><a href="http://nodester.com/api.html" title="" target="_blank">Руководство по API</a></li>
<li><a href="https://github.com/nodester/nodester" title="" target="_blank">Исходный код для размещения на своём сервере</a></li>
</ul>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/kuroikaze85.wordpress.com/1370/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/kuroikaze85.wordpress.com/1370/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/kuroikaze85.wordpress.com/1370/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/kuroikaze85.wordpress.com/1370/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/kuroikaze85.wordpress.com/1370/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/kuroikaze85.wordpress.com/1370/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/kuroikaze85.wordpress.com/1370/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/kuroikaze85.wordpress.com/1370/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/kuroikaze85.wordpress.com/1370/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/kuroikaze85.wordpress.com/1370/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/kuroikaze85.wordpress.com/1370/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/kuroikaze85.wordpress.com/1370/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/kuroikaze85.wordpress.com/1370/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/kuroikaze85.wordpress.com/1370/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=kuroikaze85.wordpress.com&amp;blog=3649962&amp;post=1370&amp;subd=kuroikaze85&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://kuroikaze85.wordpress.com/2011/02/16/node-js-nodester-hosting/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/6e18f1f7becbfe66248caa034417b759?s=96&#38;d=&#38;r=X" medium="image">
			<media:title type="html">kuroikaze85</media:title>
		</media:content>

		<media:content url="http://kuroikaze85.files.wordpress.com/2011/02/nodester_120.png" medium="image">
			<media:title type="html">Лого Nodester</media:title>
		</media:content>
	</item>
	</channel>
</rss>
