diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000..470a09d5 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,59 @@ +name: CI + +on: + push: + branches: main + pull_request: + branches: '*' + workflow_dispatch: + inputs: + openresty: + description: 'OpenResty version (e.g. 1.21.4.1rc2)' + required: true + +defaults: + run: + shell: bash + +jobs: + tests: + name: Tests + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest] + openresty: + - 1.21.4.1 + - 1.19.9.1 + - 1.19.3.2 + - 1.17.8.2 + - 1.15.8.3 + - 1.13.6.2 + - 1.11.2.5 + steps: + - if: ${{ github.event_name == 'workflow_dispatch' }} + run: echo "OPENRESTY_VER=${{ github.event.inputs.openresty }}" >> $GITHUB_ENV + - if: ${{ github.event_name == 'push' || github.event_name == 'pull_request' }} + run: echo "OPENRESTY_VER=${{ matrix.openresty }}" >> $GITHUB_ENV + - uses: actions/checkout@v2 + - name: Setup OpenResty + uses: thibaultcha/setup-openresty@main + with: + version: ${{ env.OPENRESTY_VER }} + - run: prove -r t/ + + lint: + name: Lint + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest] + openresty: [1.19.9.1] + steps: + - uses: actions/checkout@v2 + - name: Setup OpenResty + uses: thibaultcha/setup-openresty@main + with: + version: ${{ matrix.openresty }} + - run: | + echo "luarocks check" diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 94549ad8..00000000 --- a/.travis.yml +++ /dev/null @@ -1,74 +0,0 @@ -# vim:st=2 sts=2 sw=2 et: - -os: linux -dist: xenial -sudo: false - -language: c -compiler: gcc - -notifications: - email: false - -cache: - directories: - - download-cache - - perl5 - -env: - global: - - JOBS=2 - - LUAROCKS=3.4.0 - - TEST_NGINX_RANDOMIZE=1 - matrix: - - OPENRESTY=1.19.3.1 - - OPENRESTY=1.17.8.2 - - OPENRESTY=1.17.8.1 - - OPENRESTY=1.15.8.3 - - OPENRESTY=1.15.8.1 - - OPENRESTY=1.13.6.2 - - OPENRESTY=1.13.6.1 - - OPENRESTY=1.11.2.5 - - OPENRESTY=1.11.2.1 - -before_install: - - mkdir -p download-cache - - if [ ! -f download-cache/openresty-$OPENRESTY.tar.gz ]; then wget -O download-cache/openresty-$OPENRESTY.tar.gz https://openresty.org/download/openresty-$OPENRESTY.tar.gz; fi - - if [ ! -f download-cache/luarocks-$LUAROCKS.tar.gz ]; then wget -O download-cache/luarocks-$LUAROCKS.tar.gz https://luarocks.github.io/luarocks/releases/luarocks-$LUAROCKS.tar.gz; fi - - if [ ! -f download-cache/cpanm ]; then wget -O download-cache/cpanm https://cpanmin.us/; fi - - tar -zxf download-cache/openresty-$OPENRESTY.tar.gz - - tar -zxf download-cache/luarocks-$LUAROCKS.tar.gz - -install: - - chmod +x download-cache/cpanm - - download-cache/cpanm --notest Test::Nginx >build.log 2>&1 || (cat build.log && exit 1) - - download-cache/cpanm --notest --local-lib=$TRAVIS_BUILD_DIR/perl5 local::lib && eval $(perl -I $TRAVIS_BUILD_DIR/perl5/lib/perl5/ -Mlocal::lib) - - pushd openresty-$OPENRESTY - - export OPENRESTY_PREFIX=$TRAVIS_BUILD_DIR/openresty-$OPENRESTY - - ./configure --prefix=$OPENRESTY_PREFIX --without-http_ssl_module -j$JOBS >build.log 2>&1 || (cat build.log && exit 1) - - make -j$JOBS >build.log 2>&1 || (cat build.log && exit 1) - - make install >build.log 2>&1 || (cat build.log && exit 1) - - popd - - pushd luarocks-$LUAROCKS - - export LUAROCKS_PREFIX=$TRAVIS_BUILD_DIR/luarocks-$LUAROCKS - - ./configure --prefix=$LUAROCKS_PREFIX --with-lua=$OPENRESTY_PREFIX/luajit --with-lua-include=$OPENRESTY_PREFIX/luajit/include/luajit-2.1 --lua-suffix=jit >build.log 2>&1 || (cat build.log && exit 1) - - make build >build.log 2>&1 || (cat build.log && exit 1) - - make install >build.log 2>&1 || (cat build.log && exit 1) - - popd - - export PATH=$OPENRESTY_PREFIX/nginx/sbin:$LUAROCKS_PREFIX/bin:$PATH - - nginx -V - -stages: - - lint - - test - -jobs: - include: - - stage: lint - script: - - luarocks install luacheck >build.log 2>&1 || (cat build.log && exit 1) - - luarocks --version - - luacheck lib/ - -script: - - prove -j$JOBS -r t/ diff --git a/CHANGELOG.md b/CHANGELOG.md index 4e9838ef..743993ab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ # Table of Contents +- [2.6.0](#2.6.0) - [2.5.0](#2.5.0) - [2.4.1](#2.4.1) - [2.4.0](#2.4.0) @@ -13,6 +14,18 @@ - [1.0.1](#1.0.1) - [1.0.0](#1.0.0) +## [2.6.0] + +> Released on: 2022/08/22 + +#### Added + +- Use the new LuaJIT `string.buffer` API for L2 (shm layer) encoding/decoding + when available. + [#110](https://github.com/thibaultcha/lua-resty-mlcache/pull/110) + +[Back to TOC](#table-of-contents) + ## [2.5.0] > Released on: 2020/11/18 @@ -242,6 +255,7 @@ Initial release. [Back to TOC](#table-of-contents) +[2.6.0]: https://github.com/thibaultcha/lua-resty-mlcache/compare/2.5.0...2.6.0 [2.5.0]: https://github.com/thibaultcha/lua-resty-mlcache/compare/2.4.1...2.5.0 [2.4.1]: https://github.com/thibaultcha/lua-resty-mlcache/compare/2.4.0...2.4.1 [2.4.0]: https://github.com/thibaultcha/lua-resty-mlcache/compare/2.3.0...2.4.0 diff --git a/LICENSE b/LICENSE index dc61269b..873a00e7 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2017-2020 Thibault Charbonnier +Copyright (c) 2017-2022 Thibault Charbonnier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index 1b49989c..183c4666 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # lua-resty-mlcache -[![Build Status][badge-travis-image]][badge-travis-url] +[![CI](https://github.com/thibaultcha/lua-resty-mlcache/actions/workflows/ci.yml/badge.svg)](https://github.com/thibaultcha/lua-resty-mlcache/actions/workflows/ci.yml) Fast and automated layered caching for OpenResty. @@ -115,7 +115,7 @@ http { end - -- we put our instance in the global table for brivety in + -- we put our instance in the global table for brevity in -- this example, but prefer an upvalue to one of your modules -- as recommended by ngx_lua _G.cache = cache @@ -136,9 +136,9 @@ http { -- this call will try L1 and L2 before running the callback (L3) -- the returned value will then be stored in L2 and L1 -- for the next request. - local user, err = cache:get("my_key", nil, callback, "John Doe") + local user, err = cache:get("my_key", nil, callback, "jdoe") - ngx.say(user.username) -- "John Doe" + ngx.say(user.name) -- "John Doe" } } } @@ -164,6 +164,7 @@ Tests matrix results: | `1.15.8.x` | :heavy_check_mark: | `1.17.8.x` | :heavy_check_mark: | `1.19.3.x` | :heavy_check_mark: +| `1.19.9.x` | :heavy_check_mark: | > | not tested [Back to TOC](#table-of-contents) @@ -236,7 +237,7 @@ holding the desired options for this instance. The possible options are: specified, mlcache will not instantiate an LRU. One can use this value to use the `resty.lrucache.pureffi` implementation of lua-resty-lrucache if desired. - `shm_set_tries`: the number of tries for the lua_shared_dict `set()` - operation. When the lua_shared_dict is full, it attempts to free up to 30 + operation. When the `lua_shared_dict` is full, it attempts to free up to 30 items from its queue. When the value being set is much larger than the freed space, this option allows mlcache to retry the operation (and free more slots) until the maximum number of tries is reached or enough memory was freed for @@ -244,9 +245,9 @@ holding the desired options for this instance. The possible options are: **Default**: `3`. - `shm_miss`: _optional_ string. The name of a `lua_shared_dict`. When specified, misses (callbacks returning `nil`) will be cached in this separate - lua_shared_dict. This is useful to ensure that a large number of cache misses - (e.g. triggered by malicious clients) does not evict too many cached items - (hits) from the lua_shared_dict specified in `shm`. + `lua_shared_dict`. This is useful to ensure that a large number of cache + misses (e.g. triggered by malicious clients) does not evict too many cached + items (hits) from the `lua_shared_dict` specified in `shm`. - `shm_locks`: _optional_ string. The name of a `lua_shared_dict`. When specified, lua-resty-lock will use this shared dict to store its locks. This option can help reducing cache churning: when the L2 cache (shm) is full, @@ -391,7 +392,7 @@ options: indefinitely. **Default:** inherited from the instance. - `shm_set_tries`: the number of tries for the lua_shared_dict `set()` - operation. When the lua_shared_dict is full, it attempts to free up to 30 + operation. When the `lua_shared_dict` is full, it attempts to free up to 30 items from its queue. When the value being set is much larger than the freed space, this option allows mlcache to retry the operation (and free more slots) until the maximum number of tries is reached or enough memory was freed for @@ -1024,8 +1025,4 @@ Work licensed under the MIT License. [lua-resty-lock]: https://github.com/openresty/lua-resty-lock [lua-resty-lrucache]: https://github.com/openresty/lua-resty-lrucache [lua_shared_dict]: https://github.com/openresty/lua-nginx-module#lua_shared_dict - -[badge-travis-url]: https://travis-ci.org/thibaultcha/lua-resty-mlcache -[badge-travis-image]: https://travis-ci.org/thibaultcha/lua-resty-mlcache.svg?branch=master - [talk]: https://www.slideshare.net/ThibaultCharbonnier/layered-caching-in-openresty-openresty-con-2018 diff --git a/lib/resty/mlcache.lua b/lib/resty/mlcache.lua index de8eb741..7f66af0b 100644 --- a/lib/resty/mlcache.lua +++ b/lib/resty/mlcache.lua @@ -1,6 +1,5 @@ --- vim: st=4 sts=4 sw=4 et: +-- vim: ts=4 sts=4 sw=4 et: -local cjson = require "cjson.safe" local new_tab = require "table.new" local lrucache = require "resty.lrucache" local resty_lock = require "resty.lock" @@ -20,6 +19,14 @@ do } end end +local codec +do + local pok + pok, codec = pcall(require, "string.buffer") + if not pok then + codec = require "cjson" + end +end local now = ngx.now @@ -29,11 +36,14 @@ local fmt = string.format local sub = string.sub local find = string.find local type = type +local pcall = pcall local xpcall = xpcall local traceback = debug.traceback local error = error local tostring = tostring local tonumber = tonumber +local encode = codec.encode +local decode = codec.decode local thread_spawn = ngx.thread.spawn local thread_wait = ngx.thread.wait local setmetatable = setmetatable @@ -85,12 +95,12 @@ local marshallers = { end, [4] = function(t) -- table - local json, err = cjson.encode(t) - if not json then - return nil, "could not encode table value: " .. err + local pok, str = pcall(encode, t) + if not pok then + return nil, "could not encode table value: " .. str end - return json + return str end, } @@ -127,9 +137,9 @@ local unmarshallers = { end, [4] = function(str) -- table - local t, err = cjson.decode(str) - if not t then - return nil, "could not decode table value: " .. err + local pok, t = pcall(decode, str) + if not pok then + return nil, "could not decode table value: " .. t end return t @@ -164,7 +174,7 @@ end local _M = { - _VERSION = "2.5.0", + _VERSION = "2.6.0", _AUTHOR = "Thibault Charbonnier", _LICENSE = "MIT", _URL = "https://github.com/thibaultcha/lua-resty-mlcache", diff --git a/lib/resty/mlcache/ipc.lua b/lib/resty/mlcache/ipc.lua index 6f00a55f..8a7916c4 100644 --- a/lib/resty/mlcache/ipc.lua +++ b/lib/resty/mlcache/ipc.lua @@ -1,4 +1,4 @@ --- vim: st=4 sts=4 sw=4 et: +-- vim: ts=4 sts=4 sw=4 et: local ERR = ngx.ERR local WARN = ngx.WARN diff --git a/lua-resty-mlcache-2.5.0-1.rockspec b/lua-resty-mlcache-2.6.0-1.rockspec similarity index 97% rename from lua-resty-mlcache-2.5.0-1.rockspec rename to lua-resty-mlcache-2.6.0-1.rockspec index 857bf52d..4821f51a 100644 --- a/lua-resty-mlcache-2.5.0-1.rockspec +++ b/lua-resty-mlcache-2.6.0-1.rockspec @@ -1,8 +1,8 @@ package = "lua-resty-mlcache" -version = "2.5.0-1" +version = "2.6.0-1" source = { url = "git://github.com/thibaultcha/lua-resty-mlcache", - tag = "2.5.0" + tag = "2.6.0" } description = { summary = "Layered caching library for OpenResty",