nginx init.d script

Рубрика: Development | 9 February 2009, 19:41 | Vadim Voituk

Как-то так получилось что при установки nginx с исходников, в /etc/init.d/ не установился скрипт для автозапуска web-сервера.

Потому исключительно себе на заметку (знаю точно – пригодится ещё) публикую то, что удалось найти в сети и допилить напильником до рабочего состояния.

Скачать nginx init.d / rc.d скрипт.

JavaScript applet loader.

Рубрика: Development, Java, JavaScript/Ajax | 6 February 2009, 13:50 | juriy

У каждого разработчика есть свои маленькие “заморочки” по поводу того как должно выглядеть приложение. Одна из моих любимых: пользователь должен знать минимум о том, как работает приложение и на каких технологиях оно построено. Взять, к примеру, Flash. Загружается тихонько в окне браузера, крутит пользователю картинки или видео и до тех пор, пока пользователь не начнет по нему кликать правой кнопкой, не признаЕтся кто он такой.

С другой стороны Java. Вот тебе пользователь раз логотип при загрузке апплета, да побольше, побольше, а если ты вдруг забыл про то, что работаешь с великой и могучей Java, мы тебе иконку в трей кинем, чтобы он тебе оттуда напоминал что пора качать новую версию.
Вобщем, вы мою позицию поняли.

Недавно я задался вопросом, как организовать загрузку апплета на странице так, чтобы пользователь не увидел экрана загрузки. Вместо него я бы хотел, к примеру, разместить логотип и progress bar (не настоящий, а просто картинку, которая показывает, что процесс идет). Второе обязательное требование: чтобы приложение отображалось, как только GUI прорисован. Мы не хотим заставлять пользователя ждать лишнее время.
[Далее...]

How it works: Jabber server resolve

Рубрика: Development | 27 January 2009, 19:01 | Vadim Voituk

При разработке Jabber2Twitter-гейта, получил от бета-тестров жалобу на то, что не удается добавить бота в список контактов с не-Google-овских клиентов/доменов (Ya.Online, Qip, etc).
(Google тут при том, что Jabber-демон “живет” на его серверах)

Тогда в мозгу родился вопрос: А откуда Jabber-клиент должен знать, что при коннекте к Jabber-серверу нужно идти не на тот IP-адрес, куда указывать DNS, а на Google-евый сервер?

Грубо говоря, если у меня DNS-запись домена jabber2twitter.com находится на одном сервере (ServerA), а Jabber-демон – на другом (ServerB), то откуда Jabber-клиент знает, что нужно открывать сокет на ServerB:5222 ? 

Вот тут как раз в дело вступают DNS SRV-записи, которые указывают размещение сетевых сервисов для конкретного доменного имени. 
Опять же на грубом примере это выглядит так: в SRV-записи домена указывается что искать FTP/LDAP/etc. сервисы, привязанные к этому домену нужно искать вот по такому вот адресу.
Почти также как MX-записи указывают на то, где искать почтовые службы, привязанные к доменному имени. 

Возвращаясь к теме Jabber-протокола, спецификация RFC 3920, в разделе “14.3. Client-to-Server Communications”  говорит что, что перед тем, как клиент производит DNS-resolve IP-адреса, он должен проверить SRV-запись с именем ”_xmpp-client._tcp.example.com.”
И только в случае неудачи подключаться к тому серверу, на какой указывает A-запись домена.

Кому это может понадобиться, кроме разработчиков Jabber-клиентов/серверов? 

Отвечаю: Например тем, кто использует Google Chat на своем домене и хочет добавить возможность чатится с jabber-пользователями вне пределов этого домена.

В таком случае необходимо добавить SRV-записи так, как это описано тут.

В моем же случае, добавление SRV-записей вроде как решило описанную вначале заметки проблему.
Буду благодарен, если кто пользует не Google-овские Jabber-клиенты, попробует добавить в контакты bot@jabber2twitter.com и сообщит мне видит ли он бота online

GoDaddy: Nameserver not registered.

Рубрика: Development | 21 January 2009, 13:06 | Vadim Voituk

При управлении доменными именами, зарегистрированными на GoDaddy, возникла проблема, которая убила у меня 2 часа полезного времени.
(вот только не надо мне рассказывать что GoDaddy это не труЪ – сам знаю)

При попытке назначить определенному домену собственные (custom) nameservers (например ns1.myzone.com и ns2.myzone.com), получаем ошибку “Nameserver not registered.”
Аналогичная ситуация наблюдается если пытаемся создать профиль с указанием custom nameservers.

Пользовательская справка GoDaddy по поводу решения этой проблемы скромно умалчивает (хотя раньше лично мне всегда помогала).

Решение оказалось немного нетривиальным:

Необходимо в настроках домена myzone.com кроме того, что создать DNS-записи для субдоменов  ns1 и ns2, ещё и добавить аналогичные записи в “Host Summary” (прямоугольный блок внизу слева, на странице с информацией о домене).
В первом поле ввода указать ns1, а в поле “Host IP 1” – IP-адрес, куда должен указывать NS.
Аналогично и для записи ns2.

