tarantool/vshard

map_callrw can't find c stored procedure

vol0n opened this issue · 4 comments

vol0n commented

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.