[Mac OS]: Как собрать свой Sparrow Lite

Сегодня случайно узнал как получить себе экземпляр супер крутого mail клиента совершенно бесплатно, безсмсиабонентскойплаты, но с рекламой. Это по сути версия Lite, которая была раньше в AppStore, но теперь отсутствует. Нашел ссылки на скачку на brokenstones, когда хотел скачать полную версию на халяву)

Для этого не требуется супер знаний, а всего навсего:

  • скачать 20Mb из интернета
  • наличие Xcode

С первым пунктом проблем в наше время ни у кого уже нет, а со вторым я думаю уже тоже, любой разработчик ставил себе как минимум brew, который как минимум опять же тащит за собой Xcode. Поэтому приступим.

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

В общем качаем по ссылке для мака. Это zip архив на 20Mb. Не обеднеете я думаю. Распаковываем куда-нибудь, заходим в директорию и видим нам несколько вложенных директорий и файлов, для начала:

chmod +x build-mac.sh  

Это даст права на исполнение файлу сборки проекта. Далее открываем этот файл вашим любимым редактором.

vim build-mac.sh  

Находим 3ю строчку:

xcodepath=/Applications/Xcode45-DP2.app  

Здесь необходим поправить путь до своего Xcode, у меня это было

xcodepath=/Applications/Xcode.app  

После чего сохраняем файл и выходим. Собираем проект:

./build-mac.sh

Вот собственно и все. Далее заходим в папку app, это уже можно сделать через finder, открываем приложение Sparrow внутри, оно предложит скопировать себя в папку Applications ну и далее все как обычно. Вуаля, у вас есть свой экземпляр Sparrow.

Если есть ребята хорошо владеющие ReverseEngineering, то можно попробовать покурочить немного это приложение и выключить рекламу.

Прочитать

[Chef]: Создание пользователей в системе

Потребовалось однажды засетапить сервер и возникла необходимость создания пользователя.

Пусть это будет пользователь poweruser, sudo ему пока не нужно, разве что для runit'а чуть попозже добавим. На выбор встали 3 кукбука:

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

Поясню: есть пользователь poweruser, это пользователь системы на прод сервере, и есть некоторая команда разработчиков: Вася(vasya), Ваня(ivan), Петя(petya). Удобно организовать это следующим образом:

app_path/  
  data_bags/
    users/
     ivan.json
     vasya.json
     petya.json
     poweruser.json

У разработчиков хэш выглядит примерно так:

{
  "id" : "ivan",
  "ssh_keys" : "ssh-rsa .... mail@mail.com"
}

У основного нашего пользователя системы:

{
  "id" : "poweruser",
  "password" : "some_really_secure_password"
}

Теперь когда мы захотим засетапить очередную ноду, то нужно будет переопределить массив users например в роли:

name "my_super_role"  
description "my really super role"

run_list [  
  ...
  "recipe[users]"
]

default_attributes(  
  :users => [ 
    "poweruser" => [
      "ivan",
      "vasya"
    ]
  ]
)

Получается что мы доверяем заходить под пользователем poweruser нашим 2м разработчиком и что-то творить там, собирать логи, прокручивать руками какие-то таски и т.д., а вот третьему нет никакого доверия, так что его ключи не будем закидывать.

Второй кукбук это официально поддерживаемый community opscode, которым наверное пользуется большинство, а может нет. Тут все супер классно, за исключением одной небольшой вещи, ни черта непонятно как его использовать. Поэтому после 5 минут изучения кода, я решил, что он мне не нравится и использовать его не буду.

Третий кукбук от небезызвестного товарища fnichol, который написал кучу кукбуков. Именно на нем я и остановил свой выбор. Скорее всего это просто личные предпочтения. Тут все также очень просто, создаем пользователя в папке data_bags, туда в массив ssh_keys помещаем нужные нам ключики и "готовим" с помощью knife solo. В файле с ролью просто определяем массив пользователей, которых мы хотим создать.

default_attributes(  
  'users' => ['poweruser']
)
knife solo cook root@x.x.x.x nodes/some_project_node.json  

Вот и все, теперь на тачке есть пользователь poweruser.

Прочитать

Processes & Threads #3

Продолжим рассказ о тредах, процессах и способах синхронизации. В прошлый раз разговор был о мютексах, теперь же поговорим о семафорах.

Семафоры

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

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

Семафор со счетчиком 1

В ванной могут возникать 2 ситуации:

  • дверь открыта и внутри никого нет
  • дверь закрыта и внутри кто-то есть

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

В некоторых операционных системах мютексов как таковых нет, они реализованы через семафоры.

У них есть важные отличия, продолжая аналогию — мютекс это щеколда, семафор это ключ от замка. Таких ключей может быть как 1 так и много. Счетчик семафора говорит о том, сколько одновременно желающих может воспользоваться ресурсом.

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

Но для кухни такой вариант синхронизации не подойдет.

Семафор со счетчиком > 1