И только после этого, GoDaddy позволит указывать ns1.myzone.com и ns2.myzone.com в качестве Custom Nameservers для своих доменов и использовать их в профайлах.

Java in a Cloud

Рубрика: Development, Google, Groovy, Java | 26 December 2008, 15:49 | Vadim Voituk

Пока прогрессивное мировое ИТ-сообщество самозабвенно обсуждает особенности трендового термина cloud-computing, массово уговаривает Google сделать поддержку Java&Groovy в Google App Engine, гадает будет или не будет в GAE поддержка Perl-а, небольшая компания из Вашингтона представила миру свое понимание cloud-computing в Java-мире.

Речь идет о компании Stax Networks, 16 декабря уходящего года запустившей под лозунгом “Java applications in the cloud” свой аналог Google App Engine для Java-разработчиков, который предоставляет завершенную инфраструктуру для разработки, тестирования и развертывания масштабируемых Java WEB-приложений.

Технически решение Stax построено поверх Amazon EC2 и позволяет создавать приложения основанные Servlets/JSP, Struts, GWT, Wicket, JRuby, Jython, Flex, ColdFusion.
В качестве СУБД в данный момент поддерживается только MySQL.

Инфраструктура Stax построена так, чтоб разработчику на этапе написания кода не нужно было думать о том, что находится на уроверь ниже чем Stax.
Управление приложениями и базами данных производится через удобную web-консоль, а локальная разработка и отладка производится привычными методами (я использовал для этого Eclipse и консольную утилиту stax).

Чем ещё интересен данный стартап – так это то, что в данный момент они не взымают плату за использование, аргументируя это тем, что вырабатываю правильную бизнесс-модель.
В итоге попробовать Stax в действии, в отличии от аналогов, можно абсолютно бесплатно и даже не имея кредитной карты.

Что я собственно уже и сделал: написал небольшое приложение, которое выводит список контактов из БД и запустил его в cloud-е на 2х серверах.
Под заголовком “Running Java in Cloud” можно увидеть IP и имя сервера в cloud-e, который обслуживает текущий запрос. И если понажимать F5 – можно заметить, что серверов всего-то 2.

В принципе идея предоставления Platform-as-a-Service (PaaS) далеко не новая, но более или менее популярных решений для Java мне пока не встречалось.

Аналогичные разработки:

  • Google App Engine (GAE) – самый известный из подобных app-хостингов.
    Пока поддерживает только Python и хранение данных в нереляционной БД Google BigTable.
  • Microsoft Azure – аналогичный GAE сервис от Microsoft. Поддерживает .NET языки.
  • Salesforce.com – CRM-хостинг для приложений написанных на проприетарном языке Apex
  • Heroku – аналог Stax, построенный на Amazon EC2, но для RubyOnRails приложений
  • 10Gen – ещё одна платформа, поддерживающая Python, Ruby и ServerSide JavaScript, а также обьекную СУБД Mongo.

P.S. В комплекте со Stax SDK идет Groovy древней версии 1.5.6

Мини идея: Языковая анти-амнезия

Рубрика: Development, Just a life | 23 December 2008, 15:01 | Vadim Voituk

В связи с тем, что в последнее время в моей деятельность над разговорным английским преобладает письменный, часто встречаю незнакомые слова / выражения / идиомы, за которыми приходится “лазить” в словарь (например только что искал в словаре “fascinating”).

Кроме этих слов есть туева хуча таких, которые используются очень редко, и их написание забывается (чело только стоит слово “gorgeous” – каждый раз за ним в переводчик лажу)

Дабы через 5 минут не забыть только что найденное слово, я решил записывать их на старых визитках, которые валяются на столе. В результате они постоянно навиду и постепенно откладываются в памяти.

Теперь суть идеи:

Комьюнити людей, которые таким вот образом сохраняют разные словечки/словосочетания/обороты/идиомы/etc, и соответственно публикуют их внутри собственных friend-групп.
Понравилось мне выражение или оборот из очередной статьи – запостил в свою группу.
Паралельно прочел “постинги” френдов.

Построить что-ли такое поверх Twitter?

Что думаете?

Simple & Reliable Java HTTP-server

Рубрика: Development, Java | 22 December 2008, 13:43 | Vadim Voituk

Думаю никто не будет спорить с тем, что на данный момент HTTP является самым популярным высокоуровневым сетевым протоколом.
Как следствие, все больше и больше приложений используют его для организации сетевых коммуникаций, и все больше и больше приложений содержат в себе функционал примитивного HTTP-сервера.

Вариантов, как встроить в свое приложение небольшой HTTP-сервер уйма –
начиная от аскетичного и сложно-развиваемого 10-ти строчного HTTP-сервера на Groovy, заканчивая интеграцией в приложение небольшого сервлет-контейнера Jetty.

