Как стать автором
Обновить
4
0

Разработчик

Отправить сообщение

справедливости ради могу сказать, что производительность express значительно выше, чем у SimpleHTTPServer. Корректнее было бы сравнить его с tornado/TwistedWeb с прикрученным greenlet.

никогда, прошу вас, никогда не деплойтесь через npm install на продакшне.
Ворох зависимостей в 5+ уровней в глубину — это не то, что можно проконтролировать.
Ну может вас ещё спасёт приколоченный гвоздями снапшот зеркала npm, с зафиксированными намертво версиями пакетов.

многословность питона хорошо компенсируется большой и удобной стандартной библиотекой.

А почему бы в случае уже существующего express-проекта не взять bluebird и использовать его Promise.coroutine для обёртывания генераторов? Снаружи это выглядит, как обычный promise, который можно скормить в express, а внутри это выглядящий линейным код.
В принципе текущая реализация async-функций совместима с Promise и можно использовать её as is в свежих версиях node (6+?), как справедливо заметили выше.

только при условии, что тесты написаны. и они есть на вышележащие слои тоже.

Аргументы за простые и маленькие функции:
1) Каждую в отдельности легко прочитать. Меньше сущностей нужно уложить в голову, когда воссоздаётся модель поведения.
2) Легче покрывать код тестами — относительно мало инвариантов, которые нужно проверять.


Против:
1) Увеличение связности кода. Т.е. меняя функцию в глубине, можно сломать вышележащие. На самом деле сложность из самой функции перемещается в связи между ними. У каждого кусочка кода растёт количество способов его использования. Может возникнуть ситуация, когда приходится какой-то кусочек обобщать настолько, что на самом деле было бы проще раскопипастить частные случаи выше по стеку. (Нарушили случайно single responsibility и ой).


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

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

Транзакционный доступ — это как раз про отсутствие гонок =)
Транзакции — это абстракция немножко выше уровнем, чем параллельный доступ к кускам памяти. Нужна ещё реализация, которая их обеспечит.
Дедлоки при транзакциях возможны, и за этим проследят супервизоры и отстрелят зависшие.


Гонка — это когда происходят чтения или записи кусков, которые в этот же момент пишут другие, т.е. в реализации транзакций будет баг (блокировку не захватили или барьеры не выставили, или версию забыли поднять в mvcc, а уже пишем в shared-кусок), к примеру.
Они чреваты тем, что вместо целостной структуры будет полная галиматья, где полструктуры обновлены одним потоком, а вторые полструктуры — другим. Это, конечно, можно вычислять какой-то функцией, которая в рантайме будет проверять инварианты, но откуда она возьмёт данные, на которые надо откатиться, и как она найдет виноватых?


У вас была какая-то готовая и надежная реализация транзакций, или пришлось писать самим и вылавливать затейливые баги?

всё так. нужно использовать сразу весь комплекс техник оттуда, чтоб получить реальный рост отказоустойчивости. иначе первый же залетевший race condition разрушит цивилизацию.

подсказка

это ASCII, но не арт, и имеет прямое отношение отношение к дедовским способам ввода.

не может быть 17 и 13, потому что в feed есть 15.
хотя на самом деле это не так важно.

но ответ в итоге нашёлся самым простым и ортогональным хешированию образом.

Тем не менее let it crash подход с локализацией любого падения и перезапуском упавшего куска супервизором с дальнейшим пересозданием состояния начисто из доверенного персистентного источника вполне прижился в эрланге.
Впрочем в эрланге это прокатывает лишь благодаря куче других хитрых особенностей рантайма — повальной иммутабельности, взаимодействию через обмен сообщениями итд.
Так что при определённой гигиене кодирования данная техника действительно позволяет писать отказоустойчивый код. Корректный — нет.

Интересный квест. Надо сказать довольно простой — больше долго я провозился только с последними двумя задачками.
Остальные довольно простые и решаются почти без отрыва от рабочего процесса. Хотя дайджест меня заставил ненадолго зависнуть.


Ниже сорцы, которыми я размял мозг.


