const fs = require('fs'); const compose = (...funcs) => x => funcs.
reduce((x, fn) => fn(x), x); const DENSITY_COL = 3; const renderTab
table => { const cellWidth = [18, 10, 8, 8, 18, 6]; return table.ma
=> (row.map((cell, i) => { const width = cellWidth[i]; return i ? c
toString().padStart(width) : cell.padEnd(width); }).join(''))).join
}; const proportion = (max, val) => Math.round(val * 100 / max); co
calcProportion = table => { table.sort((row1, row2) => row2[DENSITY
row1[DENSITY_COL]); const maxDensity = table[0][DENSITY_COL]; table
forEach(row => { row.push(proportion(maxDensity, row[DENSITY_COL]))
return table; }; const getDataset = file => { const lines = fs.read
FileSync(file, 'utf8').toString().split('n'); lines.shift(); lines
return lines.map(line => line.split(',')); }; const main = compose
(getDataset, calcProportion, renderTable); const fs = require('fs'
compose = (...funcs) => x => funcs.reduce((x, fn) => fn(x), x); con
DENSITY_COL = 3; const renderTable = table => { const cellWidth = [
8, 8, 18, 6]; return table.map(row => (row.map((cell, i) => { const
= cellWidth[i]; return i ? cell.toString().padStart(width) : cell.p
(width); }).join(''))).join('n'); }; const proportion = (max, val)
Node.js в 2019 году
(состояние и перспективы)
Тимур Шемсединов
github.com/HowProgrammingWorks
github.com/tshemsedinov
Chief Software Architect at Metarhia
Lecturer at Kiev Polytechnic Institute
const fs = require('fs'); const compose = (...funcs) => x => funcs.
reduce((x, fn) => fn(x), x); const DENSITY_COL = 3; const renderTab
table => { const cellWidth = [18, 10, 8, 8, 18, 6]; return table.ma
=> (row.map((cell, i) => { const width = cellWidth[i]; return i ? c
Node.js уже 10 лет: v0.0.1 — 27 мая 2019
Версии 0.10.x и 0.12.x — (2013 - 2016)
Форк Io.js 1.x, 2.x, 3.x — (2014 - 2015)
Argon 4.x (2015 - 2018), 5.x (2015 - 2016),
Boron 6.x (2016 - 2019), 7.x (2016 - 2017),
Carbon 8.x (2017 - 2019), 9.x (2017 - 2018),
Dubnium 10.x (2018 - 2021),11.x (2018 - 2019),
Erbium 12.x (2019 - 2022)
const fs = require('fs'); const compose = (...funcs) => x => funcs.
reduce((x, fn) => fn(x), x); const DENSITY_COL = 3; const renderTab
table => { const cellWidth = [18, 10, 8, 8, 18, 6]; return table.ma
=> (row.map((cell, i) => { const width = cellWidth[i]; return i ? c
Node.js features
8.x V8 6.0, async/await, TurboFan and Ignition
10.x V8 6.6, HTTP/2, fs.promises, BigInt, npm 6
12.x V8 7.4, TLS 1.3, OpenSSL 1.1.1c, npm 6.10.3
новое в js: #, async/await, async stack,
динамическая куча, llhttp и llparser,
threads, безопасность: DOS в HTTP/2,
startup, diagnostic, рекурсивный fs.rmdir
const fs = require('fs'); const compose = (...funcs) => x => funcs.
reduce((x, fn) => fn(x), x); const DENSITY_COL = 3; const renderTab
table => { const cellWidth = [18, 10, 8, 8, 18, 6]; return table.ma
=> (row.map((cell, i) => { const width = cellWidth[i]; return i ? c
Shared memory and Atomics
Появилось в Node.js 9
■ SharedArrayBuffer
■ Atomics
○ add, sub, and, or, xor
○ store, load, exchange, compareExchange
○ notify, wait, wake (deprecated)
const fs = require('fs'); const compose = (...funcs) => x => funcs.
reduce((x, fn) => fn(x), x); const DENSITY_COL = 3; const renderTab
table => { const cellWidth = [18, 10, 8, 8, 18, 6]; return table.ma
=> (row.map((cell, i) => { const width = cellWidth[i]; return i ? c
Threads vs Processes
process process
JavaScript
thread
V8libuv
node.js
JavaScript
thread
V8 libuv
node.js
JavaScript
thread
V8 libuv
node.js
IPC
const fs = require('fs'); const compose = (...funcs) => x => funcs.
reduce((x, fn) => fn(x), x); const DENSITY_COL = 3; const renderTab
table => { const cellWidth = [18, 10, 8, 8, 18, 6]; return table.ma
=> (row.map((cell, i) => { const width = cellWidth[i]; return i ? c
Why Isolation?
● Ошибки
● Утечки памяти и других ресурсов
● Приложение: данные, соединения с БД
● Файловая система и корневой каталог
● Окружение ОС, PID, IPC
● Безопасность ОС: пользователи, группы
● Сеть: дескрипторы сокетов, порты, хосты
const fs = require('fs'); const compose = (...funcs) => x => funcs.
reduce((x, fn) => fn(x), x); const DENSITY_COL = 3; const renderTab
table => { const cellWidth = [18, 10, 8, 8, 18, 6]; return table.ma
=> (row.map((cell, i) => { const width = cellWidth[i]; return i ? c
Execution Strategy Problems
● Недостаточная изоляция исполнения
запросов к серверу друг от друга
● Один неудачный запрос может убить все
параллельно исполняемые
● В асинхронной среде сложно найти и
связать ошибку с запросом
● Изоляция приложений и организаций в SaaS
const fs = require('fs'); const compose = (...funcs) => x => funcs.
reduce((x, fn) => fn(x), x); const DENSITY_COL = 3; const renderTab
table => { const cellWidth = [18, 10, 8, 8, 18, 6]; return table.ma
=> (row.map((cell, i) => { const width = cellWidth[i]; return i ? c
Execution Isolation
● VPS (виртуальная машина)
● Контейнер (Docker)
● Провесс (node)
● Поток (встроенный модуль worker_threads)
● Песочница (vm.createContext, vm.Script)
● Программная абстракция
(объект или замыкание)
const fs = require('fs'); const compose = (...funcs) => x => funcs.
reduce((x, fn) => fn(x), x); const DENSITY_COL = 3; const renderTab
table => { const cellWidth = [18, 10, 8, 8, 18, 6]; return table.ma
=> (row.map((cell, i) => { const width = cellWidth[i]; return i ? c
Execution Strategy
● 1 процесс, 1 поток JS, 1 запрос в потоке
● 1 процесс, 1 поток JS, N запросов в нем
● 1 процесс, N потоков JS, 1 запрос в каждом
● 1 процесс, N потоков JS, N запрос в каждом
● N процессов, 1 поток JS, 1 запрос в каждом
● N процессов, 1 поток, N запросов в каждом
● N процессов, N потоков, 1 запрос в каждом
● N процессов, N потоков, N запрос в каждом
const fs = require('fs'); const compose = (...funcs) => x => funcs.
reduce((x, fn) => fn(x), x); const DENSITY_COL = 3; const renderTab
table => { const cellWidth = [18, 10, 8, 8, 18, 6]; return table.ma
=> (row.map((cell, i) => { const width = cellWidth[i]; return i ? c
Execution Strategy
● 1 процесс, 1 поток JS, 1 запрос в потоке
● 1 процесс, 1 поток JS, N запросов в нем
● 1 процесс, N потоков JS, 1 запрос в каждом
● 1 процесс, N потоков JS, N запрос в каждом
● N процессов, 1 поток JS, 1 запрос в каждом
● N процессов, 1 поток, N запросов в каждом
● N процессов, N потоков, 1 запрос в каждом
● N процессов, N потоков, N запрос в каждом
const fs = require('fs'); const compose = (...funcs) => x => funcs.
reduce((x, fn) => fn(x), x); const DENSITY_COL = 3; const renderTab
table => { const cellWidth = [18, 10, 8, 8, 18, 6]; return table.ma
=> (row.map((cell, i) => { const width = cellWidth[i]; return i ? c
Часто применяется для
Локальные приложения
● Сборщики и трансляторы для фронт-энда
● Пакетная и отложенная обработка
● Скрипты, сценарии, CLI
● Генерация документации, отложенное
формирование отчетов
● Сценарии тестирования для других систем
const fs = require('fs'); const compose = (...funcs) => x => funcs.
reduce((x, fn) => fn(x), x); const DENSITY_COL = 3; const renderTab
table => { const cellWidth = [18, 10, 8, 8, 18, 6]; return table.ma
=> (row.map((cell, i) => { const width = cellWidth[i]; return i ? c
Часто применяется для
Серверы:
● Серверы веб-приложений и SPA
● Серверы и API для мобильных приложений
● Любые другие веб-API (RPC, REST)
● Серверы событий (чаты, игры, интерактив)
● Заплаты на уже готовые системы
● Приложения баз данных и корпоративные
const fs = require('fs'); const compose = (...funcs) => x => funcs.
reduce((x, fn) => fn(x), x); const DENSITY_COL = 3; const renderTab
table => { const cellWidth = [18, 10, 8, 8, 18, 6]; return table.ma
=> (row.map((cell, i) => { const width = cellWidth[i]; return i ? c
Часто применяется для
Клиенты:
● Оконные приложения (Electron, nw.js)
● Кравлеры, парсеры и сбор данных
● Агенты и демоны (мониторинг, обновление)
● Обработка и трансляция видео и звука
const fs = require('fs'); const compose = (...funcs) => x => funcs.
reduce((x, fn) => fn(x), x); const DENSITY_COL = 3; const renderTab
table => { const cellWidth = [18, 10, 8, 8, 18, 6]; return table.ma
=> (row.map((cell, i) => { const width = cellWidth[i]; return i ? c
Часто применяется для
Железо:
● Промышленная автоматизация
● Программирование микроконтроллеров
(arduino, espruino, tessel)
● Интернет вещей
const fs = require('fs'); const compose = (...funcs) => x => funcs.
reduce((x, fn) => fn(x), x); const DENSITY_COL = 3; const renderTab
table => { const cellWidth = [18, 10, 8, 8, 18, 6]; return table.ma
=> (row.map((cell, i) => { const width = cellWidth[i]; return i ? c
Редко применяется
Редко применяется (но подходит) для:
● CMS, публикация контента (ниша занята)
● Массовая электронная коммерция и
торговля (только как часть решения)
● CRM, ERP, SCM системы
● Искусственный интеллект (до недавнего
времени) https://www.tensorflow.org/js
const fs = require('fs'); const compose = (...funcs) => x => funcs.
reduce((x, fn) => fn(x), x); const DENSITY_COL = 3; const renderTab
table => { const cellWidth = [18, 10, 8, 8, 18, 6]; return table.ma
=> (row.map((cell, i) => { const width = cellWidth[i]; return i ? c
Плохо подходит
● Вычисления
● Математическое моделирование
● Научные приложения
Хотя, хорошо оптимизированный JavaScript
может быть всего в 2 раза медленнее C++
const fs = require('fs'); const compose = (...funcs) => x => funcs.
reduce((x, fn) => fn(x), x); const DENSITY_COL = 3; const renderTab
table => { const cellWidth = [18, 10, 8, 8, 18, 6]; return table.ma
=> (row.map((cell, i) => { const width = cellWidth[i]; return i ? c
Deno
● Безопасность:
файловая система,сеть, окружение
● V8, TypeScript
● Rust вместо C++
● Tokio (event loop, I/O scheduler)
● Встроенный менеджер пакетов
const fs = require('fs'); const compose = (...funcs) => x => funcs.
reduce((x, fn) => fn(x), x); const DENSITY_COL = 3; const renderTab
table => { const cellWidth = [18, 10, 8, 8, 18, 6]; return table.ma
=> (row.map((cell, i) => { const width = cellWidth[i]; return i ? c
Links
Node https://bit.ly/2lFgqSN (видео)
https://node.green/
https://nodejs.org/api/worker_threads.html
JS https://wicg.github.io/web-locks
Deno https://github.com/denoland/deno
https://youtu.be/z6JRlx5NC9E
const fs = require('fs'); const compose = (...funcs) => x => funcs.
reduce((x, fn) => fn(x), x); const DENSITY_COL = 3; const renderTab
table => { const cellWidth = [18, 10, 8, 8, 18, 6]; return table.ma
=> (row.map((cell, i) => { const width = cellWidth[i]; return i ? c
Node.js
Перспективы платформы
Ответы на вопросы

Node.js in 2019

  • 1.
    const fs =require('fs'); const compose = (...funcs) => x => funcs. reduce((x, fn) => fn(x), x); const DENSITY_COL = 3; const renderTab table => { const cellWidth = [18, 10, 8, 8, 18, 6]; return table.ma => (row.map((cell, i) => { const width = cellWidth[i]; return i ? c toString().padStart(width) : cell.padEnd(width); }).join(''))).join }; const proportion = (max, val) => Math.round(val * 100 / max); co calcProportion = table => { table.sort((row1, row2) => row2[DENSITY row1[DENSITY_COL]); const maxDensity = table[0][DENSITY_COL]; table forEach(row => { row.push(proportion(maxDensity, row[DENSITY_COL])) return table; }; const getDataset = file => { const lines = fs.read FileSync(file, 'utf8').toString().split('n'); lines.shift(); lines return lines.map(line => line.split(',')); }; const main = compose (getDataset, calcProportion, renderTable); const fs = require('fs' compose = (...funcs) => x => funcs.reduce((x, fn) => fn(x), x); con DENSITY_COL = 3; const renderTable = table => { const cellWidth = [ 8, 8, 18, 6]; return table.map(row => (row.map((cell, i) => { const = cellWidth[i]; return i ? cell.toString().padStart(width) : cell.p (width); }).join(''))).join('n'); }; const proportion = (max, val) Node.js в 2019 году (состояние и перспективы) Тимур Шемсединов github.com/HowProgrammingWorks github.com/tshemsedinov Chief Software Architect at Metarhia Lecturer at Kiev Polytechnic Institute
  • 2.
    const fs =require('fs'); const compose = (...funcs) => x => funcs. reduce((x, fn) => fn(x), x); const DENSITY_COL = 3; const renderTab table => { const cellWidth = [18, 10, 8, 8, 18, 6]; return table.ma => (row.map((cell, i) => { const width = cellWidth[i]; return i ? c Node.js уже 10 лет: v0.0.1 — 27 мая 2019 Версии 0.10.x и 0.12.x — (2013 - 2016) Форк Io.js 1.x, 2.x, 3.x — (2014 - 2015) Argon 4.x (2015 - 2018), 5.x (2015 - 2016), Boron 6.x (2016 - 2019), 7.x (2016 - 2017), Carbon 8.x (2017 - 2019), 9.x (2017 - 2018), Dubnium 10.x (2018 - 2021),11.x (2018 - 2019), Erbium 12.x (2019 - 2022)
  • 3.
    const fs =require('fs'); const compose = (...funcs) => x => funcs. reduce((x, fn) => fn(x), x); const DENSITY_COL = 3; const renderTab table => { const cellWidth = [18, 10, 8, 8, 18, 6]; return table.ma => (row.map((cell, i) => { const width = cellWidth[i]; return i ? c Node.js features 8.x V8 6.0, async/await, TurboFan and Ignition 10.x V8 6.6, HTTP/2, fs.promises, BigInt, npm 6 12.x V8 7.4, TLS 1.3, OpenSSL 1.1.1c, npm 6.10.3 новое в js: #, async/await, async stack, динамическая куча, llhttp и llparser, threads, безопасность: DOS в HTTP/2, startup, diagnostic, рекурсивный fs.rmdir
  • 4.
    const fs =require('fs'); const compose = (...funcs) => x => funcs. reduce((x, fn) => fn(x), x); const DENSITY_COL = 3; const renderTab table => { const cellWidth = [18, 10, 8, 8, 18, 6]; return table.ma => (row.map((cell, i) => { const width = cellWidth[i]; return i ? c Shared memory and Atomics Появилось в Node.js 9 ■ SharedArrayBuffer ■ Atomics ○ add, sub, and, or, xor ○ store, load, exchange, compareExchange ○ notify, wait, wake (deprecated)
  • 5.
    const fs =require('fs'); const compose = (...funcs) => x => funcs. reduce((x, fn) => fn(x), x); const DENSITY_COL = 3; const renderTab table => { const cellWidth = [18, 10, 8, 8, 18, 6]; return table.ma => (row.map((cell, i) => { const width = cellWidth[i]; return i ? c Threads vs Processes process process JavaScript thread V8libuv node.js JavaScript thread V8 libuv node.js JavaScript thread V8 libuv node.js IPC
  • 6.
    const fs =require('fs'); const compose = (...funcs) => x => funcs. reduce((x, fn) => fn(x), x); const DENSITY_COL = 3; const renderTab table => { const cellWidth = [18, 10, 8, 8, 18, 6]; return table.ma => (row.map((cell, i) => { const width = cellWidth[i]; return i ? c Why Isolation? ● Ошибки ● Утечки памяти и других ресурсов ● Приложение: данные, соединения с БД ● Файловая система и корневой каталог ● Окружение ОС, PID, IPC ● Безопасность ОС: пользователи, группы ● Сеть: дескрипторы сокетов, порты, хосты
  • 7.
    const fs =require('fs'); const compose = (...funcs) => x => funcs. reduce((x, fn) => fn(x), x); const DENSITY_COL = 3; const renderTab table => { const cellWidth = [18, 10, 8, 8, 18, 6]; return table.ma => (row.map((cell, i) => { const width = cellWidth[i]; return i ? c Execution Strategy Problems ● Недостаточная изоляция исполнения запросов к серверу друг от друга ● Один неудачный запрос может убить все параллельно исполняемые ● В асинхронной среде сложно найти и связать ошибку с запросом ● Изоляция приложений и организаций в SaaS
  • 8.
    const fs =require('fs'); const compose = (...funcs) => x => funcs. reduce((x, fn) => fn(x), x); const DENSITY_COL = 3; const renderTab table => { const cellWidth = [18, 10, 8, 8, 18, 6]; return table.ma => (row.map((cell, i) => { const width = cellWidth[i]; return i ? c Execution Isolation ● VPS (виртуальная машина) ● Контейнер (Docker) ● Провесс (node) ● Поток (встроенный модуль worker_threads) ● Песочница (vm.createContext, vm.Script) ● Программная абстракция (объект или замыкание)
  • 9.
    const fs =require('fs'); const compose = (...funcs) => x => funcs. reduce((x, fn) => fn(x), x); const DENSITY_COL = 3; const renderTab table => { const cellWidth = [18, 10, 8, 8, 18, 6]; return table.ma => (row.map((cell, i) => { const width = cellWidth[i]; return i ? c Execution Strategy ● 1 процесс, 1 поток JS, 1 запрос в потоке ● 1 процесс, 1 поток JS, N запросов в нем ● 1 процесс, N потоков JS, 1 запрос в каждом ● 1 процесс, N потоков JS, N запрос в каждом ● N процессов, 1 поток JS, 1 запрос в каждом ● N процессов, 1 поток, N запросов в каждом ● N процессов, N потоков, 1 запрос в каждом ● N процессов, N потоков, N запрос в каждом
  • 10.
    const fs =require('fs'); const compose = (...funcs) => x => funcs. reduce((x, fn) => fn(x), x); const DENSITY_COL = 3; const renderTab table => { const cellWidth = [18, 10, 8, 8, 18, 6]; return table.ma => (row.map((cell, i) => { const width = cellWidth[i]; return i ? c Execution Strategy ● 1 процесс, 1 поток JS, 1 запрос в потоке ● 1 процесс, 1 поток JS, N запросов в нем ● 1 процесс, N потоков JS, 1 запрос в каждом ● 1 процесс, N потоков JS, N запрос в каждом ● N процессов, 1 поток JS, 1 запрос в каждом ● N процессов, 1 поток, N запросов в каждом ● N процессов, N потоков, 1 запрос в каждом ● N процессов, N потоков, N запрос в каждом
  • 11.
    const fs =require('fs'); const compose = (...funcs) => x => funcs. reduce((x, fn) => fn(x), x); const DENSITY_COL = 3; const renderTab table => { const cellWidth = [18, 10, 8, 8, 18, 6]; return table.ma => (row.map((cell, i) => { const width = cellWidth[i]; return i ? c Часто применяется для Локальные приложения ● Сборщики и трансляторы для фронт-энда ● Пакетная и отложенная обработка ● Скрипты, сценарии, CLI ● Генерация документации, отложенное формирование отчетов ● Сценарии тестирования для других систем
  • 12.
    const fs =require('fs'); const compose = (...funcs) => x => funcs. reduce((x, fn) => fn(x), x); const DENSITY_COL = 3; const renderTab table => { const cellWidth = [18, 10, 8, 8, 18, 6]; return table.ma => (row.map((cell, i) => { const width = cellWidth[i]; return i ? c Часто применяется для Серверы: ● Серверы веб-приложений и SPA ● Серверы и API для мобильных приложений ● Любые другие веб-API (RPC, REST) ● Серверы событий (чаты, игры, интерактив) ● Заплаты на уже готовые системы ● Приложения баз данных и корпоративные
  • 13.
    const fs =require('fs'); const compose = (...funcs) => x => funcs. reduce((x, fn) => fn(x), x); const DENSITY_COL = 3; const renderTab table => { const cellWidth = [18, 10, 8, 8, 18, 6]; return table.ma => (row.map((cell, i) => { const width = cellWidth[i]; return i ? c Часто применяется для Клиенты: ● Оконные приложения (Electron, nw.js) ● Кравлеры, парсеры и сбор данных ● Агенты и демоны (мониторинг, обновление) ● Обработка и трансляция видео и звука
  • 14.
    const fs =require('fs'); const compose = (...funcs) => x => funcs. reduce((x, fn) => fn(x), x); const DENSITY_COL = 3; const renderTab table => { const cellWidth = [18, 10, 8, 8, 18, 6]; return table.ma => (row.map((cell, i) => { const width = cellWidth[i]; return i ? c Часто применяется для Железо: ● Промышленная автоматизация ● Программирование микроконтроллеров (arduino, espruino, tessel) ● Интернет вещей
  • 15.
    const fs =require('fs'); const compose = (...funcs) => x => funcs. reduce((x, fn) => fn(x), x); const DENSITY_COL = 3; const renderTab table => { const cellWidth = [18, 10, 8, 8, 18, 6]; return table.ma => (row.map((cell, i) => { const width = cellWidth[i]; return i ? c Редко применяется Редко применяется (но подходит) для: ● CMS, публикация контента (ниша занята) ● Массовая электронная коммерция и торговля (только как часть решения) ● CRM, ERP, SCM системы ● Искусственный интеллект (до недавнего времени) https://www.tensorflow.org/js
  • 16.
    const fs =require('fs'); const compose = (...funcs) => x => funcs. reduce((x, fn) => fn(x), x); const DENSITY_COL = 3; const renderTab table => { const cellWidth = [18, 10, 8, 8, 18, 6]; return table.ma => (row.map((cell, i) => { const width = cellWidth[i]; return i ? c Плохо подходит ● Вычисления ● Математическое моделирование ● Научные приложения Хотя, хорошо оптимизированный JavaScript может быть всего в 2 раза медленнее C++
  • 17.
    const fs =require('fs'); const compose = (...funcs) => x => funcs. reduce((x, fn) => fn(x), x); const DENSITY_COL = 3; const renderTab table => { const cellWidth = [18, 10, 8, 8, 18, 6]; return table.ma => (row.map((cell, i) => { const width = cellWidth[i]; return i ? c Deno ● Безопасность: файловая система,сеть, окружение ● V8, TypeScript ● Rust вместо C++ ● Tokio (event loop, I/O scheduler) ● Встроенный менеджер пакетов
  • 18.
    const fs =require('fs'); const compose = (...funcs) => x => funcs. reduce((x, fn) => fn(x), x); const DENSITY_COL = 3; const renderTab table => { const cellWidth = [18, 10, 8, 8, 18, 6]; return table.ma => (row.map((cell, i) => { const width = cellWidth[i]; return i ? c Links Node https://bit.ly/2lFgqSN (видео) https://node.green/ https://nodejs.org/api/worker_threads.html JS https://wicg.github.io/web-locks Deno https://github.com/denoland/deno https://youtu.be/z6JRlx5NC9E
  • 19.
    const fs =require('fs'); const compose = (...funcs) => x => funcs. reduce((x, fn) => fn(x), x); const DENSITY_COL = 3; const renderTab table => { const cellWidth = [18, 10, 8, 8, 18, 6]; return table.ma => (row.map((cell, i) => { const width = cellWidth[i]; return i ? c Node.js Перспективы платформы Ответы на вопросы