Я же хочу предложить что-то среднее между этими двумя вариантами.
Начиная с 6й версии, в составе JRE поставляется пакет “com.sun.net.httpserver”, который содержит реализацию достаточно производительного и гибкого HTTP-сервера, построенного на асинхронной технологии NIO.

С его использованием код самого простого HTTP-сервера умещается в 30 строк Java-кода:


import java.io.IOException;
import java.io.PrintWriter;
import java.net.InetSocketAddress;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;

public class HttpServerEx implements HttpHandler {

	public static void main(String[] args) throws IOException {
		HttpServer server = HttpServer.create(new InetSocketAddress(80), 10);
		server.createContext("/", new HttpServerEx());
		server.start();
		System.out.println("Server started\nPress any key to stop...");
		System.in.read();
		server.stop(0);
		System.out.println("Server stoped");
	}

	@Override
	public void handle(HttpExchange exc) throws IOException {
		exc.sendResponseHeaders(200, 0);
		PrintWriter out = new PrintWriter(exc.getResponseBody());
		out.println( "Hello moto!" );
		out.close();
		exc.close();
	}

}

Теперь, думаю, никому не составит труда расширить метод handle() под свои нужды.

Более подробную документацию можно найти тут: Javadoc пакета “Java™ HTTP Server”

К сожалению исходный код пакета доступен только как часть Standard Edition Development Kit Source Release под Java Research License, что вынуждает немного “попотеть” чтоб его добыть.

P.S. За наводку спасибо Dmitriy Kopylenko и его ссылке на реализацию подобного HTTP-сервера на Scala.

WordPress: Exclude post by ID from main loop

Рубрика: Development | 13 December 2008, 23:33 | Vadim Voituk

Очень часто в wordpress, при получении списка заметок посредством создания WP_Query, нужно исключить одну или несколько, с определенными “магическими” ID.

Документация на codex.wordpress.org по этому поводу молчит. Взамен предлагается исключать только заметки из определенной категории.

Как вариант предлагается выполнять фитльтрацию внутри цикла:

$query = new WP_Query(...)
while ($query->have_posts()): $query->the_post();
    if (get_the_ID() == '231231') continue;
    ...
endwhile;

Такой метод мне не очень по душе, потому как он изменяет количество результатов при выводе.

Немного поковырявшись в исходном коде класса WP_Query обнаружилось, что возможность исключить определенные post_ID на этапе запроса все-таки есть:

$query = new WP_Query("post__not_in[]=231231&post__not_in[]=231232&..")

Особенность недокументированного параметра “post__not_in” в том, что его значение обязательно должно быть arrray-ем (оттуда и символы “[" и "]“). Иначе получим warning и неверный результат.

Для “кодирования” списка ID в строку, можно воспользоваться функцией http_build_query().

Mount tool trick – Symlinks replcement

Рубрика: Development | 4 December 2008, 10:52 | Vadim Voituk

Есть такая категория убогого *nix софта, которая не поддерживает работу с символическими ссылками файловой системы.

К числу таких относится, например, FTP-демон VSFTPd (ох доберусь я как-то до того, кто мне его посоветовал).

Специально для таких случаев хочу посоветовать использовать утилиту mount с параметром –bind.
Она позволяет выполнить mount одной директории в другую, причем даже на другом физическом диске.

Запускается приблизительно так:
mount --bind /dir/from /dir/to

И соответственно запись в /etc/fstab выглядит таким образом:
/dir/from /dir/to none rw,bind 0 0

Имею надежду, что будет полезно тем, кому время-от времени приходится перебрасывать данные между разделами и дисками сохраняя старые директории.

The power of 4k

Рубрика: Development, Java | 27 November 2008, 11:25 | juriy

Уже много-много времени я увлекаюсь разработкой игр на Java. Да что тут говорить, мое первое приложение на Java была мини-игра для мобильного телефона Siemens M55, моя первая постоянная “программистская” работа была тоже связана разработкой игрушек на Java.

Эта заметка посвящена ежегодному событию, которое проходит по инициативе www.javagaming.org – состязанию Java 4k. Правила очень простые – необходимо сделать интересную игру на Java, так чтобы размер архива (jar) с игрой (и всеми ресурсами) не привышал 4 килобайта. Трюки вроде “напишу-ка я на 4 кб загрузчик, который подтянет с сайта мой 50-мегабайтный движок” не проходят.
Естественный вопрос: “что, черт побери, можно написать на 4 килобайта?”. Чтобы на него ответить достаточно взглянуть на игрушки прошлых лет:

Победитель прошлого года, простая, но интересная аркада:

Spiderball4k
А эта игра потрясет любого: изометрическая Real-Time стратегия, где есть разные юниты, можно строить здания, добывать ресурсы и воевать с AI! Комментарий к этой работе с форума javagaming выражает основную мысль как нельзя лучше: “Hey, where did you put other 100k?!”
T4anks

Есть еще множество интересных игр. В этом году я думаю присоединиться к соревнованию. Надеюсь, времени хватит.