101

Re: библиотека lua_share (обмен данными между скриптами lua)

вот: https://github.com/untoxa/lua_share/com … 8d74cb964c
бинарники: https://github.com/untoxa/lua_share/releases/latest

102

Re: библиотека lua_share (обмен данными между скриптами lua)

Спасибо. Я тут пока обнаружил небольшой inconsistency.
local ns = sh.GetNameSpace("test_name_space")
val = ns:DeepCopy() -- nil
ns["hello"] = nil
val = ns:DeepCopy() -- {}
Было бы хорошо, чтобы всегда пустой NameSpace как nil возвращался, т.к. иногда нужно делать DeepCopy() в очень частом цикле (sleep(1)) и 99.9% времени он пуст. И чтобы не плодить в garbage пустые таблицы.

103

Re: библиотека lua_share (обмен данными между скриптами lua)

При этом не нужно его там физически в памяти удалять, просто возвращать из dll nil, а не пустую копию, если там пусто.

104 (2021-06-21 09:50:05 отредактировано Андрей_)

Re: библиотека lua_share (обмен данными между скриптами lua)

Можно унифицировать __call для IPC как говорили? Сейчас вот такая реализация гасит сервер при ns('pop'), наверно ищет глобальную. Не знаю, зачем кому-то нужно именно глобальную запускать, когда можно сразу определить ее в каком-то неймспейсе. Ну если нужно, то для глобальных особый неймспейс globals..

__default_namespace_metatable = {
    __newindex = function(self, key, value)
        self.__data[key] = value
    end,
    __index = function(self, key)
        return self.__data[key]
    end,
    __call = function(self, f, ...)
        if f=='get' then return self.__data end
        if f=='pop' then
            local data = self.__data
            if data~=nil and next(data) then 
                self.__data = {}
            else data = nil
            end
            return data
        end
        return self[f](...)
    end
}

И насчет итерирования, о котором вы говорили. Вы предполагали осуществлять блокирование неймспейса на все его итерирование? Иначе это не корректно, он может меняться. Сейчас можно просто взять DeepCopy и по ней итерировать.

..Обнаружил проблему. Как минимум DeepCopy() в IPC в новой сборке работает на порядок медленнее. А может и остальное. С чем это связано? Просто меняю обратно 2 dll - получаю предыдущую скорость. Может сборка без оптимизаций?

105 (2021-06-21 13:13:15 отредактировано toxa)

Re: библиотека lua_share (обмен данными между скриптами lua)

Андрей_ пишет:

Было бы хорошо, чтобы всегда пустой NameSpace как nil возвращался, т.к. иногда нужно делать DeepCopy() в очень частом цикле (sleep(1)) и 99.9% времени он пуст. И чтобы не плодить в garbage пустые таблицы.

это не очень хорошая идея использовать DeepCopy в частом цикле, хотя, зависит от величины таблицы, конечно.

проверять на пустоту и возвращать nil если нет элементов идея не очень хорошая. создайте table.value = 1, потом сделайте table.value = nil. table станет {} а не nil. ровно это мы и наблюдаем. к тому же, нужно проверять на пустоту, а это нетривиальная задача, не в смысле реализации, а в смысле определения подхода: что считать пустотой.

если вас беспокоит неопределенность, используйте val = (ns:DeepCopy() or {})

106 (2021-06-21 13:29:34 отредактировано toxa)

Re: библиотека lua_share (обмен данными между скриптами lua)

Андрей_ пишет:

И насчет итерирования, о котором вы говорили. Вы предполагали осуществлять блокирование неймспейса на все его итерирование? Иначе это не корректно, он может меняться. Сейчас можно просто взять DeepCopy и по ней итерировать.

нет, не предполагал. если вам нужна блокировка - итерируйте копию.

Андрей_ пишет:

..Обнаружил проблему. Как минимум DeepCopy() в IPC в новой сборке работает на порядок медленнее. А может и остальное. С чем это связано? Просто меняю обратно 2 dll - получаю предыдущую скорость. Может сборка без оптимизаций?

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

107 (2021-06-21 13:16:39 отредактировано toxa)

Re: библиотека lua_share (обмен данными между скриптами lua)

я не вижу причин блокировать таблицу во время итерирования. если нужна блокировка - всегда можно сделать ее самостоятельно при помощи флагов внутри общего хранилища.

108

Re: библиотека lua_share (обмен данными между скриптами lua)

toxa пишет:

я не вижу причин блокировать таблицу во время итерирования. если нужна блокировка - всегда можно сделать ее самостоятельно при помощи флагов внутри общего хранилища.

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

А вот такой метод get в __call будет работать по скорости примерно одинаково с DeepCopy?

109

Re: библиотека lua_share (обмен данными между скриптами lua)

Андрей_ пишет:

Этак она может перестроиться так, что даже повторно элементы проитерируются.. )

нет. из-за особенностей реализации next()

Андрей_ пишет:

А вот такой метод get в __call будет работать по скорости примерно одинаково с DeepCopy?

какой?

110

Re: библиотека lua_share (обмен данными между скриптами lua)

