Skip to content
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

How can I use this client with tarantool queues? #33

Open
AndreyAlifanov opened this issue Oct 13, 2022 · 3 comments
Open

How can I use this client with tarantool queues? #33

AndreyAlifanov opened this issue Oct 13, 2022 · 3 comments

Comments

@AndreyAlifanov
Copy link

Hello!

I try to use this client with queues in tarantool (it's modified code from Simple.cpp). And can't do it in normal way.

int main()
{
	Connector<Buf_t, Net_t> client;
	Connection<Buf_t, Net_t> conn(client);
	int rc = client.connect(conn, {.address = address,
				       .service = std::to_string(port),
				       /*.user = ...,*/
				       /*.passwd = ...,*/
				       /* .transport = STREAM_SSL, */});
	if (rc != 0)
	{
		std::cerr << conn.getError().msg << std::endl;
		return -1;
	}

	rid_t f1 = conn.call("queue.create_tube", std::make_tuple("test", "fifo"));

	while (!conn.futureIsReady(f1))
	{
		if (client.wait(conn, f1, WAIT_TIMEOUT) != 0)
		{
			std::cerr << conn.getError().msg << std::endl;
			conn.reset();
		}
	}

	std::optional<Response<Buf_t>> response = conn.getResponse(f1);
	assert(response != std::nullopt);

	printResponse<Buf_t>(conn, *response); // this method from sample without modifications

	client.close(conn);

	return 0;
}

As result I get an error from conn.call:

RESPONSE ERROR: msg=unsupported Lua type 'function' line=/usr/src/tarantool/src/lua/utils.c file=/usr/src/tarantool/src/lua/utils.c errno=0 type=LuajitError code=32

But tube is created, in fact.

I guess, that I should use eval instead of call. But client doesn't contain this method.

So I have 2 questions:

  1. How to use this client with Tarantool queues properly?
  2. How to write wrappers for queue methods? Is it possible at all?
@AndreyAlifanov
Copy link
Author

I wrote wrapper for eval. And now I can use it in a such way:

//	rid_t f1 = conn.eval("queue.create_tube('test2', 'fifo')");
	rid_t f1 = conn.eval("queue.tube.test2:drop()");

In my case it works. But I'm not sure if I've done it correctly.

template<class BUFFER>
size_t
RequestEncoder<BUFFER>::encodeEval(const std::string &expr)
{
	iterator_t<BUFFER> request_start = m_Buf.end();
	m_Buf.write('\xce');
	m_Buf.write(uint32_t{0});
	encodeHeader(Iproto::EVAL);
	tnt::mpp::encode(m_Buf, tnt::mpp::as_map(std::forward_as_tuple(
		MPP_AS_CONST(Iproto::EXPR), expr)));
	uint32_t request_size = (m_Buf.end() - request_start) - PREHEADER_SIZE;
	++request_start;
	request_start.set(__builtin_bswap32(request_size));
	return request_size + PREHEADER_SIZE;
}

template<class BUFFER, class NetProvider>
rid_t
Connection<BUFFER, NetProvider>::eval(const std::string &expr)
{
	impl->enc.encodeEval(expr);
	impl->connector.readyToSend(*this);
	return RequestEncoder<BUFFER>::getSync();
}

@Totktonada
Copy link
Member

unsupported Lua type 'function'

It seems the same as tarantool/go-tarantool#94. I suggest to create a wrapper around queue.create_tube(), which will not return a function as part of the result.

local function queue_create_tube(...)
    queue.create_tube(...)
end

_G.queue_create_tube = queue_create_tube
box.schema.func.create('queue_create_tube', {if_not_exists = true})
box.schema.user.grant('username', 'execute', 'function', 'queue_create_tube', {
    if_not_exists = true
})

@AndreyAlifanov
Copy link
Author

Thank you for solution. I'll try it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants