Code Monkey home page Code Monkey logo

Comments (5)

yongboy avatar yongboy commented on July 28, 2024 1

@spacewander

I'm back :))

Last week, I reviewed the stream-lua-nginx-module project's c code, here is the tcp stream's semaphore version.

semaphore_stream.lua for stream-lua-nginx-module

-- Copyright (C) Yichun Zhang (agentzh)
-- Copyright (C) cuiweixie
-- Copyright (C) nieyong
-- I hereby assign copyright in this code to the lua-resty-core project,
-- to be licensed under the same terms as the rest of the code.


local ffi = require 'ffi'
local base = require "resty.core.base"


local FFI_OK = base.FFI_OK
local FFI_ERROR = base.FFI_ERROR
local FFI_DECLINED = base.FFI_DECLINED
local ffi_new = ffi.new
local ffi_str = ffi.string
local ffi_gc = ffi.gc
local C = ffi.C
local type = type
local error = error
local tonumber = tonumber
local getfenv = getfenv
local get_string_buf = base.get_string_buf
local get_size_ptr = base.get_size_ptr
local setmetatable = setmetatable
local co_yield = coroutine._yield
local ERR_BUF_SIZE = 128


local errmsg = base.get_errmsg_ptr()


ffi.cdef[[
    struct ngx_stream_lua_semaphore_s;
    typedef struct ngx_stream_lua_semaphore_s ngx_stream_lua_semaphore_t;
    struct ngx_stream_session_s;
    typedef struct ngx_stream_session_s  ngx_stream_session_t;

    int ngx_stream_lua_ffi_semaphore_new(ngx_stream_lua_semaphore_t **psem,
        int n, char **errmsg);

    int ngx_stream_lua_ffi_semaphore_post(ngx_stream_lua_semaphore_t *sem, int n);

    int ngx_stream_lua_ffi_semaphore_count(ngx_stream_lua_semaphore_t *sem);

    int ngx_stream_lua_ffi_semaphore_wait(ngx_stream_session_t *s,
        ngx_stream_lua_semaphore_t *sem, int wait_ms,
        unsigned char *errstr, size_t *errlen);

    void ngx_stream_lua_ffi_semaphore_gc(ngx_stream_lua_semaphore_t *sem);
]]


local psem = ffi_new("ngx_stream_lua_semaphore_t *[1]")


local _M = { version = base.version }
local mt = { __index = _M }


function _M.new(n)
    n = tonumber(n) or 0
    if n < 0 then
        return error("no negative number")
    end

    local ret = C.ngx_stream_lua_ffi_semaphore_new(psem, n, errmsg)
    if ret == FFI_ERROR then
        return nil, ffi_str(errmsg[0])
    end

    local sem = psem[0]

    ffi_gc(sem, C.ngx_stream_lua_ffi_semaphore_gc)

    return setmetatable({ sem = sem }, mt)
end


function _M.wait(self, seconds)
    if type(self) ~= "table" or type(self.sem) ~= "cdata" then
        return error("not a semaphore instance")
    end


    ngx.log(ngx.ALERT, ".................................................")
    for k, v in pairs(getfenv(0).ngx) do
        ngx.log(ngx.INFO, k .. " : " .. tostring(v))
    end
    ngx.log(ngx.ALERT, ".................................................")

    local r = getfenv(0).__ngx_sess

    if not r then
        return error("no session found")
    end

    local milliseconds = tonumber(seconds) * 1000
    if milliseconds < 0 then
        return error("no negative number")
    end

    local cdata_sem = self.sem

    local err = get_string_buf(ERR_BUF_SIZE)
    local errlen = get_size_ptr()
    errlen[0] = ERR_BUF_SIZE

    local ret = C.ngx_stream_lua_ffi_semaphore_wait(r, cdata_sem,
                                             milliseconds, err, errlen)

    if ret == FFI_ERROR then
        return nil, ffi_str(err, errlen[0])
    end

    if ret == FFI_OK then
        return true
    end

    if ret == FFI_DECLINED then
        return nil, "timeout"
    end

    -- Note: we cannot use the tail-call form here since we
    -- might need the current function call's activation
    -- record to hold the reference to our semaphore object
    -- to prevent it from getting GC'd prematurely.
    local ok, err = co_yield()
    return ok, err
end


function _M.post(self, n)
    if type(self) ~= "table" or type(self.sem) ~= "cdata" then
        return error("not a semaphore instance")
    end

    local cdata_sem = self.sem

    local num = n and tonumber(n) or 1
    if num < 1 then
        return error("no negative number")
    end

    -- always return NGX_OK
    C.ngx_stream_lua_ffi_semaphore_post(cdata_sem, num)

    return true