toxa пишет:

какой?

Выше по поводу __call в IPC и кусок кода метатаблицы для неймспейса. Вызов ns('get'), должен работать аналогично DeepCopy

111

Re: библиотека lua_share (обмен данными между скриптами lua)

Андрей_ пишет:

Выше по поводу __call в IPC и кусок кода метатаблицы для неймспейса. Вызов ns('get'), должен работать аналогично DeepCopy

никакой разницы. код, который копирует результат один и тот же. немного медленнее из-за вызова метаметода __call(), но это довольно мало.

112 (2021-06-21 14:12:51 отредактировано Андрей_)

Re: библиотека lua_share (обмен данными между скриптами lua)

toxa пишет:
Андрей_ пишет:

Выше по поводу __call в IPC и кусок кода метатаблицы для неймспейса. Вызов ns('get'), должен работать аналогично DeepCopy

никакой разницы. код, который копирует результат один и тот же. немного медленнее из-за вызова метаметода __call(), но это довольно мало.

Хорошо. Добавьте пожалуйста поддержку __call в неймспейсах для IPC. Проксирование как в не-IPC.

113

Re: библиотека lua_share (обмен данными между скриптами lua)

пожалуйста: https://github.com/untoxa/lua_share/com … 34740cea6f

114 (2021-06-22 09:14:22 отредактировано Андрей_)

Re: библиотека lua_share (обмен данными между скриптами lua)

toxa пишет:

пожалуйста: https://github.com/untoxa/lua_share/com … 34740cea6f

Собрал, проверю. И добавил на всякий случай ключ оптимизации -O3. Есть какие-то причины этого не делать?

И нашел, что же тормозит. Это просто sleep(1). Вот сейчас стабильно этот код в квике работает 15.4 сек, а не 1 сек. Но днем с этим проблем не было. Не знаете, что может быть? Причем я пробовал и квиковский sleep и сокетовый, результат одинаков. Причем он такой же и для sleep(10).

local sleep=sleep
for i=0,1000 do
    sleep(1)
end

..после нескольких перезапусков квика сейчас 1.5-1.6с. Не пойму от чего зависит.

Вот, похоже эта проблема. Как исправить видимо на уровне ОС,чтобы не было переключения какого-то
https://stackoverflow.com/questions/232 … akes-15-ms

И все это для реализации RPC вызова в другом макросе\квике. Вы говорили только через опрос со sleep можно?
Может еще как-то можно? Sleep(0) приводит к видимой загрузке в простое, а Sleep(15) - много. timeBeginPeriod(1) не сильно портит жизнь ОС\батарее и т.п.?

115

Re: библиотека lua_share (обмен данными между скриптами lua)

NtSetTimerResolution()

116

Re: библиотека lua_share (обмен данными между скриптами lua)

toxa пишет:

NtSetTimerResolution()

не работает в последних сборках Windows 10 на глобальном уровне. Надо как-то вызывать это из/для самого процессса.
https://habr.com/ru/post/522212/
У меня все утилиты показывают текущее разрешение 1мс. А Sleep(1) в квике все равно работает 15.5мс. Но так и не понятно, как он иногда переходит на 1.5мс.
Интересно, если бы такая ф-ция появилась в lua_share.dll для вызова, это работало бы.. )

117

Re: библиотека lua_share (обмен данными между скриптами lua)

library lua_mmtimer;

uses  windows;

type  NTSTATUS       = ULONG;

const STATUS_SUCCESS = NTSTATUS(0);

function NtQueryTimerResolution(LowRes: PULONG; HighRes: PULONG; CurrRes: PULONG): NTSTATUS; stdcall; external 'ntdll.dll' name 'NtQueryTimerResolution';
function NtSetTimerResolution(RequestedRes: ULONG; Set_: Boolean; ActualRes: PULONG): NTSTATUS; stdcall; external 'ntdll.dll' name 'NtSetTimerResolution';


function luaopen_lua_mmtimer(ALuaInstance: pointer): longint; cdecl;
var ResSet: ULONG;
begin 
  NtSetTimerResolution(5000, true, @ResSet);
  result:= 0; 
end;

exports
  luaopen_lua_mmtimer name 'luaopen_lua_mmtimer';

end.

для использования просто пишете:

mt = require "lua_mmtimer"

и всё

118

Re: библиотека lua_share (обмен данными между скриптами lua)

Спасибо! Вот и моя первая dll для квика. Кажется теперь понимаю, почему вы выбираете паскаль для этого )

119 (2021-06-27 19:55:52 отредактировано Андрей_)

Re: библиотека lua_share (обмен данными между скриптами lua)

А почему индексные метаметоды создают объект, а call - нет? Это не удобно, т.к. для надежности всегда после GetIPCNameSpace надо что-то в него пробрасывать. Вдруг () вызовется раньше..  При этом еще и сервер очень неприятно слетает, даже квик перезапускать приходится. С таким успехом можно всегда создавать объект в GetIPCNameSpace. Но лучше, чтобы все метаметоды одинаково инициализировали в этом плане. Какие доводы против инициализации call-ом?

