-
Notifications
You must be signed in to change notification settings - Fork 35
storage: preserve original error on function fail #629
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well done! I'm glad, you've figured out the reason 🎉
P.S. And please, don't forget to rebase)
949d8a9 to
80bd895
Compare
Serpentian
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Almost there! Well done
Serpentian
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Small nits are left
Serpentian
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for the patches! Well done
Gerold103
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the patch 💪!
| local function test_local_call_return_type_consistency_template(add_to_schema, | ||
| g) | ||
| g.replica_1_a:exec(function(add_to_schema) | ||
| rawset(_G, 'test_return_tuple', function() | ||
| return box.tuple.new({100, 200, 'tuple'}) | ||
| end) | ||
| if add_to_schema then | ||
| box.schema.func.create('test_return_tuple') | ||
| end | ||
| local status, result = ivshard.storage.call(1, | ||
| 'read', | ||
| 'test_return_tuple', | ||
| {}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The argument line wraps look malformed. Maybe make the function name shorter, or wrap all arguments to the next line like:
local function test_local_call_return_type_consistency_template(
add_to_schema, g)
...
Same with the ivshard.storage.call().
| if not func then | ||
| return pcall(netbox_self_call, netbox_self, func_name, args) | ||
| end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So if my function left a transaction unfinished, and it was called via netbox_self_call(), then netbox_self_call() will roll it back?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. If the function throws an error during an active transaction, the transaction is rolled back in handle_eval_result. If the function leaves the transaction unfinished, it is rolled back after the function completes
|
I ran some performance tests, and here are the results. SetupHardware Intel(R) Xeon(R) Gold 6230 CPU @ 2.10GHzTarantool Tarantool 2.11.0-0-g247a9a4183
Target: Linux-x86_64-Release
Build options: cmake . -DCMAKE_INSTALL_PREFIX=/usr/local -DENABLE_BACKTRACE=TRUE
Compiler: GNU-8.3.1
C_FLAGS: -fexceptions -funwind-tables -fasynchronous-unwind-tables -fno-common -fopenmp -msse2 -Wformat -Wformat-security -Werror=format-security -fstack-protector-strong -fPIC -fmacro-prefix-map=./tarantool=. -std=c11 -Wall -Wextra -Wno-gnu-alignof-expression -fno-gnu89-inline -Wno-cast-function-type
CXX_FLAGS: -fexceptions -funwind-tables -fasynchronous-unwind-tables -fno-common -fopenmp -msse2 -Wformat -Wformat-security -Werror=format-security -fstack-protector-strong -fPIC -fmacro-prefix-map=./tarantool=. -std=c++11 -Wall -Wextra -Wno-invalid-offsetof -Wno-gnu-alignof-expression -Wno-cast-function-type2 shards, 2 replicas in one shard, 9 routers, 9 load generators, which are created as follows: tarantool generate_load.lua \
--bucket_count 30000 \
--op_type replace \
--warmup \
--uri localhost:3305,localhost:3306,localhost:3307,localhost:3308,localhost:3309,localhost:3310,localhost:3311,localhost:3312,localhost:3313 \
--fibers 50 \
--ops 1000000 \Mean of 20 iterations The perf test is from https://github.com/tarantool/vshard-ee/pull/51, with registered replace function in schema.
|
|
Let's do only that variant:
The perf degradation is way too huge in the second variant. We'll leave #630 unresolved for now, since nobody complained about that yet. |
ee34ee2 to
4c6abe1
Compare
mrForza
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for the clean patch! 👍 Left some minor comments below
| end | ||
| local status, err = ivshard.storage.call(1, 'read', 'test_fail', {}) | ||
| ilt.assert_not(status) | ||
| local err_msg = tostring(err) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't need to convert the whole error into a string, because it will contain an excess data: code, base_type, type, trace. It can slightly slow down the assert_(not)_str_contains. We need only the message of this error.
Lets simplify it:
ilt.assert_str_contains(err.message, 'test_error')
ilt.assert_not_str_contains(err.message, 'Transaction is active')| end, {global_cfg}) | ||
| end | ||
|
|
||
| local function test_error_msg_is_preserved_template(add_to_schema, g) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: lets make this template function consistent with other ones: g argument should come first.
local function test_error_msg_is_preserved_template(g, add_to_schema)and it will be looked just a bit pretty in test_error_msg_is_preserved function:
test_error_msg_is_preserved_template(g, false)
test_error_msg_is_preserved_template(g, true)
vshard/storage/init.lua
Outdated
| -- transaction, then in Tarantool versions before 3.0.0-beta1-18, | ||
| -- the original error is replaced by the "Transaction is active" error. | ||
| -- We manually check if the function returned an error. If so, we | ||
| -- rollback the transaction to reveal the original error. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: the comment should be in the handle_eval_function.
then in Tarantool versions before 3.0.0-beta1-18
It happens everywhere, so no need to mention version
|
I can confirm, that @kamenkremen commit doesn't cause major perf degradation, so I remove However, @Gerold103, can we go even further and drop that piece of shit from net.box, which we don't need at all: local results = {...}
for i = 1, select('#', ...) do
if type(results[i]) == 'cdata' then
results[i] = msgpack.decode(msgpack.encode(results[i]))
end
end
return unpack(results)This breaks backward compatibility of 5 workers (load generators), 9 routers, 2 shards, 2 replicas in one shard. replaces. Before the patches: After Ivan`s commit: After two commits (Ivan's + Mine: #641): EditActually, we must fix it in core: tarantool/tarantool#11624 (comment). The inconsistency between versions is much more serious: the return type on router becomes This way we have the following backward compatibility breakage: when cdata is returned on old vshard versions, vshard automatically did table from it, from now on cdata itself is returned. IMHO, it's ok. |
In Tarantool versions prior to 3.0.0-beta1-18, `net_box.self.call()` cannot invoke C stored or Lua persistent functions. Therefore, if such a function is registered in `box.func`, vshard executes it via `func.call` instead. If such a function raises an error during an uncommitted transaction, 'Transaction is active...' error is going to be raised, which will mask the original error. This patch fixes that bug by checking the function call result. If the function returns an error and a transaction is still active, vshard now explicitly rolls back the transaction. Fixes tarantool#614 NO_DOC=bugfix
|
I think it is fine to just drop |
For older Tarantool versions vshard uses func.call to execute functions.
If such a function raises an error during an uncommitted transaction, 'Transaction is active...' error is going to be raised, which will mask the original error.
This patch fixes that bug by checking the function call result. If the function returns an error and a transaction is still active, vshard now explicitly rolls back the transaction.
Fixes #614
NO_DOC=bugfix