end


function _M.count(self)
    if type(self) ~= "table" or type(self.sem) ~= "cdata" then
        return error("not a semaphore instance")
    end

    return C.ngx_stream_lua_ffi_semaphore_count(self.sem)
end


return _M

The ngx_lua 0.10.7+ required Error

When you got stream lua entry thread aborted: runtime error: /data0/openresty/lualib/resty/core/base.lua:20: ngx_lua 0.10.7+ required error message, maybe you can do a annotation for base.lua file around line 20 code, skip the check , then it works.

--if not ngx.config
--   or not ngx.config.ngx_lua_version
--   or ngx.config.ngx_lua_version < 10007
--then
--    error("ngx_lua 0.10.7+ required")
--end

Other

Maybe I should make a pull request later :))

from lua-resty-core.

yongboy avatar yongboy commented on July 28, 2024

Here is my mac's openresty version:

#bin/openresty -v
nginx version: openresty/1.11.2.2

#bin/openresty -V
nginx version: openresty/1.11.2.2
built by clang 8.0.0 (clang-800.0.42.1)
built with OpenSSL 1.0.2k  26 Jan 2017
TLS SNI support enabled
configure arguments: --prefix=/data0/openresty/nginx --with-cc-opt='-O2 -I/usr/local/opt/openssl/include/ -I/usr/local/opt/pcre/include/' --add-module=../ngx_devel_kit-0.3.0 --add-module=../echo-nginx-module-0.60 --add-module=../xss-nginx-module-0.05 --add-module=../ngx_coolkit-0.2rc3 --add-module=../set-misc-nginx-module-0.31 --add-module=../form-input-nginx-module-0.12 --add-module=../encrypted-session-nginx-module-0.06 --add-module=../srcache-nginx-module-0.31 --add-module=../ngx_lua-0.10.7 --add-module=../ngx_lua_upstream-0.06 --add-module=../headers-more-nginx-module-0.32 --add-module=../array-var-nginx-module-0.05 --add-module=../memc-nginx-module-0.17 --add-module=../redis2-nginx-module-0.13 --add-module=../redis-nginx-module-0.3.7 --add-module=../rds-json-nginx-module-0.14 --add-module=../rds-csv-nginx-module-0.07 --with-ld-opt='-Wl,-rpath,/data0/openresty/luajit/lib -L/usr/local/opt/openssl/lib/ -L/usr/local/opt/pcre/lib/' --with-stream --with-stream_ssl_module --add-module=/data0/stream-lua-nginx-module --with-http_ssl_module

from lua-resty-core.

spacewander avatar spacewander commented on July 28, 2024

The ngx.semaphore support is still under todo list.
https://github.com/openresty/stream-lua-nginx-module#todo

Pull request is welcome!

from lua-resty-core.

gdrbyKo1 avatar gdrbyKo1 commented on July 28, 2024

@yongboy
Hi. Thank you for the code above, I wanted to use the semaphore api today and found out it isn't supported yet, but then I found this issue and your solution, so I thought I'd give it a try.
Unfortunately, it looks like there was some change in the stream-lua-nginx-module project, because when I try to require "ngx.semaphore_stream", I get the following error message:

2018/03/23 14:17:53 [error] 749#0: *1 lua entry thread aborted: runtime error: /home/user/resty/resty_home/lualib/ngx/semaphore_stream.lua:67: /home/user/resty/resty_home/luajit/lib/libluajit-5.1.so.2: undefined symbol: ngx_stream_lua_ffi_semaphore_new
stack traceback:
coroutine 0:
        [C]: in function '__index'
        /home/user/resty/resty_home/lualib/ngx/semaphore_stream.lua:67: in function 'new'
        [...]

It appears the ngx_stream_lua_ffi_semaphore_new is now gone. The original (HTTP) semaphore.lua module references the ngx_http_lua_ffi_sema_new equivalent function, the definition of which can be found here: https://github.com/openresty/lua-nginx-module/blob/c97473b5e66fdfa118b91e428dd8a0417ce81f8c/src/ngx_http_lua_semaphore.c#L310
But when I search for ngx_stream_lua_ffi_semaphore_new in the stream-lua-nginx-module and meta-lua-nginx-module projects, I get no hits. And nothing relevant when searching for semaphore or sema as well. Did some commit remove the semaphore functionality from the stream-lua-nginx-module project?

I think I've found the commit: openresty/stream-lua-nginx-module@8aca0ad

from lua-resty-core.

thibaultcha avatar thibaultcha commented on July 28, 2024

ngx.semaphore is available in the stream module since 4e5a130. This will be part of the upcoming 1.15.6.1 release. Considering this resolved. Thanks!

from lua-resty-core.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.