Skip to content

Commit

Permalink
Add schema reload counter to stats
Browse files Browse the repository at this point in the history
Add counter of schema reloads in calls to module statistics. Schema
reloads are counted over all spaces and stored in top level, like
`space_not_found` counter.

```
crud.stats().schema_reloads
---
- 2
...

```

In metrics, they are stored in `tnt_crud_schema_reloads` counter.

Part of #224
  • Loading branch information
DifferentialOrange committed Feb 4, 2022
1 parent a827ab3 commit 85d2108
Show file tree
Hide file tree
Showing 7 changed files with 134 additions and 1 deletion.
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -622,6 +622,7 @@ crud.stats()
count: 4
time: 0.000004
space_not_found: 0
schema_reloads: 0
...
crud.stats('my_space')
---
Expand All @@ -642,7 +643,9 @@ field will be empty. If no operations has been called for a
space, it will not be represented. Operations called for
spaces not found both on storages and in statistics registry
(including cases when crud can't verify space existence)
will increment `space_not_found` counter.
will increment `space_not_found` counter. Operation calls
that reloaded a schema will increment `schema_reloads`
counter.

Possible statistics operation labels are
`insert` (for `insert` and `insert_object` calls),
Expand Down
8 changes: 8 additions & 0 deletions crud/common/schema.lua
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ local ReloadSchemaError = errors.new_class('ReloadSchemaError', {capture_stack =

local const = require('crud.common.const')
local dev_checks = require('crud.common.dev_checks')
local fiber_context = require('crud.common.fiber_context')

local schema = {}

Expand Down Expand Up @@ -103,6 +104,13 @@ function schema.wrap_func_reload(func, ...)
end
end

local context_stats = fiber_context.init_section('router_stats')
if context_stats.schema_reloads == nil then
context_stats.schema_reloads = i
else
context_stats.schema_reloads = context_stats.schema_reloads + i
end

return res, err
end

Expand Down
18 changes: 18 additions & 0 deletions crud/stats/local_registry.lua
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ function registry.init()
internal.registry = {}
internal.registry.spaces = {}
internal.registry.space_not_found = 0
internal.registry.schema_reloads = 0

return true
end
Expand Down Expand Up @@ -180,4 +181,21 @@ function registry.observe_map_reduces(count, space_name)
return true
end

--- Increase statistics of schema reloads
--
-- @function observe_schema_reloads
--
-- @tparam number count
-- Schema reloads performed.
--
-- @treturn boolean Returns true.
--
function registry.observe_schema_reloads(count)
dev_checks('number')

internal.registry.schema_reloads = internal.registry.schema_reloads + count

return true
end

return registry
4 changes: 4 additions & 0 deletions crud/stats/module.lua
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,10 @@ local function wrap_tail(space_name, op, pairs, start_time, call_status, ...)
registry.observe_map_reduces(context_stats.map_reduces, space_name)
end

if context_stats.schema_reloads ~= nil then
registry.observe_schema_reloads(context_stats.schema_reloads)
end

fiber_context.drop_section('router_stats')
end

Expand Down
39 changes: 39 additions & 0 deletions test/entrypoint/srv_stats.lua
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,45 @@ package.preload['customers-storage'] = function()
unique = false,
if_not_exists = true,
})

rawset(_G, 'create_space', function()
local change_customers_space = box.schema.space.create('change_customers', {
format = {
{name = 'id', type = 'unsigned'},
{name = 'bucket_id', type = 'unsigned'},
{name = 'value', type = 'string'},
},
if_not_exists = true,
engine = engine,
})

-- primary index
change_customers_space:create_index('id_index', {
parts = { {field = 'id'} },
if_not_exists = true,
})
end)

rawset(_G, 'create_bucket_id_index', function()
box.space.change_customers:create_index('bucket_id', {
parts = { {field = 'bucket_id'} },
if_not_exists = true,
unique = false,
})
end)

rawset(_G, 'set_value_type_to_unsigned', function()
local new_format = {}

for _, field_format in ipairs(box.space.change_customers:format()) do
if field_format.name == 'value' then
field_format.type = 'unsigned'
end
table.insert(new_format, field_format)
end

box.space.change_customers:format(new_format)
end)
end,
}
end
Expand Down
47 changes: 47 additions & 0 deletions test/integration/stats_test.lua
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ local space_id = 542
local space_name = 'customers'
local unknown_space_name = 'non_existing_space'
local new_space_name = 'newspace'
local schema_change_space_name = 'change_customers'

g.before_all(function(g)
g.cluster = helpers.Cluster:new({
Expand All @@ -37,6 +38,7 @@ g.before_each(function(g)
g.router:eval("crud = require('crud')")
helpers.truncate_space_on_cluster(g.cluster, space_name)
helpers.drop_space_on_cluster(g.cluster, new_space_name)
helpers.drop_space_on_cluster(g.cluster, schema_change_space_name)
end)

function g:get_stats(space_name)
Expand Down Expand Up @@ -724,3 +726,48 @@ g.test_spaces_dropped_in_runtime_supported_with_stats = function(g)
t.assert_equals(op_after.error.count - op_before.error.count, 1,
"Error requests count incremented since space was known to registry before drop")
end


-- luacheck: max comment line length 150
-- Based on https://github.com/tarantool/crud/blob/76e33749226d5fd1195e2628502a9e01d6a616fa/test/integration/updated_shema_test.lua#L622
local function perform_insert_call_with_schema_reload(g)
-- create space w/ bucket_id index
helpers.call_on_servers(g.cluster, {'s1-master', 's2-master'}, function(server)
server.net_box:call('create_space')
server.net_box:call('create_bucket_id_index')
end)

-- value should be string error
local obj, err = g.router:call(
'crud.insert_object', { schema_change_space_name, { id = 11, value = 123 } }
)

t.assert_equals(obj, nil)
t.assert_is_not(err, nil)
t.assert_str_contains(err.err, "type does not match one required by operation: expected string")

-- set value type to unsigned
helpers.call_on_servers(g.cluster, {'s1-master', 's2-master'}, function(server)
server.net_box:call('set_value_type_to_unsigned')
end)

-- check that schema changes were applied
-- insert value unsigned - OK
local obj, err = g.router:call(
'crud.insert_object', { schema_change_space_name, { id = 11, value = 123 } }
)

t.assert_is_not(obj, nil)
t.assert_equals(err, nil)
end

g.test_call_with_schema_reload_increments_counter = function(g)
local stats_before = g:get_stats()

perform_insert_call_with_schema_reload(g)

local stats_after = g:get_stats()

t.assert_gt(stats_after.schema_reloads, stats_before.schema_reloads,
"Schema reloads counter incremented")
end
14 changes: 14 additions & 0 deletions test/unit/stats_test.lua
Original file line number Diff line number Diff line change
Expand Up @@ -530,6 +530,20 @@ g.test_map_reduce_increment = function(g)
"Counter of map reduces incremented")
end

g.test_schema_reload = function(g)
local op = stats_module.op.INSERT
local inc = 1

local _, err = g.router:eval(eval_with_fiber_context_setup,
{ op, space_name, 'schema_reloads', inc })
t.assert_equals(err, nil)

local stats = g:get_stats()

t.assert_equals(stats.schema_reloads, inc,
"Counter of map reduces incremented")
end

g.test_resolve_name_from_id = function(g)
local op = stats_module.op.LEN
g.router:eval(call_wrapped, { 'return_true', stats_module.op.LEN, {}, space_id })
Expand Down

0 comments on commit 85d2108

Please sign in to comment.