Invitation to Interview for: Blogger Developer & Javascript Fixer
Invitation to Interview for: Blogger Developer & Javascript Fixer
Доброе утро, пупсики скрам-мастера, ниндзя-ноджс гуру и ТДД-эксперты в разработке высоконагруженных бек-ендов "2 запроса в секунду". Сегодня мы поговорим о расстановке столов внутри офисной комнаты (презентация на ascii5 прилагается). Имеется комната вида:
/-----------------\
| |
| |
| |
| |
| |
| |
\-----------------/
Вот так рассаживать программистов НЕправильно:
/-----------------\
| |
| o o o |
| === === === |
| === === === |
| o o o |
| |
\-----------------/
Точно так же неправильной является "облегченный" вариант предыдущей расстановки:
/-----------------\
| o o o |
| === === === |
| |
| |
| === === === |
| o o o |
\-----------------/
Единственно правильной расстановкой является вот эта:
/-----------------\
| === === === |
| o o o |
| |
| |
| o o o |
| === === === |
\-----------------/
Никто никого не заёбывает лишними разговорами, никто не пялится на чужие рожи сто раз в день, любители пейр-программинга (а еще больше -- его ненавистники) тоже довольны, т.к. не нужно совершать царский обход столов чтоб глянуть какую же хуйню кто-то там написал.
Спасибо!
Нода с риаком отвалилась, мускуль от нагрузки стал "ппопадать". Нет, пора идти спать явно.
Это чувство, когда как не сядешь поработать -- какая-то хуйня за прошедшие сутки случилась и приходится разгребать и подымать. Сейчас вообще пиздец -- на редисах по 11 млн записей и место закончилось (даже своп), на воркерах место закончилось (при чём узнал я это когда деплой-скрипт не мог ссш-сертификаты пробросить и сделать гит клон почему-то), мониторинг давно лёг уже. Ну что за пиздец.
Всё же, есть какие-то преимущества у статической типизации. Но какие? // половину времени сэкономил бы, блеать
cf30cca Fix remaining tests Me, 66 minutes ago
99674ac Fix some of tests Me, 71 minutes ago
ae2c63d pep8 fixes, usage of bl instead of object method Me, 19 hours ago
17a0328 Remove foo module Me, 19 hours ago
944b358 Provide special mechanism for countdown celery tasks in tests Me, 19 hours ago
dd54954 Refactor tests a bit, get back Foo's email class Me, 22 hours ago
6f0c8fe Remove unused modules Me, 24 hours ago
842ea7e Fix syntax Me, 24 hours ago
9c6d02b Fix data model in test Me, 25 hours ago
68ced8d Fix tests Me, 2 days ago
781bcd4 Add category property to emails Me, 2 days ago
158cd45 Fix import Me, 2 days ago
e3587b8 Fix syntax after hard merge Me, 2 days ago
ca29d12 Fix import Me, 2 days ago
538e4b4 Fix more tests Me, 2 days ago
0b5d3df Fix more tests Me, 5 days ago
ccf99c7 Create order items for test Me, 5 days ago
340b199 Add items to cart for rendering email Me, 5 days ago
76a7b4a Add missing super()s, add travis INVALID render string setting Me, 5 days ago
0d7258e Remove unused class Me, 5 days ago
5d9f9d0 Some fixes in tests and logic Me, 5 days ago
23b5e41 pep8 fixes Me, 6 days ago
b9a5c27 Rebase Me, 6 days ago
1e95f98 Add cart, add failure template Me, 8 days ago
318e3a8 “Rebase” Foo’s work Me, 8 days ago
b19d2ad BUG-729 get shit done Me, 8 days ago
Наконец-то не поленился и написал питоноскрипт, проходящий по риаку и выводящий хоть какую-то статистику (чтоб понять, работает это говно вообще или нет). И вдруг я осознал, что ДА У НАС ЖЕ ХАЙЛОАД! ~30k ивентов одного только типа в минуту (это сейчас, когда почти ничего не работает). Был уверен, что всё гораздо меньше.
На работе в пятницу будут представлять НОВУЮ АРХИТЕКТУРУ, даже на научный пэпер сослались в ридми гитхаба, сижу читаю. Всё-таки как-то ненаучно все эти распределённые системы. Какое-то сплошное:
Let’s start out with three assumptions which are
asserted and not justified. We simply assume these are
true based on experience.
Не то чтобы я был учёным дохуя, конечно же, но лучше бы меня аналогично вгоняли в написание каких-то генераторов парсеров и компиляторов, чем в эту сетевую хуйню.
Интересно, насколько сложно запилить какой-то бутстрап-скрипт, который не только на сервер емакс ставит, но еще и для него настройку делает для питонопрограммирования по типу pep8/pyflakes. А то чувствую сейчас начну фигачить неслабо прямо в сервере (статистику всякую из продакшна выгребать).
Пожалуйста не клонируйте,
не форкайте и вообще
не трогайте.
1999, Мао Дзы
Короче, благодаря следованию гит-воркфлоу поломал нахуй репозитории и
приходится переносить старую работу на новый клон пофайлово при помощи
супер-команды
git diff filename > ../patch.patch && cd ../my-repo-with-feature
&& git apply ../patch.patch; cd ../my-repo-with-feature-discarded
Кайф!
Драйвер редиса возвращает Redis (Either Reply a)
. При операции HGET
возвращает, соответственно, Redis (Either Reply (Maybe ByteString))
, типа значения по ключу может и не быть. Программист для упрощения пишет сначала специальную функцию redis'
, которая заворачивает ответ редиса в EitherT-based монаду, чтоб соединять подобные вычисления и возвращать первую неудачу:
newtype Redis' a = Redis' (EitherT Redis.Reply Redis.Redis a) deriving (MonadIO)
instance Monad Redis' where
return = Redis' . EitherT . return . Right
(Redis' m) >>= f = Redis' $ m >>= \rv -> unwrapRedis' $ f rv
redis' = Redis' . EitherT
Таким образом, теперь, если вы получаете ответ Redis (Either Reply a)
, вы его преобразуете в
Redis' (EitherT Reply Redis a)
и можете соединять подобные вычисления в do-блоке типа:
do
res <- redis' $ Redis.hget foo bar
res2 <- redis' $ Redis.hget baz zab
и вычисление остановится на первом возврате ошибки.
Далее. Программисту необходимо по кучке значений сделать HGET
и вернуть это как-то внутри кортежа, поскольку мы внутри новой монады Redis'
-- завернуть результат в неё. В случае, если значения хоть по одному ключу не существует, хочется вернуть Nothing
для всех. Потому создаётся новая монада:
newtype HashFields a = HashFields (MaybeT Redis' a)
deriving (Functor, Monad)
instance Applicative HashFields where
pure = return
(<*>) = ap
описывающая вычисления типа Redis'
, которые могут вернуть неудачу. Пишется новая функция
hashField = HashFields . MaybeT . redis'
способная завернуть результат неудачи в новую монаду, которая умеет останавливаться на первой неудаче. Также пишется специальная функция для HGET
:
getField :: ByteString -- ^ Key
-> ByteString -- ^ Hash field name
-> HashFields String
getField key field = fmap toString $ hashField $ Redis.hget key field
Также напишем функцию, которая "запустит" наше вычисление:
getRedisFields :: forall a. HashFields a -> Redis' (Maybe a)
getRedisFields (HashFields f) = runMaybeT f
И теперь лёгким движением руки мы можем сделать что-то вроде:
getRedisFields ((,,,,,) <$>
getField k "foo" <*>
getField k "bar" <*>
getField k "baz" <*>
getField k "zab" <*>
getField k "rab" <*>
getField k "oof")
Вопрос: вам не кажется это "слишком"? Я пока еще не настолько просто манипулирую типами в голове, чтоб ощутить всю ситуацию, хорошо хоть в целом могу медленно прости по шагам по коду, но есть ощущение, что что-то здесь не так.
Пишу тонну factory-бойлерплейта, но понимаю, что читающий может быть слишком шокирован, потому заставляю себя "пока-что-ненужные" вещи писать напрямую. Possible-cultural-misunderstanding-driven development.