Javascript-форум (https://javascript.ru/forum/)
-   Ваши сайты и скрипты (https://javascript.ru/forum/project/)
-   -   Collection v5 (https://javascript.ru/forum/project/47717-collection-v5.html)

kobezzza 25.07.2014 14:11

Хорошо подумав, решил отказаться от концепции iterations, а вычислять время активной операции на каждой итерации и прерывания будут разруливаться автоматически планировщиком. Каждой задаче можно будет задать приоритет.

Т.е. можно будет просто делать вызов $C и не думать, что он-что то там залочит.

$C(...).forEach(() => {
    ...
}, {worker: true})

$C(...).forEach(() => {
    ...
}, {worker: true})

$C(...).forEach(() => {
    ...
}, {worker: true})

$C(...).forEach(() => {
    ...
}, {worker: true})

... over 9000 операций


Количество активных операций и сами операции будит рулить планировщик, т.е. программисту об этом думать не нужно. Интерфейс обратного вызова будет спроектирован для совместной работы Promise и Async.

Самое приятное, что обновлённый движок Collection 5 позволит очень просто реализовать такую фичу с помощью оператора yield и у нас будет реальная альтернатива "тяжёлым потокам".

melky 25.07.2014 14:16

как изнутри планируешь это делать? nextTick ?

kobezzza 25.07.2014 14:25

Цитата:

Сообщение от melky (Сообщение 322732)
как изнутри планируешь это делать? nextTick ?

Для node - setImmediate. nextTick всегда добавляет операции в конец текущей итерации событийного цикла, а setImmediate переносит на следующий (в node 0.8 nextTick работал как setImmediate, но в node 0.10 это поведение изменили, а старый функционал вынесли в setImmediate).

Для браузера - setTimeout / setImmediate.

Сейчас алгоритм примерно такой планируется: планировщик следит, чтобы все worker операции $C не занимали более 80мс в одном итерационном цикле. По умолчанию у всех операций будет одинаковый приоритет, но его можно будет указывать явно.

kobezzza 20.08.2014 19:21

Сегодня написал первую тестовую версию реализации "лёгких потоков" на основе прерываний (yield) и планировщика с системой приоритетов.

Видео
Одновременно создаётся 50 forEach, в каждом по 1кк итераций и рандомно задаются приоритеты, т.е. общее количество итераций 50кк. Интерфейс не лочится и тормозов нет в принципе, результатом очень доволен. Думаю завтра / послезавтра зарелизю 5.2 версию с поддержкой.

Плюсы лёгкий потоков:
1) Нет затрат на создание;
2) Т.к. всё крутится в рамках главного потока, то прямой доступ к DOM и переменным замыкания (но тут нужно быть аккуратным, ибо моно выстрелить себе в ногу :));
3) Нет ограничений на количество создаваемых потоков (вернее есть, но равно количеству доступной памяти)

Минусы:
1) Требуется поддержка генераторов, т.е. пока работает только в ФФ, Хроме и компании, Ноде. В ИЕ ожидается с 12-й версии.
2) Теоретически возможно залочить поток, если сама итерация в цикле будет очень тяжёлой.

Алгоритм:

В рамках одной итерации событийного цикла JS все асинхронные процессы Collection могут забрать не более 60мс времени суммарно. У каждой задачи есть приоритет (по умолчанию normal)

var maxPriority = 40;
var priority = {
	'low'     : maxPriority / 8,
	'normal'  : maxPriority / 4,
	'hight'   : maxPriority / 2,
	'critical': maxPriority
};


Чем выше приоритет, тем выше вероятность, что данная задача попадёт в исполнение конкретного событийного цикла (но не 100%). Задачи с одинаковым приоритетом выбираются случайно с линейным распределением.

Определение выполняемых задач осуществляется на каждой итерации событийного цикла.

PS: цифорки на видео - это количество выделенных на операцию итераций событийного цикла.

kobezzza 21.08.2014 15:31

Пописав день с лёгкими тредами, я уже не понимаю, как я жил без них - это просто чудо!)

kobezzza 21.08.2014 20:01

Продумываю API вложенных потоков (т.е. поток созданный внутри потока).

Концепт такой:

$C(...).forEach(function (el) {
    // Метод wait приостановит выполнение родительского потока,
    // пока не выполнится дочерний и в качестве ответа вернёт результат работы дочернего потока
    this.wait($C(el).forEach(function () {
        ...
    }, {thread: true}));
}, {thread: true});


Также решил добавить метод .sleep который имеет следующий интерфейс:

sleep(time, opt_test, opt_interval)


*) время в мс
*) функция-проверка, если вернёт true, то поток "проснётся"
*) если true и opt_test вернёт false, то проверка будет проводится каждые time пока поток не проснётся

MallSerg 21.08.2014 21:01

Любопытно а зачем это?
кто и где это использует?

kobezzza 21.08.2014 21:22

Цитата:

Сообщение от MallSerg (Сообщение 326937)
Любопытно а зачем это?
кто и где это использует?

Что именно зачем? Потоки? Это настолько очевидно, что я даже не знаю что и написать :)

Что касается плюсов / минусов перед тяжелыми потоками, то я писал выше.

MallSerg 21.08.2014 22:09

Я не в курсе, то что такое Collection.
мне просто любопытно посмотреть на реальный пример где это может использоваться.
Прочитав описание я так и не придумал где(на каком реальном примере) это можно использовать ((

kobezzza 21.08.2014 22:16

Ну дык:

https://github.com/kobezzza/Collection/wiki
https://github.com/kobezzza/Collecti...-Collection%3F


Часовой пояс GMT +3, время: 02:48.