jdesgats / ljsonschema

Pure Lua JSON schema validator
MIT License
46 stars 21 forks source link

how to cache the generated validator ? #11

Closed Mryashbhardwaj closed 4 years ago

Mryashbhardwaj commented 4 years ago

adding this as an issue because I could not find another way to reach out.

-- Note: do cache the result of schema compilation as this is a quite
-- expensive process

I read the above in the examples given, but I am not able to figure out what to cache exactly. can you please share an example of caching the compiled schema

Tieske commented 4 years ago
-- Note: do cache the result of schema compilation as this is a quite
-- expensive process
local myvalidator = jsonschema.generate_validator {
  type = 'object',
  properties = {
    foo = { type = 'string' },
    bar = { type = 'number' },
  },
}

After this code runs myvalidator is a function. That is the function you should retain and cache, instead of calling jsonschema.generate_validator over and over again.

jdesgats commented 4 years ago

Yeah, one common pattern if you know the schemas in advance is to compile them at the module level:

local jsonschema = require 'jsonschema'
local _M = {} -- module exports

-- at module level
local myvalidator = jsonschema.generate_validator { ... }

function _M.some_function(obj)
    local result = myvalidator(obj)
    ...
end

return _M
Mryashbhardwaj commented 4 years ago

@jdesgats in my use case, these schemas are not predefined, and they will change as well (we also need to purge cached validators). Also we have more than one nginx workers.

@Tieske, i want to understand how to cache functions

Tieske commented 4 years ago

pseudo code, using an lru-cache:

local run_validator do
  local lru = resty.lru(100)

  run_validator = function(data, schema)
    local f = lru:get(f)

    if not f then
      f = resty_lsjonschema.generate(schema)
      lru:set(schema, f)
    end

    return f(data)
  end
end