120

Re: библиотека lua_share (обмен данными между скриптами lua)

я не проверяю, существует объект для вызова или нет. проглатывать ошибки неправильно.

сейчас просто достаем объект, не важно какой, может быть таблица, а может функция, что угодно, и пытаемся его вызывать. если это функция или что угодно с метаметодом __call(), то он вызовется.

то есть не нужно для глобальных функций делать прокси из таблицы с метаметодом __call().

а раз так, то непонятно: что создавать? и почему именно это?

то, что квик виснет - неприятно. наверное, нужно добавить тайм-аут ожидания ответа.

121 (2021-06-28 17:18:47 отредактировано Андрей_)

Re: библиотека lua_share (обмен данными между скриптами lua)

toxa пишет:

я не проверяю, существует объект для вызова или нет. проглатывать ошибки неправильно.

сейчас просто достаем объект, не важно какой, может быть таблица, а может функция, что угодно, и пытаемся его вызывать. если это функция или что угодно с метаметодом __call(), то он вызовется.

то есть не нужно для глобальных функций делать прокси из таблицы с метаметодом __call().

а раз так, то непонятно: что создавать? и почему именно это?

то, что квик виснет - неприятно. наверное, нужно добавить тайм-аут ожидания ответа.

И все же, почему отличаются подходы чтения через [] и запуска через () для свежеполученного неймспейса?
Оба метоаметода определены в одном месте. Но только второй требует некоей доп. инициализации где-то внутри. Которая достигается через обращение к [] сперва:
ns["test"] = "Hello, world" -- must ensure test_name_space exists, call does not create the object
А ns["test"] не "must ensure test_name_space exists", т.к. само делает "create the object"

122

Re: библиотека lua_share (обмен данными между скриптами lua)

не совсем понял что вы имеете в виду в двух последних строках, возможно что-то напутали. так вот:

ns["key"] = "value"

однозначно определяет, что вы хотите присвоить ключу "key" значение "value" в некой таблице. если таблицы нет, то мы ее создаем.

когда мы делаем ns("param") и ns у нас не существует, то что нам создать, таблицу? а у этой таблицы будет метаметод __call()? с чего бы? а если boot удалить?

кроме того, как я сказал, ns не обязательно должна быть таблицей. может быть глобальной функцией. тогда ns("param") можно сделать, а ns["key"] = "value" - нельзя (ну или можно, если функции присвоить метатаблицу с метаметодами __index и __newindex, но это из разряда курьезов).

в общем, я не вижу особого смысла в том, чтобы создавать объект при вызове его как функции.

123 (2021-06-29 10:04:46 отредактировано Андрей_)

Re: библиотека lua_share (обмен данными между скриптами lua)

toxa пишет:

ns["key"] = "value"

однозначно определяет, что вы хотите присвоить ключу "key" значение "value" в некой таблице. если таблицы нет, то мы ее создаем.

когда мы делаем ns("param") и ns у нас не существует, то что нам создать, таблицу? а у этой таблицы будет метаметод __call()? с чего бы? а если boot удалить?

ns мы получили не произвольно, а явно указав, что это неймспейс "x". "x" определен в boot, либо применяется политика по умолчанию - таблица. Т.к. смысла быть неопределенной ф-цией нет ) Поэтому нет никакой неопределенности что создавать.  ns("param") однозначно определяет, что вы хотите вызвать __call в объекте "x" из boot, либо таблице по умолчанию. Естественно, разработчик либо обеспечивает __call() в "x", либо в __default_namespace_metatable, которое по умолчанию назначается всем таблицам. Если зачем-то удалить boot (в чем пользы и смысла нет совсем), вот тогда можно и получать ошибку.
А иначе мы в итоге имеем то, что __call это мегаполезно и будет использоваться 90% проектов, но нужно всегда самому пробрасывать в индекс ненужное, иначе будет плохо. А значит, для надежности всегда делать это после GetNameSpace. Учитывая, что и без использования call не так много смысла в отложенном создании таблицы под GetNameSpace, лучше уж создавать ее всегда сразу, если ее нет. Внутри GetNameSpace. Не получая доп рисков ошибок и cold run инициализации при первом использовании.

Я, кстати, и не предполагал, что через ns = GetIPCNamespace("x") можно сослаться на глобальную ф-цию х. Это не описано. А точно ли можно? Впрочем, это было бы лишним нагромождением.

124

Re: библиотека lua_share (обмен данными между скриптами lua)

я не считаю, что __call это мегаполезно и нужно использовать это повсеместно.

просто пишите код аккуратно и никаких проблем не будет. слишком много умолчаний и подавление ошибок - это плохо, ведет к неочевидным проблемам в будущем.

да, можно сослаться на глобальную функцию. да, не описано, потому что я изменения в поведении __call не описывал в доке.

125

Re: библиотека lua_share (обмен данными между скриптами lua)

local sh = require "lua_share"
sh['test']=1

Когда не используется неймспейс, переменные создаются в _G, или в какой-то неявной таблице\неймспейсе?