g
да
l
Чтобы чат совсем уж не загрязнять - давайте тут. Проект довольно живой, то там то там нужны расчеты - в воркер я думаю будет не удобно
А как скомпилить kotlin-js в js с учетом того, что common скомпилен в wasm?
Ведь, насколько я понимаю, когда kotlin-js компилится в js, то он с собой (в себя) забирает и kotlin-common, так?
g
тут же больше речь не в удобстве, можно достаточно удобное API реализовать на основе Promise для webworker, вопрос имеет ли смысл эти расчеты переносить фон, если это большие куски вычислений, то должно помочь, а если очень много мелких, то может оказаться что накладные расходы больше
А как скомпилить kotlin-js в js с учетом того, что common скомпилен в wasm?
нужно использовать стандартный интероп с wasm
вот так
т.е. там сейчас эдакий “JNI” нужно писать при интеропе js и wasm
еще нужно понимать, что сырой wasm в комбинации с сырым kotlin/native может быть не лучшим сочетанием. Потенциально это конечно очень круто и думаю станет будущим веба во многом, но сейчас, в кратко-срочной перспективе, не факт что усилия окупятся, особенно учитывая что у вас уже есть код для JS Вот писать все на wasm может быть интересной опцией
l
Логики и сущностей много. Лучше все на котлин
В итоге все кроме либ будет на котлин
Собственно из-за этого стало тормозить, и теперь идея или компилить во что то быстрое или применять вебворкер, чтобы логика считалась на другом ядре (насколько я понимаю) или просто всю тяжелую логику перенести в кроссплатформенное приложение а браузер попросить с ним связываться. Сам интерфейс не хочется в приложение совать: у меня карты и всякие анимации - это все довольно хорошо на js работает, и либы js это все могут
Так что пока склоняюсь к последнему варианту. Он безусловно странный
Я думал использовать electron/cordova, но, судя по всему, скорость будет аналогичная js в браузере.
С помощью kotlin наверняка получится создать нативные приложения (скомпилированные нативно jmv-dalvik, swift ios, че там еще виндовое) у которых вместо интерфейса - встроенный браузер (надеюсь хромиум)
Как вам такая идея? @gildor
Я ведь правильно понимаю, что kotlin-common можно будет скомпилировать почти под любую платформу
g
kotlin-common теперь можно скомпилировать в JVM, JS или различные native target, включая wasm, других пока нет
Собственно из-за этого стало тормозить, и теперь идея или компилить во что то быстрое или применять вебворкер
я за вебворкер. Хотя бы будет доступна многопоточность настоящая, хоть и на воркерах
тяжелую логику перенести в кроссплатформенное приложение
Всмысле на сервер?
Я думал использовать electron/cordova, но, судя по всему, скорость будет аналогичная js в браузере.
Та же самая, или даже медленее, так как хром какой нибудь обновляется быстрее электрона
l
Компилится natinve помоему под все распространенное: Windows (x86_64 only at the moment) Linux (x86_64, arm32, MIPS, MIPS little endian) MacOS (x86_64) iOS (arm64 only) Android (arm32 and arm64) WebAssembly (wasm32 only)
g
Ну это все нативные таргеты kotlin/native
там есть и другие и новые будут добавлятся
но все это нативное, это нужно понимать
l
ну... common же скомпилится в это. Или вы что то еще хотите сказать?
g
да, скомпилируется
но так как это все kotlin/native то это все достаточно низкоуровневое
l
Ну и... хорошо.. не?)
Что не так то?
g
смотря для чего)
для UI точно не хоррошо)
а что за кейс, можно узнать? Клиентское приложение?
l
Сек
g
Просто использовать несколько разных уровней (браузер + платформенные api) и объеденять конечно можно, но достаточно запарно
l
Клиентское приложение, активно показывающее сложные карты (куча объектов) + всякие красивые анимации интерфейса. Это все уже есть на js большей частью на kotlin (кроме либ). Это я хотел оставить в браузере или каком то платформенном WebView - потому что готово ну и вообще удобно. Смотрится одинаково. А мозги - компилить нативно. Соединять наитупейшим образом - через сеть. localhost. Если не прокатит - организовать канал передачи от браузера к "локальному серверу", там только строки передавать или бинарники, сойдет я думаю. работа разовая будет.
То есть мозги сайта вынести на сервер, но сам сервер - локально.
g
понятно
l
Что скажете?
g
ну мне кажется воркер может работать не хуже
он же от сервиса ничем не отличается по сути
l
Только в воркере js будет крутиться
g
в плане api, делаешь некий запрос, получаешь ответ, только в рамках одной виртуальной машины
l
про api не понял
g
это да, вопрос насколько критична производительность
понятно js будет медленее скорее всего, но вот насколько?
может просто распаралеливания хватит на все задачи
наврядли у вас там реалтайм процессинг какой то, где голая производительность и летенси критичны
l
Тут вот в чем еще дело... Большая часть работы проходит над здоровой коллекцией данных. Если в json - это мегов 50 будет, не меньше.
Обновления прилетают с основного сервера
И... я как понимаю.. в случае воркера это все надо будет пихать в него строкой (он ведь без состояния или я чет не знаю)?
g
ну можно например в IndexedDB запихать это все
и воркер оттуда данные будет получать
к тому же воркер может сам эти данные с сервиса запросить и в базу сложить
l
ну и получается... что сейчас сервер - логика - сайт логично заменить на сервер - приложение - сайт А не на сервер - сайт - воркер Но, я все же, рассмотрю воркер по подробней.
g
просто держать несколько стеков в одном приложении конечно можно, но звучит как будто это сложнее
ладно в разных, а тут одно приложение
l
Ну и... когда веб сайт пишут - так же.
g
воркер просто способ вынести тяжелые вычисления из UI
но веб сайт не поднимает свой веб сервер что бы к нему отдавать вычисления
т.е. два клиентских стека технологий
есть серверный, есть клиентский
l
Ну... это вопрос местоположения сервера)
g
просто если это настоящий сервер, и общение по сети, то лучше все вынести на сервер, что бы облегчить клиент
l
Низя, куча оффлайн логики
Можно сказать, что должны быть оффлайн предсказания поведения сервера. Что то в этом духе.
Плюс - планируется кроссплатформенное приложение десктопное. Но совсем уже тяжелое. Я хотел одну структуру на все приложения, чтобы можно было код и UI легко перетаскивать
g
ну да, другой вопрос
если нужно оффлайн, то все должно быть на клиенте
ну писать все в common хорошая идея, можно много переиспользовать
но пытаться считать все в wasm надеясь что там будет быстрее идея хорошая, но возможно преждевременная
я там кидал ссылку на то как делать интероп wasm/js, это боль, прям как jni
s
а что говорит профайлер v8?
может быть стоит просто оптимизировать js код? v8 нынче мощная штука, можно добиться очень хорошей производительности
мне кажется что webasm будет выигрывать для совсем уж числодробилок
l
Проблемы начинаются на инициализации - когда прилетает 50 мегабайт данных сериализованных.
s
используется arraybuffer или просто json-ка парсится?
если просто json-ка, то переписывание на бинарные данные с использованием arraybuffer-ов может дать прирост в несколько раз
l
@snrostov Используется kotlin.serialization. Сейчас json, можно переключить на cbor (правда пока только через base64)
Оптимизировать наверняка можно. Но продукт еще развивается и придется часто это делать. Потом код частенько используется и на бэкенде и на фронте, так что оптимизировать прям под конкретный js тоже не всегда удобно.
А реализовать надо в обозримые сроки, именно поэтому я рассматриваю вариант отдельного нативного приложения, потому что оно даст бОльший запас производительности, а затраты на разработку будут единичные - оптимизировать можно будет куда меньше.
g
Нативной приложение конечно скейлится лучше, но оно вот с кроссплатформенным UI проблема
l
браузер
g
Ну так браузер уже не нативное
l
Браузер - не нативное. Браузер - только UI
А мозги - нативно
g
Виртуальная машина внутри нативного приложения в песочнице
Затраты на эти биндинги могут быть выше чем выйгрыш от нативной части
А в чем конкретно проблема с 50мб данных? Что тормозит?
l
Так... только контент передавать
g
Парсинг?
l
Парсинг 50 мегов тормозит Тормозят постоянные пробегания по всем этим коллекциям из 50 мегов. Я не могу их оптимизировать каждый раз, мне надо успевать фичи сдавать.
g
Просто парсинг то без проблем в вебворкер выносится, данные подготавливаются и в IndexedDB в подготовленном виде записываются
И потом запросами в базу получаются. Будет намного быстрее, без лока UI
l
Я не могу воркер запустить как еще одно приложение?
g
Ну парсинг 50 метров данных в классы в UI треде будет тормозить везде
Всмысле?
Воркер и так в отдельном процессе
l
Я не совсем представляю работу с воркером. Погуглю конечно. Как сейчас я понимаю, что воркер это скрипт, которому на вход я дая строку, он сколько то ее там думает и завершается, то есть он скриптовый, предназначен для использования скриптом.
Но при этом остается еще одна задача - "большого" десктопного приложения, где я не совсем уверен что фишки с воркерами могут подойти, хотя наверно таки должны.
Я еще подумаю, спасибо про предложение о воркерах.
g
Нет, о воркер можно просто думать о сервисе
Сам воркер можно заимплиментить просто как отдельный модуль Kotlin/js
Его приложение основное стартует, указывая скрипт (output файл с js этого котлин модуля), и потом его не стопать, просто слать команды, получать результаты
Для простоты имплементации такого запрос/ответ можно что-то вроде promise-worker либу заюзать, можно свою написать, не суть, зависит от кейса
s
promise-worker
а лучше корутины
g
Ну Корутины и так умеют await для Promise
Но да, можно Корутины и без промизов
l
А передача данных в воркер только строкой или можно объекты? Вроде в примерах вижу что объекты
s
ну просто зачем создавать promise, когда можно напрямую корутину пробуждать
А передача данных в воркер только строкой или можно объекты?
можно объекты, но они сериализуются и дессирализуются обратно (автоматический)
передавать без копирования можно только ArrayBuffer-ы и текстуры для WebGl
g
Можно строкой, можно arraybffer
l
Ага, спсб
g
Но для вашего кейса я бы реально просто команды слал, а все данные в базе хранил, раз их много, зачем лезть за каждым мелким куском в воркер
Пусть воркер тяжёлые задачи делает, вроде парсинг и обработки 50мб данных
l
Ок... как думаете, сложности с хранением хдоровых сложных объектов в IndexedDB должны быть?
Может оно там их копирует по двадцать раз или типа того?
Погуглил вебворкеры. Это выглядит как еще один, практически полноценный (без dom) поток для js и этот поток может меняться с основным данными, причем не запрос-ответ - а как заблагорассудится. Как я понял, можно даже setInterval в воркере запустить и он будет "пинать" основной поток каждый n секунд (это я так проверяю что все правильно понял)
Если так, то вместо отдельного приложения, что я хотел писать - я просто сделать то же самое - но в воркере + IndexDB для расшаренных данных, судя по всему, IndexedDB может транзакции.
s
поток может меняться с основным данными, причем не запрос-ответ - а как заблагорассудится
можно обмениваться только сообщениями причем при отправке сообщения серилизуются, а при получении обратно дессирализуются (со всем объектами на которые ссылается исходный). есть ограничения на то какие объекты можно передать. DOM например нельзя. шарить объекты нельзя (но можно шарить ArrayBuffer)
l
Да, я понимаю, что будет сериализация с некоторыми исключениями. Так же можно передавать данные через IndexedDB (типа по старинке)
Я к тому, что после запуска сайта я бы запустил воркер (ы), содержащие все тяжелые мозги (те, что я хотел в нативное приложение сложить). А в основном потоке будет UI, который будет как "тонкий клиент". А все мозги, пробегания по коллекциям, websocket/http/stomp и прочие запросы можно делать из воркера. То есть в воркере же я через websocket получу 50 мегов, там же распарсю и положу в IndexedDB, а потом пну основной поток, типа "готово"
Сейчас ищу, можно ли блокировать поток при записи в IndexedDB или может колбек можно передать, промис... чтобы в коде быть уверенным что в IndexedDB записалось
g
Да, все так
s
Блокировать точно нельзя... Можно сделать промис через отправку сообщения, да (т.е. при получения сообщения “готово” делать promsie.resolve())
g
А зачем его блокировать?
l
Имеется ввиду, что мне после записи в IndexedDB надо точно понимать, что данные записались и основной поток их увидит
g
Так воркер об этом скажет
l
Или блокировка или промис/колбек/четтакое
Воркер?... не
g
Там есть колбек
Ну всмысле воркер запишет, получит колбэк, что все записалось и оповестит ui
l
Все, нашел var request = store.put(userObject); request.onsuccess = funct.. Спасибо
g
Там api на промизах тоже есть вроде
l
Эх... "kotlin indexeddb" - нету(
s
Кстате интересено, дадут ли браузеры записать 50 мб в indexed db
l
А вторую базу низя?
s
Я не знаю, но предполагаю что должно быть ограничение на домен
l
наверно во всяких электронах-кордовах можно будет это убрать
s
Эх... “kotlin indexeddb” - нету(
наверное можно попрбовать натравить ts2kt на кусок lib.d.ts в котором есть IndexedDb
l
Приходите ко мне работать )) Натравите))
g
Да там же базовое апи совсем небольшое, можно и руками описать
В Chrome есть Quota Management API, через него сколько нужно можно запросить. Для всяких электронов совсем не проблема
l
Тогда, все получается шикарно
s
В Chrome есть Quota Management API
Интересно, спасибо. Правда, если я все правильно понял, для веб сайтов можно использовать 20% от 1/3 свободного места на диске. Причем место разделяется между всеми сайтами и когда заканчивается данные просто удаляются. Запросить дополнительное место для веб сайтов никак.
g
все так, но тут вроде речь не о веб сайте
ну и данные все равно где то хранить надо, просто IndexedDB выглядит как наиболее быстрое и удобное решение для табличных данных
и всячкеской обработки списков
l
Воу воу... погодите, какие табличные?)
g
в крайнем случае можно и в оперативке хранить в воркере
l
Там вроде что угодно класть можно
g
Да, но там же есть еще и запросы
в чем и крутость
s
просто IndexedDB выглядит как наиболее быстрое
померил. в 10000 медленее чем хэш мапа в js... правда не уверен что точно мерял. интересная задачка, надо будет проверить на выходных )
в 10000 медленее чем хэш мапа в js...
на чтение
l
Сейчас у меня POJO в js. Ключ - идентификатор объекта. + самописные "индексы" по другим полям, ссылающиеся на те же объекты
g
IndexedDB будет медленнее чем прямой доступ к памяти, тут без вопросов, как и любая база данных медленнее чем прямой доступ
Но память по размеру ограничена, и сложные запросы с индексом (а не просто обращение по ключу) могут быть быстрее в базе
Ну и + персистентность
Короче все те же кейсы как для баз данных вне веба и браузера
l
Спасибо
s
сложные запросы с индексом (а не просто обращение по ключу)
Разве IndexedDB оптимизирует сложные запросы? Возможно вы путаете с Web SQL которая depricated? Насколько я понимаю IndexedDB умеет как раз только по BTree искать (т.к. никаких джоинов, bitmap-сканов, объеденений индексов и т.д.). Оптимизируются только операции поиска и сортировки. Один индекс на две колонки создать нельзя. Ну и запросы к структурам которые в памяти хранятся ведь всегда быстрее. Поэтому врдяли могут быть такие запросы которые выполнятся быстрее в IndexDB нежели к стркутуре в памяти.
Но это к исходному вопросу конечно не имеет отношения. Жалко нельзя тред из треда создавать )
l
Еще один месседж в главном чате - вот вам и тред) Правда, не отсюда. /me вспомнил Google Wave
IndexedDB, если она не обязательно грузится в оперативу - можно использовать как хранилище для сброса 50 мегов, Там часть редко меняется, чтобы не перекачивать
Не могу понять как использовать котлиновский апи для воркеров
g
Это просто описание скоупа воркера в Котлине
с ним ниего не делать. это даже не котлиновское API, а API браузера, просто в котлине есть external декларации для большинства API браузера. Запускайте так же как и в JS запускается (т.е. создаете интсанс Worker (https://kotlinlang.org/api/latest/jvm/stdlib/org.w3c.dom/-worker/index.html) и просто указывается путь к js файлу). В этот инстанс можно слать сообщения А сам этот js файл для воркера - скомпилированный Kotlin код, где внутри можете уже достучаться до вот того самого API, что выше скинули Как то вот так:
Copy code
external val self: DedicatedWorkerGlobalScope
self
внутри воркера вместо
Window
содержит тот самый `DedicatedWorkerGlobalScope`'
👍 1
Нужен кстати именно WebWorker, он же просто Worker, а не ServiceWorker, который больше для обработки всяческих уведомлений в фоне нужен, а не для тяжелых вычяслений
И кстати можно проголосовать за этот issue: https://youtrack.jetbrains.com/issue/KT-21388
l
Описание, что self, указанный таким образом, используется как window - то, что надо. Интересно, почему выбрано именно self?
g
Не совсем
Это так работает уже в браузерах
есть window глобальный, в котором Window хранится, а есть self, который может быть как Window, так и WorkerScope, у них причем часть методов общие
l
@gildor А вот нет, не пашет)
s
@lewik это нужно добавить в main, и добавить опцию в копилятор: call main
g
конечно как топ левел декларация не раотает, нужно в метод перенести
call main по умолчанию же вроде включен, не?
s
call main по умолчанию же вроде включен, не?
да, точно
l
Просто еще не использовал kotlin в js как точку входа. А про main да, что то было.
А есть где то работающий пример? А то все равно воркер в console не пишет и не отвечает. А ошибок нет
g
у меня где то локально валялся, но нигде ну опубликован
а в браузере отлаживать не получается?
l
На брейкпоинте в воркере не останавлвается, если я все правильно конечно делаю.
g
ну а отправка запросов что возвращаетЮ?
Сложно что-то сказать, видимо где то ошибка в коде, там магии особо никакой нет
l
@gildor А чего она вернет? Ничего
Copy code
fun postMessage(message: Any?, transfer: Array<dynamic> = definedExternally): Unit
Еще покопаюсь не получится - выложу
g
Ничего, ага, это просто канал отправки
Поэтому подход как у promise-worker удобнее, там абстракция, которая эмулирует запрос/ответ