map_callrw can't find c stored procedure
vol0n opened this issue · 4 comments
Problem
We have a c stored procedure execute
, earlier we called it via replicaset api like this:
replica:callbre(
'execute',
args,
{ is_async = true }
)
Now we've started to use map_callrw
router api, which gives us an error saying it is not defined:
router.map_callrw('execute', args)
---
- null
- code: 33
base_type: ClientError
type: ClientError
message: Procedure 'execute' is not defined
trace: [{'file': './src/box/lua/call.c', 'line': 112}]
- 5bb12a3c-4de8-4059-8172-8c926d6a6bc2
...
The function was created like this:
box.schema.func.create(
'execute',
{ if_not_exists = true, language = 'C' }
)
And it is callable through box.func api:
box.func['execute']:call()
---
- error: 'Failed to decode dispatched data: Invalid(Tuple, Some("expected
tuple of 2 elements, got 0"))'
...
Tarantool version: 2.11.0
Vshard version: latest
Hint
After digging a bit in the code I found that map_callrw(f, args)
calls storage_map(f, args)
, the latter calls net.box.self.call(f, args)
and this internally in tarantool calls box_lua_find
which tries to find the function in lua globals.
On the other hand, replica:callbre(f, args)
calls net.box.conn.call
, the latter first checks whether the function is in cache and only then uses box_lua_find
.
So the problem seems to be in using self.call
inside storage_map
Thank you for digging! The issue is blocked by tarantool/tarantool#9131
Can we just always use box.func
? netbox.self
is used because in the old times it was the only way to call a local function without requiring its Lua or C module.
Sure, we can. But it doesn't change the fact, that netbox.self
doesn't work.
It does mean that the ticket is not blocked though. I suggest we drop the 'blocked' label.