Предположим мы сделали в кухне дверь с замком. У замка есть 2 комплекта ключей, которые висят снаружи на стене. Дверь всегда закрыта, когда кто входит внутрь кухни, он закрывает за собой дверь. Такие правила игры, таким образом можно контролировать необходимое нам количество людей внутри кухни.

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

Тоже самое происходит с тредами, мы устанавливаем счетчик равный 2. Когда треду требуется ресурс он уменьшает счетчик семафора на 1 и забирает ресурс, когда второму требуется это же ресурс, он также уменьшает счетчик на 1, третьему же треду придеться ждать пока один из предыдущих пользователей вернет ресурс на место.

Существует еще несколько способов синхронизации — условные переменные, барьеры и т.д., но о них я здесь говорить не буду.

На этом вводную часть буду считать законченной и в следующих заметках планирую рассказать о тонкостях реализации тредов в Ruby.

Прочитать

Processes & Threads #2

Поскольку основные определения и понятия уже введены перейду сразу к сути.

Взаимное исключение

Мой любимый пример с хостелом. Встали вы с утра и сильно хотите помыться и выйти уже из этой душной комнаты, набитой храпящими потными мужиками, а дверь в ванную как назло закрыта, потому что кто-то уже моется, да еще и очередь из тапочек и полотенец собралась.

Это именно то, что происходит с тредами при попытке доступа к общему ресурсу. Когда один тред захватывает его, то ставит на него блок(закрывает ванную изнутри на щеколду).

Это способ синхронизации, который использует объект mutex (от MUTual EXclusion — взаимное исключение). В этом примере это щеколда, которая блокирует доступ всем остальным участникам, когда кто-то помылся и вышел, т.е. снял защитный барьер, следующий тред начинает использовать ресурс и ставит на него защиту.

Но тут есть свое исключение, mutex скорее рекомендательное защитное средство нежели правило, так что если у вас есть сосед весом в 120 кг, занимающийся тайским боксом, он вполне может выломать дверь и войти.

Приоритеты

Интересный вопрос встает перед операционной системой или же перед разработчиком приложения, что делать когда ванная откроется? Кого пускать первым?

Было бы честным пустить того, кто следующий в очереди или того кто дольше всех ждет, а может все же пропустить того 120 килограммового парня, пока он сам не подвинул следующего. Есть много способов выбрать что же такое "честно" в данном контексте.

Например можно решить это двумя факторами: приоритетом исполнения и временем ожидания.

Допустим 2 человека сразу ожидают очереди помыться, один из них уже сильно опаздывает на назначенную встречу, а у второго нет больших планов на это утро. Логичнее было бы пропустить того, у кого встреча, но каким образом это делать? Например, назначить ему больший приоритет, а человеку без планов низкий приоритет. Возможное решение делать это простыми числами от 1 до скольки-то.

С тредами тоже самое, тред наследует от своего родителя алгоритм планирования (scheduling). Но вполне может внутри себя его и переопределить вызвав соответствующие функции операционной системы(зависит от реализации самой ОС).

Так что же происходит, когда дверь в ванную открывается? Мы даем возможность помыться тому, у кого приоритет выше остальных. В случае если остались все с одинаковым приоритетом "честно" будет отдать право воспользоваться ванной тому, кто дольше всех ждет.

На этом утренние посиделки с процессами и тредами закончены, в следующем выпуске нашей ультроразвлекательной программы поговорим о другом способе синхронизации - семафорах.

Прочитать

[Отзыв]: Операционная система UNIX

Первое, что хочется написать:

Это было сложно

Это большая книга, с большим объемом информации и могу с точностью сказать, что вернусь к ней еще как минимум раз. Информация здесь - это основы, которые должен знать каждый уважающий себя разработчик.

  • как устроена Unix
  • как работают сокеты
  • как происходит передача информации по разным протоколам
  • что такое ядро системы

....

Перечислять можно еще очень долго и много. Самое главное, что надо понять - изучайте основы. Надо всегда четко понимать под какую систему вы разрабатываете приложение. Не важно на каком языке вы пишете, C, Ruby, Erlang. Они все используют на низком уровне возможности и ресурсы системы.

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

Если вы не понимаете как устроена файловая система и как база хранит свои данные на ней, то никогда не сможете нормально оптимизировать запросы, когда быстрее full_scan, а когда random_access.

Очень важная часть книги про процессы и сигналы. Когда и кому отдаются ресурсы по приоритету, какие сигналы и когда корректно отсылать. Каким образом происходит рождение процесса и кто на самом деле умирает при kill -9 pid.

Наверное это все,что я могу сказать про эту книгу, просто прочитайте.

Ссылка для желающих:

"Операционная система UNIX" Андрей Робачевский, Сергей Немнюгин, Ольга Стесик - ISBN 978-5-94157-538-1"Операционная система UNIX" Андрей Робачевский, Сергей Немнюгин, Ольга Стесик - ISBN 978-5-94157-538-1

Прочитать