Хорошо подумав, решил отказаться от концепции 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 и у нас будет реальная альтернатива "тяжёлым потокам". |
как изнутри планируешь это делать? nextTick ?
|
Цитата:
Для браузера - setTimeout / setImmediate. Сейчас алгоритм примерно такой планируется: планировщик следит, чтобы все worker операции $C не занимали более 80мс в одном итерационном цикле. По умолчанию у всех операций будет одинаковый приоритет, но его можно будет указывать явно. |
Сегодня написал первую тестовую версию реализации "лёгких потоков" на основе прерываний (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: цифорки на видео - это количество выделенных на операцию итераций событийного цикла. |
Пописав день с лёгкими тредами, я уже не понимаю, как я жил без них - это просто чудо!)
|
Продумываю 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 пока поток не проснётся |
Любопытно а зачем это?
кто и где это использует? |
Цитата:
Что касается плюсов / минусов перед тяжелыми потоками, то я писал выше. |
Я не в курсе, то что такое Collection.
мне просто любопытно посмотреть на реальный пример где это может использоваться. Прочитав описание я так и не придумал где(на каком реальном примере) это можно использовать (( |
|
Часовой пояс GMT +3, время: 02:48. |