Брутфорсный велосипед к 24й задачке, ибо не осилил разложить на множители в уме
def getnum(literal):
    return ord(literal) - 48 if 48 <= ord(literal) <= 57 else ord(literal) - 87

def todecimal(literal, osn):
    return reduce(lambda a, x: a+getnum(x[1])*(osn**x[0]), enumerate(reversed(literal)), 0)

def toliteral(num, osn):
    if num < osn:
        return str(num) if num < 10 else chr(num+87)
    val = num / osn
    r = num % osn
    return toliteral(val, osn) + (str(r) if r < 10 else chr(r+87)) # всё это происки лисперов злых.

for i in xrange(11, 35):
    for j in xrange(11, 35):
        num = todecimal('cb0b6', i) + todecimal('feed', j)
        v = toliteral(num, i+j)
        if i * j == 221:
            print i, j, v

Как хорошо, что 25 задание оказалось не на йожином диалекте, а образцом литературного языка.
import collections

# пробелы не выпиливаем, всё равно они самые популярные
c = collections.Counter(s.decode('utf-8').replace(',','').lower())

# и дальше до посинения ищем правильные частоты.
replaces = dict(zip(map(lambda x: x[0], c.most_common()), 'а здесь список по убывающей частоте и его я вам не дам'))
print reduce(lambda a, x: a+replaces.get(x, u'_'), s.decode('utf-8').lower(), '')
даже так скажу. не надо брать varchar2, надо использовать nvarchar2, потому что иначе серверные сортировки могут очень странно работать для неанглоязычных строк.
я сам в такого опасного человека легко превращаюсь, когда пишу что-то не относящееся к моим основным компетенциям.
Разные мелкие скрипты, которые могут мне облегчить жизнь, но не стоят вложения серьёзных усилий, или куски на ангуляре, в котором я, мягко говоря, плохо разбираюсь и неоткуда быстро взять системные знания, а задачу нужно решить.
Согласен с поправкой, просто хотелось сделать акцент именно на протечке абстракции сокета. В случае TCP и UDP абстракция течёт по-разному и вызывает разные проблемы.
Мне кажется, что человек, который не знает что такое сокет, менее опасен, чем человек, знающий про TCP-сокеты, и бодро фигачащий точно такую же реализацию поверх UDP со словами, «ну а шо, что то — сокет, что это — сокет, оба — сокеты». Не надо так. Не знающего человека можно научить, а вот человека с уже сложившимся паттерном мышления нужно переучивать, что сложнее.

N.B. это больше про людей, которые применяют stackowerflow-driven development, и не относится к людям, умеющим читать нормальную документацию перед использованием чего-либо.
> Не нужно делать проблему, когда возникает задача написать программу для обмена по UDP, а вы раньше писали только обмен по TCP протоколу.

Охохохо, мне кажется, что вы серьёзно подставились. Потому что между TCP и UDP транспортом есть небольшая, но критически важная разница в виде абстракции, которую каждый из них предлагает.
TCP — это труба из байтов. С ним всё отлично (почти), байты всегда приходят в том порядке, что отправлены и доставка гарантируется.
UDP — это негарантированная передача блобов ограниченной длины. Стоит напороться на какой-нибудь перегруженный маршрутизатор, и пакеты могут не дойти совсем. Приложение обязано быть готово к тому, что блобы придут в любом порядке, и могут не придти вообще, отправляющая сторона тоже должна быть к этому готова. Также есть куча всяких граблей вроде поддержки фрагментации пакетов в сети и MTU, которые неявно задают ограничения на передаваемый размер блоба.

Т.е. если вы пишете конечный автомат, управляемый по UDP, вы должны быть готовы к куда большему пространству подаваемых в него команд, плюс самостоятельно реализовать алгоритм переотправки застрявших на отправителе команд, итд. // да, есть библиотеки, но требования понимания, что внутри происходит это не отменяет.
ацетон в этой стране щас не купишь. =(

Информация

В рейтинге
Не участвует
Зарегистрирован
Активность