expirationd icon indicating copy to clipboard operation
expirationd copied to clipboard

Make expiratind worker start delayed until an is_expired function is available

Open WeCodingNow opened this issue 2 years ago • 2 comments

Right now the expirationd worker start can be delayed until the space it is supposed to scan is created However, there is no such mechanism for the is_expired function.

Consider this scenario:

  • cartridge-extensions is used
  • we want to inject the function we would use as the is_expired function through cartridge-extensions
  1. supply a function to be used as the is_expired function
  2. configure expiratoind to use this function

Like this (in clusterwide config):

extensions/expiration.lua
local M = {}

local fiber = require('fiber')

function M.check_ttl(args, tuple)
    local now = fiber.time()
    local ttl = tuple[args.ttl_field]
    local timestamp = tuple[args.timestamp_field]

    if (ttl == nil or timestamp == nil) then
        return false
    end

    return now > timestamp + ttl
end

return M
extensions/config.yml
functions:
  check_ttl:
    module: extensions.expiration
    handler: check_ttl
    events:
    - binary:
        path: __check_ttl
expirationd.yml
# tasks
expire_session:
  space: session
  is_expired: __check_ttl
  options:
    args:
      ttl_field: max_inactive_interval
      timestamp_field: last_accessed_time
  is_master_only: true

This scenario would work until a restart of one instance occurs. After the restart, an error as this would occur:

text
myapp.s2-1 | 2023-03-10 16:36:10.086 [32983] main/103/init.lua confapplier.lua:156 E> Instance entering failed state: ConfigFound -> InitError
myapp.s2-1 | ValidateConfigError: ...p/.rocks/share/tarantool/cartridge/roles/expirationd.lua:188: ...p/.rocks/share/tarantool/cartridge/roles/expirationd.lua:130: expirationd: is_expired must be a function name in _G
myapp.s2-1 | stack traceback:
myapp.s2-1 |    ...p/.rocks/share/tarantool/cartridge/roles/expirationd.lua:188: in function <...p/.rocks/share/tarantool/cartridge/roles/expirationd.lua:171>
myapp.s2-1 |    [C]: in function 'xpcall'
myapp.s2-1 |    ...ring_session_tnt/myapp/.rocks/share/tarantool/errors.lua:145: in function 'pcall'
myapp.s2-1 |    ...ion_tnt/myapp/.rocks/share/tarantool/cartridge/roles.lua:377: in function 'validate_config'
myapp.s2-1 |    ...t/myapp/.rocks/share/tarantool/cartridge/confapplier.lua:863: in function 'init'
myapp.s2-1 |    ...g_session_tnt/myapp/.rocks/share/tarantool/cartridge.lua:858: in function 'cfg'
myapp.s2-1 |    /home/bass/LocalCode/spring_session_tnt/myapp/init.lua:36: in main chunk
screenshot

image

The error is unfixable via configuration re-application, as you can't apply config in a cluster that is in error state.

As a solution, I think that this could be done:

  • relax the requirement on the is_tuple_expired argument so as to not require for the specified function to exist when the expirationd.start is called

WeCodingNow avatar Mar 10 '23 13:03 WeCodingNow

I want to better understand your motivation:

  1. Why can't you register the function in the application code?
  2. Why can't you register a wait-wrapper for the function in the application code?
  3. Is it possible to inherit a role from expirationd and to add a dependency from cartridge.extensions?

oleg-jukovec avatar Mar 10 '23 14:03 oleg-jukovec

It is possible to do all of that, however, the issue - being a feature proposal - proposes a feature that would allow me to do something that I can't at the moment.

The thing I can't do at the moment is: integrate cartridge-extensions module with expirationd module via registering functions in application config (as opposed to application code).

WeCodingNow avatar Mar 13 '23 09:03 WeCodingNow