• Как конфигурация влияет на архитектуру приложения

      Тестовое приложение для тестирования сериализаторов было сделано на библиотеке NFX. Это Unistack библиотека. Честно говоря, я затрудняюсь назвать другой пример Unistack библиотеки. Может быть что-то похожее есть в виде ServiceStack. Хотя ServiceStack, в отличии от NFX, размазан по нескольким dll. Но самое главное, ServiceStack не является Uni, так как его части сделаны немножко по-разному, и он не покрывает такого глобального пространства, как NFX. Но целью данной статьи не является обсуждение концепции Unistack, а одна из особенностей использования NFX.

      Как использование NFX повлияло на наше тестовое приложение? Давайте посмотрим.
      Читать дальше →
    • Tестирование сериализаторов под .NET

      Код Serbench находится на GitHub.

      Начало проекта


      Этот бенчмарк проект начался со статьи “Serializers in .NET v.2” на GeeksWithBlogs.net. В статье было рассмотрено довольно много имеющихся под .NET сериализаторов. Но, чтобы превратить эту статью и соответствующий код в настоящий бенчмарк, надо было сделать несколько улучшений.

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

      Во-вторых, сериализаторы сильно отличаются по интерфейсам. Наш бенчмарк не должен заставлять сериализатор следовать нашему выбору интерфейса. Наоборот, бенчмарк должен быть настолько гибким, чтобы каждый сериализатор мог бы использовать наиболее подходящий для него интерфейс. То есть надо передавать в бенчмарк дополнительные параметры конкретного сериализатора.
      Читать дальше →
    • Пишем LINQ на JavaScript с нуля

      Зачем


      Однажды при разработке компонента графика для веб-браузера мы столкнулись с проблемой обработки последовательностей на JavaScript.

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

      Естественно, хотелось бы иметь аналогичные возможности и на JavaScript.

      На данный момент существует немало реализаций LINQ для JavaScript, например, linq.js, $linq. Эти реализации предоставляют широкие возможности, сравнимые с реализацией на C#. Обратной стороной является немалый размер кода, из которого в конкретном приложении может использоваться лишь небольшая часть. Например, нам необходима лишь функция distinct, а мы вынуждены добавлять килобайты кода third-party библиотеки.

      Опять же, любопытно разобраться, как же конкретная библиотека работает, а разбирать исходный код большой библиотеки зачастую утомительно. Или в нашем случае у нас уже есть своя библиотека для JavaScript и мы лишь хотим её компактно дополнить функционалом работы с последовательностями.
      Читать дальше →
    • Метапрограммирование (с примерами на JavaScript)

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

        Популярное понимание метапрограммирования обычно очень размытое, и чаще всего, заканчивается такими вариантами:
        • Шаблоны и макросы, используемые при компиляции
        • Программа, которая изменяет саму себя
        • Программа, генерирующая другую программу

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

        Читать дальше →
      • Назад, к технологиям верхнего палеолита, от любимых всеми REST, STATEless, CRUD, CGI, FastСGI и MVC

          «Только со смертью догмы начинается наука.»
          // Галилео Галилей


          «Я начал завидовать рабам. Они всё знают заранее. У них твёрдые убеждения.»
          // х/ф Марка Захарова «Убить дракона» по мотивам пьесы Евгения Шварца


          Уже пару лет и дня не проходит, чтобы я не услышал (или не прочитал) от людей, начинающих новые проекты, фразу типа «Возьмем серверный движок для REST API и MVC, и погнали». Сначала я думал, что у этих слов есть один источник, может книжку какую завезли во все магазины или где-то в топе поисковиков лежит статья, зомбирующая разработчиков. Если же выяснять у них, что они понимают под REST и MVC, то можно повредиться умом. Ну с MVC уже все ясно, об этом я уже давно писал, ничего не изменилось, только усугубилось, стоит набрать в Google Images «mvc» и мы увидим страшное, стрелочки в любые стороны. Ну а про REST отвечают следующее: ну как же, нам нужно из браузерного GUI и мобильного приложения вызывать серверные методы, например: setUserCity(userId, cityId) или calculateMatrix(data) или startVideoConverter(options, source, destination) а потом мы столкнемся с большой нагрузкой и архитектура REST все решит. Дальше я задаю вопросы, от которых глаза округляются уже у тех, кто недавно еще горел праведной верой, рвался в бой и точно знал, что к чему в этом мире. Теперь можно перейти к рассмотрению терминологической катастрофы, в эпицентре которой мы с вами пребываем.
          Читать дальше →
        • NFX — Ультраэффективная Бинарная Сериализация в CLR

            Требования


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

            • самозацикленные графы объектов (деревья с back-references)
            • массивы структур (value types)
            • классы/структуры с readonly полями
            • инстансы существующих .Net коллекций (Dictionary, List), которые внутренне используют custom-сериализацию
            • большое кол-во инстансов типов, специализированных для конкретной задачи


            Речь пойдёт о трёх аспектах, которые очень важны в распределённых кластерных системах:

            • скорость сериализации/десериализации
            • объём объектов в сериализированном виде
            • возможность использовать существующие объекты без надобности “украшения” этих объектов и их полей вспомогательными атрибутами для сериализации

            Читать дальше →
          • Храним 300 миллионов объектов в CLR процессе

              Камень преткновения — GC


              Все managed языки такие как Java или C# имеют один существенный недостаток — безусловное автоматическое управление паматью. Казалось бы, именно это и является преимуществом managed языков. Помните, как мы барахтались с dandling-указателями, не понимая, куда утекают драгоценные 10KB в час, заставляя рестартать наш любимый сервер раз в сутки? Конечно, Java и C# (и иже с ними) на первый взгляд разруливают ситуацию в 99% случаев.

              Так-то оно так, только вот есть одна проблемка: как быть с большим кол-вом объектов, ведь в том же .Net никакой магии нет. CLR должен сканировать огромный set объектов и их взаимных ссылок. Это проблема частично решается путём введения поколений. Исходя из того, что большинство объектов живёт недолго, мы высвобождаем их быстрее и поэтому не надо каждый раз ходить по всем объектам хипа.

              Но проблема всё равно есть в тех случаях, когда объекты должны жить долго. Например, кэш. В нём должны находиться миллионы объектов. Особенно, учитывая возрастание объемов оперативки на типичном современном серваке. Получается, что в кэше потенциально можно хранить сотни миллионов бизнес-объектов (например, Person с дюжиной полей) на машине с 64GB памяти.

              Однако на практике это сделать не удаётся. Как только мы добавляем первые 10 миллионов объектов и они “устаревают” из первого поколения во второе, то очередной полный GC-scan “завешивает” процесс на 8-12 секунд, причём эта пауза неизбежна, т.е. мы уже находимся в режиме background server GC и это только время “stop-the-world”. Это приводит к тому, что серверная апликуха просто “умирает” на 10 секунд. Более того, предсказать момент “клинической смерти” практически невозможно.
              Что же делать? Не хранить много объектов долго?

              Зачем


              Но мне НУЖНО хранить очень много объектов долго в конкретной задаче. Вот например, я храню network из 200 миллионов улиц и их взаимосвязей. После загрузки из flat файла моё приложение должно просчитать коэффициенты вероятностей. Это занимает время. Поэтому я это делаю сразу по мере загрузки данных с диска в память. После этого мне нужно иметь object-graph, который уже прекалькулирован и готов “к труду и обороне”. Короче, мне нужно хранить резидентно около 48GB данных в течении нескольких недель при этом отвечаю на сотни запросов в секунду.

              Вот другая задача. Кэширование социальных данных, которых скапливаются сотни миллионов за 2-3 недели, а обслуживать необходимо десятки тысяч read-запросов в секунду.
              Читать дальше →