Skip to content

feat: coio interface extension

Feodor Alexandrov requested to merge coio-interface-extension into picodata-submodule

Resolving of reachable remote domain

On registration of async getaddrinfo request via coio_ares_getaddrinfo firstly invokes the coio_ares_sock_state_cb which knows about latest socket state. Callback uses the socket state to register the corresponding events to async wait via libev.

When event ready, io callback from libev invokes and we call the ares_process_fd on the given file descriptor (socket) to check if request returned something. If it was - an addrinfo_cb invoked where we have access to the result pointer (via cb parameter) and destination pointer (via context) simultaneously and saves the result.

ares_process_fd changes the socket state and coio_ares_sock_state_cb invokes again to wake up the corresponding fiber and stop an io event.

running 1 test
test tarantool::network::client::tcp::tests::async_resolve_select_normal_behavior ... 

coio_ares_getaddrinfo("invalid.com"): <--------------for unreachable domain
	coio_ares_sock_state_cb():
		fiber(): 0x7efc51c00400
		socket_fd: 20
		read: 1
		write: 0
		(read || write) => ev_io_set()

coio_ares_getaddrinfo("ya.ru"): <----------------for reachable domain
	coio_ares_sock_state_cb():
		fiber(): 0x7efc51c00400 <----------------differrent fibers--------.
		socket_fd: 21                                                     |
		read: 1                                                           |
		write: 0                                                          |
		(read || write) => ev_io_set()                                    |
                                                                                  |
         <--------------------------------------------------------yield           |
                                                                                  |
coio_ares_io_cb("ya.ru"):                                                         |
	fiber(): 0x5635e6727860 <------------------------------------------------/
	revents: 1 (read)
	ares_process_fd():
		addrinfo_cb():
			request->fiber: 0x7efc51c00400
			status: 0 => Successful completion

			print_ares_addrinfo():
				ya.ru: 5.255.255.242

		coio_ares_sock_state_cb():
			fiber(): 0x5635e6727860
			socket_fd: 21
			read: 0
			write: 0
			fiber_wakeup()
			ev_io_stop()
ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 403 filtered out

Resolving local hosts by name

When localhost resolves by name aka "localhost" - coio_ares_sock_state_cb doesn't invokes. It is the reason to check if result ready immediately after coio_ares_getaddrinfo. Same is right for all records from /etc/hosts.

coio_ares_getaddrinfo("localhost"):
	addrinfo_cb():
		fiber(): 0x7f5574000400 <--------------------\ same fibers
		request->fiber: 0x7f5574000400 <-------------/
		status: 0 => Successful completion

		print_ares_addrinfo():
			localhost: 127.0.0.1

Resolving local hosts by ip

When localhost resolves by ip aka "127.0.0.1" - coio_ares_sock_state_cb will be invoked and result will be returned in a normal way via ares_process_fd and addrinfo_cb. Same is right for all records from /etc/hosts.

Resolving of unreachable remote domain

In this case coio_ares_io_cb invokes periodically until timeout occurred

coio_ares_getaddrinfo("invalid.com"):
	coio_ares_sock_state_cb():
		fiber(): 0x7f5574000400
		socket_fd: 20
		read: 1
		write: 0
		(read || write) => ev_io_set()

coio_ares_io_cb("invalid.com"):
	fiber(): 0x55ea92dac860
	revents: 1
	ares_process_fd():
		coio_ares_sock_state_cb(): <--------- read state was installed
			socket_fd: 21
			read: 1
			write: 0
			ev is active <-------------------- already active, and not set evt again

coio_ares_io_cb("invalid.com"):
	fiber(): 0x55ea92dac860
	revents: 1
	ares_process_fd():
			<----------------------------- nothing happens here, because still no changes:
						       just check state again and yield

coio_ares_timeout_cb():
^C
Edited by Feodor Alexandrov

Merge request reports