Skip to content

Commit a038a72

Browse files
api: support vshard groups
This patch adds Cartridge vshard groups [1] and non-default vshard router [2] support to CRUD operations. To specify Cartridge vshard group, pass vshard group name with `vshard_router` option of a crud operation. ```lua crud.select('customers_ddl', {{'=', 'age', 41}}, {vshard_router = 'customers'}) ``` To use non-default vshard router, pass vshard router object with `vshard_router` option of a crud operation. ```lua local router = vshard.router.new(cfg) crud.select('customers_ddl', {{'=', 'age', 41}}, {vshard_router = router}) ``` If `vshard_router` is not specified, default vshard router is used to process the request. If default vshard router is not found (for example, if it is a Cartridge application with vshard groups) and option is not specified, the error is returned. 1. https://www.tarantool.io/en/doc/latest/book/cartridge/cartridge_dev/#using-multiple-vshard-storage-groups 2. https://www.tarantool.io/ru/doc/latest/reference/reference_rock/vshard/vshard_router/#router-api-new Closes #44
1 parent 37c7f4b commit a038a72

24 files changed

+2260
-77
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
77

88
## [Unreleased]
99

10+
### Added
11+
* Support `vshard_router` option in operations for Cartridge vshard groups
12+
or non-default vshard routers (#44).
13+
1014
### Changed
1115
* Deprecate using space id in `crud.len` (#255).
1216

README.md

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,9 @@ where:
207207
* `timeout` (`?number`) - `vshard.call` timeout (in seconds)
208208
* `bucket_id` (`?number|cdata`) - bucket ID
209209
* `fields` (`?table`) - field names for getting only a subset of fields
210+
* `vshard_router` (`?string|table`) - Cartridge vshard group name or
211+
vshard router instance. Set this parameter if your space is not
212+
a part of the default vshard cluster
210213

211214
Returns metadata and array contains one inserted row, error.
212215

@@ -259,6 +262,9 @@ where:
259262
* `rollback_on_error` (`?boolean`) - any failed operation will lead to
260263
rollback on a storage, where the operation is failed, report error
261264
about what tuples were rollback, default is `false`
265+
* `vshard_router` (`?string|table`) - Cartridge vshard group name or
266+
vshard router instance. Set this parameter if your space is not
267+
a part of the default vshard cluster
262268

263269
Returns metadata and array with inserted rows, array of errors.
264270
Each error object can contain field `operation_data`.
@@ -393,6 +399,9 @@ where:
393399
* `prefer_replica` (`?boolean`) - if `true` then the preferred target is one of
394400
the replicas
395401
* `balance` (`?boolean`) - use replica according to vshard load balancing policy
402+
* `vshard_router` (`?string|table`) - Cartridge vshard group name or
403+
vshard router instance. Set this parameter if your space is not
404+
a part of the default vshard cluster
396405

397406
Returns metadata and array contains one row, error.
398407

@@ -426,6 +435,9 @@ where:
426435
* `timeout` (`?number`) - `vshard.call` timeout (in seconds)
427436
* `bucket_id` (`?number|cdata`) - bucket ID
428437
* `fields` (`?table`) - field names for getting only a subset of fields
438+
* `vshard_router` (`?string|table`) - Cartridge vshard group name or
439+
vshard router instance. Set this parameter if your space is not
440+
a part of the default vshard cluster
429441

430442
Returns metadata and array contains one updated row, error.
431443

@@ -458,6 +470,9 @@ where:
458470
* `timeout` (`?number`) - `vshard.call` timeout (in seconds)
459471
* `bucket_id` (`?number|cdata`) - bucket ID
460472
* `fields` (`?table`) - field names for getting only a subset of fields
473+
* `vshard_router` (`?string|table`) - Cartridge vshard group name or
474+
vshard router instance. Set this parameter if your space is not
475+
a part of the default vshard cluster
461476

462477
Returns metadata and array contains one deleted row (empty for vinyl), error.
463478

@@ -492,6 +507,9 @@ where:
492507
* `timeout` (`?number`) - `vshard.call` timeout (in seconds)
493508
* `bucket_id` (`?number|cdata`) - bucket ID
494509
* `fields` (`?table`) - field names for getting only a subset of fields
510+
* `vshard_router` (`?string|table`) - Cartridge vshard group name or
511+
vshard router instance. Set this parameter if your space is not
512+
a part of the default vshard cluster
495513

496514
Returns inserted or replaced rows and metadata or nil with error.
497515

@@ -544,6 +562,9 @@ where:
544562
* `rollback_on_error` (`?boolean`) - any failed operation will lead to
545563
rollback on a storage, where the operation is failed, report error
546564
about what tuples were rollback, default is `false`
565+
* `vshard_router` (`?string|table`) - Cartridge vshard group name or
566+
vshard router instance. Set this parameter if your space is not
567+
a part of the default vshard cluster
547568

548569
Returns metadata and array with inserted/replaced rows, array of errors.
549570
Each error object can contain field `operation_data`.
@@ -676,6 +697,9 @@ where:
676697
* `timeout` (`?number`) - `vshard.call` timeout (in seconds)
677698
* `bucket_id` (`?number|cdata`) - bucket ID
678699
* `fields` (`?table`) - field names for getting only a subset of fields
700+
* `vshard_router` (`?string|table`) - Cartridge vshard group name or
701+
vshard router instance. Set this parameter if your space is not
702+
a part of the default vshard cluster
679703

680704
Returns metadata and empty array of rows or nil, error.
681705

@@ -733,6 +757,9 @@ where:
733757
* `rollback_on_error` (`?boolean`) - any failed operation will lead to
734758
rollback on a storage, where the operation is failed, report error
735759
about what tuples were rollback, default is `false`
760+
* `vshard_router` (`?string|table`) - Cartridge vshard group name or
761+
vshard router instance. Set this parameter if your space is not
762+
a part of the default vshard cluster
736763

737764
Returns metadata and array of errors.
738765
Each error object can contain field `operation_data`.
@@ -869,6 +896,9 @@ where:
869896
* `prefer_replica` (`?boolean`) - if `true` then the preferred target is one of
870897
the replicas
871898
* `balance` (`?boolean`) - use replica according to vshard load balancing policy
899+
* `vshard_router` (`?string|table`) - Cartridge vshard group name or
900+
vshard router instance. Set this parameter if your space is not
901+
a part of the default vshard cluster
872902

873903

874904
Returns metadata and array of rows, error.
@@ -1007,6 +1037,9 @@ where:
10071037
* `space_name` (`string`) - name of the space
10081038
* `opts`:
10091039
* `timeout` (`?number`) - `vshard.call` timeout (in seconds)
1040+
* `vshard_router` (`?string|table`) - Cartridge vshard group name or
1041+
vshard router instance. Set this parameter if your space is not
1042+
a part of the default vshard cluster
10101043

10111044
Returns true or nil with error.
10121045

@@ -1040,6 +1073,9 @@ where:
10401073
* `space_name` (`string`) - name of the space
10411074
* `opts`:
10421075
* `timeout` (`?number`) - `vshard.call` timeout (in seconds)
1076+
* `vshard_router` (`?string|table`) - Cartridge vshard group name or
1077+
vshard router instance. Set this parameter if your space is not
1078+
a part of the default vshard cluster
10431079

10441080
Returns number or nil with error.
10451081

@@ -1089,6 +1125,7 @@ where:
10891125
* `opts`:
10901126
* `timeout` (`?number`) - maximum time (in seconds, default: 2) to wait for response from
10911127
cluster instances.
1128+
* `vshard_router` (`?string|table`) - Cartridge vshard group name or vshard router instance.
10921129

10931130
Returns storages status table by instance UUID or nil with error. Status table fields:
10941131
* `status` contains a string representing the status:
@@ -1158,6 +1195,9 @@ where:
11581195
* `balance` (`?boolean`) - use replica according to
11591196
[vshard load balancing policy](https://www.tarantool.io/en/doc/latest/reference/reference_rock/vshard/vshard_api/#router-api-call),
11601197
default value is `false`
1198+
* `vshard_router` (`?string|table`) - Cartridge vshard group name or
1199+
vshard router instance. Set this parameter if your space is not
1200+
a part of the default vshard cluster
11611201

11621202
```lua
11631203
crud.count('customers', {{'==', 'age', 35}})

crud/borders.lua

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
local checks = require('checks')
22
local errors = require('errors')
3-
local vshard = require('vshard')
43

54
local const = require('crud.common.const')
65
local dev_checks = require('crud.common.dev_checks')
@@ -71,10 +70,9 @@ local function call_get_border_on_router(vshard_router, border_name, space_name,
7170
checks('table', 'string', 'string', '?string|number', {
7271
timeout = '?number',
7372
fields = '?table',
73+
vshard_router = '?string|table',
7474
})
7575

76-
opts = opts or {}
77-
7876
local replicasets = vshard_router:routeall()
7977
local space = utils.get_space(space_name, replicasets)
8078
if space == nil then
@@ -160,7 +158,11 @@ local function call_get_border_on_router(vshard_router, border_name, space_name,
160158
end
161159

162160
local function get_border(border_name, space_name, index_name, opts)
163-
local vshard_router = vshard.router.static
161+
opts = opts or {}
162+
local vshard_router, err = utils.get_vshard_router_instance(opts.vshard_router)
163+
if err ~= nil then
164+
return nil, BorderError:new(err)
165+
end
164166

165167
return schema.wrap_func_reload(vshard_router, call_get_border_on_router,
166168
border_name, space_name, index_name, opts
@@ -183,6 +185,11 @@ end
183185
-- @tparam ?table opts.fields
184186
-- Field names for getting only a subset of fields
185187
--
188+
-- @tparam ?string|table opts.vshard_router
189+
-- Cartridge vshard group name or vshard router instance.
190+
-- Set this parameter if your space is not a part of the
191+
-- default vshard cluster.
192+
--
186193
-- @return[1] result
187194
-- @treturn[2] nil
188195
-- @treturn[2] table Error description
@@ -206,6 +213,11 @@ end
206213
-- @tparam ?table opts.fields
207214
-- Field names for getting only a subset of fields
208215
--
216+
-- @tparam ?string|table opts.vshard_router
217+
-- Cartridge vshard group name or vshard router instance.
218+
-- Set this parameter if your space is not a part of the
219+
-- default vshard cluster.
220+
--
209221
-- @return[1] result
210222
-- @treturn[2] nil
211223
-- @treturn[2] table Error description

crud/common/sharding_func.lua

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
local log = require('log')
2-
local vshard = require('vshard')
32

43
local sharding_metadata_module = require('crud.common.sharding.sharding_metadata')
4+
local utils = require('crud.common.utils')
55

66
local sharding_func_cache = {}
77

@@ -15,8 +15,9 @@ function sharding_func_cache.update_cache(space_name, vshard_router)
1515
log.warn("require('crud.common.sharding_func').update_cache()" ..
1616
"is deprecated and will be removed in future releases")
1717

18-
if vshard_router == nil then
19-
vshard_router = vshard.router.static
18+
local vshard_router, err = utils.get_vshard_router_instance(vshard_router)
19+
if err ~= nil then
20+
return nil, err
2021
end
2122

2223
return sharding_metadata_module.update_sharding_func_cache(vshard_router, space_name)

crud/common/sharding_key.lua

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
local log = require('log')
2-
local vshard = require('vshard')
32

43
local sharding_metadata_module = require('crud.common.sharding.sharding_metadata')
4+
local utils = require('crud.common.utils')
55

66
local sharding_key_cache = {}
77

@@ -13,8 +13,9 @@ function sharding_key_cache.update_cache(space_name, vshard_router)
1313
log.warn("require('crud.common.sharding_key').update_cache()" ..
1414
"is deprecated and will be removed in future releases")
1515

16-
if vshard_router == nil then
17-
vshard_router = vshard.router.static
16+
local vshard_router, err = utils.get_vshard_router_instance(vshard_router)
17+
if err ~= nil then
18+
return nil, err
1819
end
1920

2021
return sharding_metadata_module.update_sharding_key_cache(vshard_router, space_name)

crud/common/utils.lua

Lines changed: 85 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ local fun = require('fun')
55
local bit = require('bit')
66
local log = require('log')
77

8+
local is_cartridge, cartridge = pcall(require, 'cartridge')
9+
810
local const = require('crud.common.const')
911
local schema = require('crud.common.schema')
1012
local dev_checks = require('crud.common.dev_checks')
@@ -17,6 +19,7 @@ local GetSpaceFormatError = errors.new_class('GetSpaceFormatError', {capture_sta
1719
local FilterFieldsError = errors.new_class('FilterFieldsError', {capture_stack = false})
1820
local NotInitializedError = errors.new_class('NotInitialized')
1921
local StorageInfoError = errors.new_class('StorageInfoError')
22+
local VshardRouterError = errors.new_class('VshardRouterError', {capture_stack = false})
2023
local fiber_clock = require('fiber').clock
2124

2225
local utils = {}
@@ -758,16 +761,23 @@ end
758761
-- @tparam ?number opts.timeout
759762
-- Function call timeout
760763
--
764+
-- @tparam ?string|table opts.vshard_router
765+
-- Cartridge vshard group name or vshard router instance.
766+
--
761767
-- @return a table of storage states by replica uuid.
762768
function utils.storage_info(opts)
763-
local vshard_router = vshard.router.static
769+
opts = opts or {}
770+
771+
local vshard_router, err = utils.get_vshard_router_instance(opts.vshard_router)
772+
if err ~= nil then
773+
return nil, StorageInfoError:new(err)
774+
end
775+
764776
local replicasets, err = vshard_router:routeall()
765777
if replicasets == nil then
766-
return nil, StorageInfoError:new("Failed to get all replicasets: %s", err.err)
778+
return nil, StorageInfoError:new("Failed to get router replicasets: %s", err.err)
767779
end
768780

769-
opts = opts or {}
770-
771781
local futures_by_replicas = {}
772782
local replica_state_by_uuid = {}
773783
local async_opts = {is_async = true}
@@ -835,4 +845,75 @@ function utils.storage_info_on_storage()
835845
return {status = "running"}
836846
end
837847

848+
local expected_vshard_api = {
849+
'routeall', 'route', 'bucket_id_strcrc32',
850+
'callrw', 'callro', 'callbro', 'callre',
851+
'callbre', 'map_callrw'
852+
}
853+
854+
--- Verifies that a table has expected vshard
855+
-- router handles.
856+
local function verify_vshard_router(router)
857+
dev_checks("table")
858+
859+
for _, func_name in ipairs(expected_vshard_api) do
860+
if type(router[func_name]) ~= 'function' then
861+
return false
862+
end
863+
end
864+
865+
return true
866+
end
867+
868+
--- Get a vshard router instance from a parameter.
869+
--
870+
-- If a string passed, extract router instance from
871+
-- Cartridge vshard groups. If table passed, verifies
872+
-- that a table is a vshard router instance.
873+
--
874+
-- @function get_vshard_router_instance
875+
--
876+
-- @param[opt] router name of a vshard group or a vshard router
877+
-- instance
878+
--
879+
-- @return[1] table vshard router instance
880+
-- @treturn[2] nil
881+
-- @treturn[2] table Error description
882+
function utils.get_vshard_router_instance(router)
883+
dev_checks('?string|table')
884+
885+
local router_instance
886+
887+
if type(router) == 'string' then
888+
if not is_cartridge then
889+
return nil, VshardRouterError:new("Vshard groups are supported only in Tarantool Cartridge")
890+
end
891+
892+
local router_service = cartridge.service_get('vshard-router')
893+
assert(router_service ~= nil)
894+
895+
router_instance = router_service.get(router)
896+
if router_instance == nil then
897+
return nil, VshardRouterError:new("Vshard group %s is not found", router)
898+
end
899+
elseif type(router) == 'table' then
900+
if not verify_vshard_router(router) then
901+
return nil, VshardRouterError:new("Invalid opts.vshard_router table value, " ..
902+
"a vshard router instance has been expected")
903+
end
904+
905+
router_instance = router
906+
else
907+
assert(type(router) == 'nil')
908+
router_instance = vshard.router.static
909+
910+
if router_instance == nil then
911+
return nil, VshardRouterError:new("Default vshard group is not found and custom " ..
912+
"is not specified with opts.vshard_router")
913+
end
914+
end
915+
916+
return router_instance
917+
end
918+
838919
return utils

0 commit comments

Comments
 (0)