Приклади коду з літньої школи з Node.js і JavaScript в КПІ

Товариші інженери, доповідаю вам про успіхи у підготовці науково-технічних кадрів в галузі програмної інженерії в Київському політехнічному інституті і публікую цікаві приклади коду, які були написані для навчального курсу, але, сподіваюся, цікаві і з практичної точки зору. Ідея, впровадити JavaScript і Node.js в навчальний процес, визрівала у мене вже кілька років. Але для освоєння базових речей у програмуванні мені більше подобається C, щоб люди відчули машину, навчилися контролювати себе і свій код. А ось для прикладних задач, у яких рівень абстракції C вже не достатньо иллюстративен, мультипарадигменный і гнучкий JavaScript прижився. Разом з потужним і простим API Node.js, писати концептуальний код прямо на парі, виявилося дуже зручно. Крім того, знання JavaScript обов'язково стануть в нагоді на практиці будь-якому інженеру, який працює в ІТ. Частину коду, розробленого студентами курсу, вже потрапила в серйозні Open Source проекти і це прекрасна практика, яку може повторити кожен, адже лабораторні роботи ми поступово викладаємо на github і будемо робити це й надалі, забезпечуючи їх методичними вказівками і не піклуючись про те, що студенти будуть списувати з форков, адже все це потрібно в першу чергу їм самим. Приклади я ще раз розкласти по поличках на літній школі, яка проходить з 9 по 26 серпня 2016 року в Києві, і розклад якої можна знайти тут. Отже, переходимо до найбільш показовим прикладів коду.
Приклад №1. Живі таблиці
Написання щось на подобу живих таблиць Google Spreadsheets з гуглдоксов, може надихнути навіть двієчника. Нехай це буде маленька електронна таблиця 6x5, але у неї може зайти кілька людей і введені ними дані будуть синхронізуватися по мережі в реальному часі. Це наочно, ефектно і застосовується на практиці. Крім того, в цьому завданні приховані додаткові теми, застосування WebSocket і EventEmitter, написати просту реалізацію самостійно, розширити можливості EventEmitter для підписки на всі події. Основна задача цієї роботи, розрахованої на 1 лекцію і 2 практики, це освоїти подієву реактивну модель обчислень, замість проходу по циклу і трансляцію подій по мережі.
Починати можна вже не з нуля, базовий код сервера 41 рядок, і 53 рядка клієнт написаний і викладений разом із завданням на гітхабі: https://github.com/HowProgrammingWorks/EventDrivenProgramming
Приклад №2. Розподілені обчислення
Як захопити студентів розподіленими обчисленнями? Я думаю, що їм просто треба дати щось просте, що вони зможуть реалізувати за одну-дві пари. Ні хто, звичайно, в здоровому глузді не буде писати великих обчислювальних задач на Node.js, але він дуже короткий і показовий у тому сенсі, що JavaScript має однопоточную модель виконання. Ми можемо наочно розпаралелити обчислення, перевівши їх в асинхронну парадигму і розподіливши між кількома процесами. Для цього пропонується перейти від циклів до итераторам. У цьому разі зникають змінні циклів і стан, тобто вихідний набір даних вже можна різати і передавати в різні процеси. Це підходить для задач, в яких послідовність обробки елементів набору даних не важлива, а таких завдань дуже багато. Крім того, ітератори можна перевизначити, перехопити або написати свої. Ми можемо реалізувати межпроцессовое взаємодія і мережевий обмін, приховавши це за абстракцією ітератора. Прикладної код не зміниться, тільки реалізація ітератора буде різати завдання на частини, зберігати у себе індекси частин, а потім, при отриманні результатів (нехай навіть в іншому порядку), їх можна буде склеїти в потрібній послідовності.
теж можна Починати не з нуля, є заготовки коду на гітхабі https://github.com/HowProgrammingWorks/InterProcessCommunication містять два варіанти обміну між процесами: через IPC (вбудований в операційну систему і має обгортку в Node.js API) і через TCP сокетів. Останній можна застосовувати не тільки для розпаралелювання в межах одного сервера, але і для побудови кластера з декількох багатоядерних серверів.
Цю задачу можна розвивати як завгодно довго, якщо студенту мало і у нього є здібності і бажання копнути глибше, то він може написати менеджер ресурсів для обчислювального кластера, в якому буде тримати стан кожного обчислювального процесу і розподіляти обчислювальні завдання на вільні ресурси чи взагалі, пропорційно їх продуктивності. Можна збирати статистику про продуктивності для різних завдань і оптимізувати балансування навантаження. Можна реалізувати обчислення на сервері, а запити слати з багатьох клієнтів, а можна, навпаки, мати багато воркеров і слати їм запити з одного майстра. Можна навіть зробити брокер запитів, тоді у нас виходить один TCP сервер, який має два типи клієнтів: замовник і виконавець. Замовники надсилають завдання, а брокер (сервер) розподіляє їх на виконавців, потім збирає з них частини рішення і надсилає замовникам об'єднані рішення.
Приклад №3. Пісочниці, інверсія управління та впровадження залежностей
Ще одна важлива тема, це екранування прикладного коду в пісочницях. У цьому сенсі Node.js дає нам доступ до API віртуальної машини V8 і це дозволяє створювати контексти виконання коду динамічно. Пісочниці мають свій глобальний контекст і зовсім не мають доступу до головного глобального контексту програми, якщо ми спеціально не пробросим в них посилання на ті чи інші об'єкти. Завдяки цьому ми можемо продемонструвати принципи інверсії управління та впровадження залежностей для модулів, а не тільки для класів. Ми можемо взяти посилання на об'єкт або функцію з однієї пісочниці, і впровадити її в іншу пісочницю. Можемо обернути будь API в пісочниці, додавши в його поведінка логування, заміри швидкості, розподілені обчислення, функції безпеки і що завгодно. Пісочниці, це одна з найбільш потужних можливостей ноди, але, на жаль, поки мало використовується в прикладних програмах.
Взагалі кажучи, управління залежностями в ноді з коробки таке собі, все робиться через DL (dependency lookup), реалізацією якого і є горезвісний require. Це спосіб, при якому модулі самі подгружают в свій контекст інші модулі, вказуючи повний шлях до файлу або ім'я модуля в репозиторії npm. При цьому, завантажувані модулі отримують повний доступ до глобального контексту програми і можуть змінити в ньому що завгодно, наприклад, видалить setTimeout, перевизначити метод Array.prototype.forEach() або замінити require своєю функцією. Взагалі, бібліотеки JavaScript часто модифікують базові класи мови і це призводить до конфліктів коду. Від цього немає порятунку, крім як запускати конфліктуючий код в пісочницях і реалізувати екранування, а залежно впроваджувати основного додатки, створюючи посилання на них у глобальному контексті пісочниць.
Краще всього перейти до зовнішнього декларативним опису залежностей, на подобу того, що ми маємо в package.json. Але require в ноді дублює в імперативному стилі, то декларативне опис, що міститься в package.json. У великих проектах часто трапляється, що два різних компонента залежать від різних версій однієї бібліотеки (це жахливо звичайно, але як є), а в package.json можна описати тільки одну. Оформляти всі ці компоненти як окремі npm пакети і піднімати свій npm сервер або викладати їх в приватний репозиторій, можна звичайно. Але значно гарніше вирішити відразу два завдання за допомогою пісочниць та впровадження залежностей. Головний модуль може вважати файл опису залежностей і довантажити потрібні версії залежностей потрібні пісочниці, одночасно захищаючи їх контексти.
Посилання на репозиторій https://github.com/HowProgrammingWorks/InterProcessCommunication і в ньому є 3 папки:
  • sandboxedModule — це про використання пісочниць
  • interfaceWrapper — про обгортку інтерфейсів
  • dependencyInjection — про впровадження залежностей
Посилання
Висновок
наступного разу я покажу ще більше прикладів коду з наших лабораторних робіт, наприклад: веб-чат через вебсокеты, практичне застосування метапрограммирования, розширюваний HTTP сервер для старого веба, асинхронна композиція функцій, підвищення рівня абстракції коду, розробка спеціалізованих протоколів, сериализаторов і серверів на базі TCP і UDP, синхронізація каталогів мережі, побудова DSL мов, наприклад, мови запитів до структур даних в оперативній пам'яті і т. д. Спасибі за Вашу увагу.
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.