Re: библиотека lua_share (обмен данными между скриптами lua)
Как на словах выглядит схема обеспечения такой работы с помощью очереди я не вполне представляю.
Вы не вошли. Пожалуйста, войдите или зарегистрируйтесь.
QUIK -> DDE → Написание внешних библиотек на C++/Delphi/C# для Lua → библиотека lua_share (обмен данными между скриптами lua)
Как на словах выглядит схема обеспечения такой работы с помощью очереди я не вполне представляю.
есть считалка. она выгребает из очереди данные для расчетов и результат своих расчетов кладет в очереди для других компонент. такой конвейер.
есть считалка. она выгребает из очереди данные для расчетов и результат своих расчетов кладет в очереди для других компонент. такой конвейер.
Ага, и нужно на каждую ф-цию создавать свой скрипт-считалку, который будет всегда запущен в квике. Именно для ее исполнения в одном потоке. С паковкой\распаковкой всех данных от скриптов-заказчиков. Это намного менее удобно, чем заниматься обработкой самим скриптам в их среде и потоке. Да и нет такой единой ф-ции обработки, каждый макрос делает обработку общих данных по своему. Логику из них выносить не надо, каждый макрос- вещь в себе. Надо только обеспечить им монопольный доступ к объекту общей памяти на нужное им время. Для этого даже не требуется многопоточной машины в библиотеке. Пусть есть 10 макросов, это 11 потоков (+ основной, колбековый) и пусть даже код boot исполняется однопоточно. Мьютексы доступа к объекту должны быть не в lua машине а в dll, на подступах потоков макросов к lua машине.
И с одной стороны можно было бы эмулировать mutex с помощью boot. Макрос в цикле со sleep (в его потоке) вызывает метаметод boot, который однопоточно и атомарно пытается установить флаг. Но проблема в том, что sleep тут должно быть малым, и это забьёт запросами библиотеку, которая однопоточна. Пока кто-то пытается так получить доступ к одному объекту, страдают все остальные независимые пользователи общей памяти.
А в цепочке обращений макроса к dll, к конкретному объекту, должно быть место, исполняемое в потоке макроса и куда можно встроить нормальный mutex, сериализующий эти потоки.
ну, насколько мне известно, такого решения в данный момент не существует и я не слышал, чтобы кто-то подобным занимался.
ps: любой малый sleep(), скажем, sleep(0) и "забить запросами библиотеку" станет невозможно. "забить" можно только с busywait.
Мьютексы доступа к объекту должны быть не в lua машине а в dll, на подступах потоков макросов к lua машине.
если в качестве разделяемого хранилища используется одна общая lua-машина, как в библиотеке lua_share, данное решение невозможно.
вот, объект типа NameSpace конструируется без обработчика __call:
[url]https://github.com/untoxa/lua_share/blob/master/lua_share_main.pas#L278[/url]а объект типа IPCNameSpace с обработчиком __call:
[url]https://github.com/untoxa/lua_share/blob/master/lua_share_main.pas#L288[/url]надо просто дописать имплементацию call для случая NameSpace. но ns("test", "a") не очень красиво, все же ns:test("a") гораздо круче.
Так все таки. Там не только call нет, там нет ничего кроме index, newindex. Другие метаметоды сейчас не поддерживаются, просьба добавить. Пробую __mod.
Что значит «не поддерживаются»?! ) А вам, собственно, какие нужны?
Кроме того, всегда есть, как минимум, пара объектов: к каждому объекту в общей lua-машине в каждой квиковой lua-машине для него создается прокси. Вы можете цеплять любые свои метаметоды из квикового скрипта к прокси-объекту, а можете цеплять любые свои метаметоды к oбщему объекту со стороны lua_share_boot.lua.
То есть, в некотором смысле, не только все метаметоды поддерживаются, но и к тому же дважды. Вы сделать-то что хотите?
Что значит «не поддерживаются»?! ) А вам, собственно, какие нужны?
Кроме того, всегда есть, как минимум, пара объектов: к каждому объекту в общей lua-машине в каждой квиковой lua-машине для него создается прокси. Вы можете цеплять любые свои метаметоды из квикового скрипта к прокси-объекту, а можете цеплять любые свои метаметоды к oбщему объекту со стороны lua_share_boot.lua.
То есть, в некотором смысле, не только все метаметоды поддерживаются, но и к тому же дважды. Вы сделать-то что хотите?
Вы выше говорили, что все метаметоды по вашей ссылке поддерживаются в boot. И работают соответственно однопоточно. Я специально уточнял ) Так вот, там только индексные и call для IPC. Как в вашем pas и указано в саморегистрации.
Мета в прокси однопоточность не обеспечат. Хотелось бы более чем 2 метаметода на объект с обеспечением эксклюзивности запуска. Я хочу в boot определить __mod и вызвать в скрипте типа queues % 2
Вы, вообще, понимаете как метаметоды работают? Не важно сколько по-умолчанию реализовано в dll. Те, что не реализованы вы дописываете на lua сами. Весь код, что имеется в lua_share выполняется эксклюзивно. В контексте разных тредов, но не более чем в одном треде в каждый момент времени.
Если вы в boot определите __mod() то и действовать он тоже будет внутри общей lua-машины. Например, если вы напишете подобное выражение в коде инициализации, либо используете это в другом метаметоде, том же __index().
И что должно быть результатом «queues % 2»?
Нет, можно, конечно, по-умолчанию проксировать вызовы всех метаметодов без разбора, но по-моему такая хрень получится…
Я то вообще понимаю ) Вы понимаете, что я уже 2 дня спрашиваю, как можно вызвать код с блокированием потоков? И мы пришли к тому, что сейчас это только метаметоды в boot. Вы сами мне это предложили, сказав, что я могу использовать любой. И как же мне их использовать, если они не проксируются? определить в boot то я могу. Но наладить это как вызов через прокси..? Как я сам устрою это проксирование?
через index/newindex. пишете в таблицу данные в какой-нибудь синтетический ключ, скажем, "__mod", на той стороне в __newindex() делаете self % <что-там нужно>, в __mod() на той стороне определяете, что такое "%". можете на этой стороне так же переопределить __mod() чтобы он делал что-то вроде self["__mod"] = 2 и возвращал результат. тогда получится проброс вызова.
просто тупо пробрасывать все подряд лишено всякого смысла. как по-вашему должен пробрасываться вызов __gc() ?!
через index/newindex. пишете в таблицу данные в какой-нибудь синтетический ключ, скажем, "__mod", на той стороне в __newindex() делаете self % <что-там нужно>, в __mod() на той стороне определяете, что такое "%". можете на этой стороне так же переопределить __mod() чтобы он делал что-то вроде self["__mod"] = 2 и возвращал результат. тогда получится проброс вызова.
просто тупо пробрасывать все подряд лишено всякого смысла. как по-вашему должен пробрасываться вызов __gc() ?!
Я примерно так и сделал в итоге. Но вы считаете, что пробрасывать вызов всех ф-ций через __index это меньшее извращение, чем использование % для какого-то функционала? Включите call хотя бы. Я явно спрашивал, какие метаметоды "проксируются" в нынешних терминах, уже тогда указывая "неужели только индексные".
toxa пишет:я давал ссылку выше.
Я знаю, какие бывают в lua. Спросил, какие из них поддерживаются библиотекой для атомарного исполнения после взятия их как GetNameSpace. Мы выяснили, что __call с передачей имени внутреннего метода и параметров - не работает. а __index работает.. Тогда какие метаметоды работают и почему только они?
На что вы ответили "все".
По возможности нужно, чтобы проксирование подхватывало все, которые определены в boot.
По возможности нужно, чтобы проксирование подхватывало все, которые определены в boot.
внимание, вопрос. в объекте permanent определен метаметод __gc(). он должен пробрасываться?
наверное, в пробросе все-таки должен быть какой-то смысл.
__call() не сделан потому, что для IPC он работает специфически: вызывает функции, определенные глобально. я посчитал, что так будет проще для понимания, теперь, если поменять - пропадет совместимость. но я не уверен, что для не-IPC он должен работать так же. я подумаю, как лучше сделать.
возможно, у прокси по умолчанию стоит реализовать __pairs(), тогда общие таблицы можно будет итерировать. тупо пробросить __pairs() нельзя, потому что [s]гладиолус[/s] он возвращает функцию next(), а динамически проксировать функции, чтобы они могли вызываться в любой момент из lua-машины квика, как мы выяснили выше, не так чтобы очень просто.
остальное лучше оставить пользователю, потому что "queues % 2" вызванный из квика не обязательно должен делать то же самое, что "queues % 2" вызванный из lua_share_boot.
Андрей_ пишет:По возможности нужно, чтобы проксирование подхватывало все, которые определены в boot.
внимание, вопрос. в объекте permanent определен метаметод __gc(). он должен пробрасываться?
наверное, в пробросе все-таки должен быть какой-то смысл.
__call() не сделан потому, что для IPC он работает специфически: вызывает функции, определенные глобально. я посчитал, что так будет проще для понимания, теперь, если поменять - пропадет совместимость. но я не уверен, что для не-IPC он должен работать так же. я подумаю, как лучше сделать.
возможно, у прокси по умолчанию стоит реализовать __pairs(), тогда общие таблицы можно будет итерировать. тупо пробросить __pairs() нельзя, потому что [s]гладиолус[/s] он возвращает функцию next(), а динамически проксировать функции, чтобы они могли вызываться в любой момент из lua-машины квика, как мы выяснили выше, не так чтобы очень просто.
остальное лучше оставить пользователю, потому что "queues % 2" вызванный из квика не обязательно должен делать то же самое, что "queues % 2" вызванный из lua_share_boot.
__gc() - особый случай. Это не из области функционала объекта, а про управление его жизнью. С т.з. функций прокси по смыслу и есть тот самый объект в общей памяти. Так что смысла в проксировании методов из boot гораздо больше, чем в не проксировании. Что значит оставить пользователю, если вы не предоставляете пользователю альтернативы горожению протокола RPC в оператор [], единственно доступный? Оставьте пользователю выбор какие метаметоды проксировать, какие нет - тогда да. А если не возможно - проксируйте по умолчанию то, что задано в boot. Переопределить метаметоды в прокси пользователь как раз сможет при желании. А проксировать - нет. Либо вы не сказали как.
__call для всех логичнее проксирвоать, а для вызова глобальных ф-ций определить особый namespace "globals" и в нем его переопределить.
И еще, стоит рассмотреть переход на патченную машину с поддержкой многопоточности. Монстр квиковская или нет, но это у нас среда исполнения де-факто. И она нормально работает в потоках main и колбеков. Но может вы лучшую найдете.
Потому что без этого как можно было всерьез предлагать переносить обработку в boot и RPC, если эти методы будут блокирвоать всю общую память? В многопоточной сериализация потоков будет уже на уровне объектов. Ну и, видимо, если использовать квиковскую машину, то в boot будут доступны и все ф-ции квика.
Наткнулся сейчас вот на это. Что об этом думаете? )
[url]https://forum.quik.ru/forum10/topic6198/[/url]
__call для всех логичнее проксирвоать, а для вызова глобальных ф-ций определить особый namespace "globals" и в нем его переопределить.
да
И еще, стоит рассмотреть переход на патченную машину с поддержкой многопоточности. Монстр квиковская или нет, но это у нас среда исполнения де-факто. И она нормально работает в потоках main и колбеков. Но может вы лучшую найдете.
нет
Ну и, видимо, если использовать квиковскую машину, то в boot будут доступны и все ф-ции квика.
ну пусть arqa technologies и делает. функции доступны не будут, чтобы были - quik должен сам инициализировать lua-машину в момент ее создания, а это невозможно из сторонней dll.
в общем, резюме такое: поддержать call(), поддержать _pairs(), по возможности сделать динамическое проксирование функций: ns.other_table:method(args) - это интересная задача. когда у меня появится возможность этим заниматься я доделаю.
напоминаю, что lua_share это бесплатная open-source mit-licenced библиотека. если вам что-то не нравится, или вы хотите что-то доделать в ней быстрее - всегда можно форкнуть и сделать из этого форка все что угодно самостоятельно.
Наткнулся сейчас вот на это. Что об этом думаете?
автор пытается выглядеть умнее, чем есть на самом деле, но незнание терминологии его выдает.
вот, я делал такой proof-of-concept для "многопоточной" lua-машины quik: [url]https://github.com/untoxa/lua_threads[/url] можете попробовать использовать это. но, повторюсь: идея - говно, несмотря на то, что прототип более-менее работает.
всегда можно форкнуть и сделать из этого форка все что угодно самостоятельно.
Никогда не программировал на паскале и дельфи. Там есть все, что нужно для сборки? Включая lua библиотеки и т.п.? Какую версию дельфи рекомендуете?
Все собирается при помощи бесплатного fpc (x64). Кроме fpc и клонированного репозитория ничего не требуется. В репе есть батник для сборки.
QUIK -> DDE → Написание внешних библиотек на C++/Delphi/C# для Lua → библиотека lua_share (обмен данными между скриптами lua)
Форум работает на PunBB, при поддержке Informer Technologies, Inc