-
Notifications
You must be signed in to change notification settings - Fork 16
connect 모듈
connect 모듈의 최초 진입은 memcached_connect() 함수로 시작됩니다.
memcached_connect() 함수는 memcached 객체가 arcus-memcached 서버와 통신을 하기 위해 연결을 수립하는 기능을 수행합니다. 이 과정에서 다른 함수들을 호출하는데, 그 함수들은 다음과 같습니다.
- backoff_handling() - arcus-memcached 서버의 상태가 timeout 상태라면 retry time 조건을 만족하는지 확인하는 함수
- network_connect() - 실제 연결을 시도하는 함수
- memcached_version_instance() - 연결이 수립되었을 때 arcus-memcached의 version에 따라 다른 통신 프로토콜을 사용하기 위해 arcus-memcached 서버의 version을 요청하는 함수
- memcached_mark_server_for_timeout() - 연결을 시도했으나 연결이 수립되지 않았을 때 arcus-memcached 서버 상태를 timeout 상태로 마크하는 함수
memcached_connect() 함수는 실제 연결 시도를 하기 전에 backoff_handling() 함수를 먼저 호출하여 현재 arcus-memcached 서버 상태가 연결을 시도하기에 적합한 상태인지 확인합니다.
server 객체의 상태가 timeout이 아니면 연결을 시도하기에 적합한 것으로 판별합니다.
server 객체의 상태가 timeout이면 현재 시간이 마지막으로 연결 실패한 시간보다 설정 값(default 1초) 이상 시간이 흘렀다면 연결을 다시 시도하기 적합한 상태로 판별하고, 그렇지 않으면 부적합한 상태로 판별합니다.
memcached_connect() 함수 내에서 실제 연결 시도를 수행하는 함수입니다.
우선 server 객체에 연결을 해야 하는 host 정보가 저장되어 있지 않을 경우, set_hostinfo() 함수를 호출하여 host 정보를 저장합니다.
-
set_hostinfo() 함수에서는 getaddrinfo() system call을 이용해 hostname과 port로 구성된 정보를 addrinfo 구조체 형태로 변환하여 server 객체에 저장합니다.
-
getaddrinfo() system call에서 EAI_AGAIN 이외의 에러가 발생할 경우 최대 5회 set_hostinfo() 함수를 재시도합니다.
-
EAI_AGAIN 에러가 발생할 경우에는 network timeout 상태이므로 set_hostinfo() 함수를 재시도 하지 않고 연결 실패로 간주합니다.
-
set_socket_nonblocking() 함수를 호출합니다. set_socket_nonblocking() 함수에서는 fcntl() system call을 통해 socket을 non-blocking 모드로 동작하도록 해줍니다.
set_hostinfo() 함수에서 host 정보가 저장된 후에는 network_connect() 함수에서 socket() system call을 통해 socket file descriptor를 할당 받습니다.
socket() system call에서 에러가 발생한 경우 연결 실패로 간주합니다.
socket file descriptor를 할당 받은 후에는 set_socket_options() 함수를 호출하여 필요한 socket 옵션들을 setsockopt() system call로 설정합니다.
set_socket_options() 함수를 호출한 뒤 connect() system call을 통해 연결을 시도합니다.
connect() system call에서 에러가 발생하지 않았다면 곧바로 연결이 수립된 것으로 판별합니다.
socket이 non-blocking 모드로 설정되어 있기 때문에 EWOULDBLOCK, EINPROGRESS, EALREADY 에러가 발생하는 경우에는 연결 수립을 맺는 중으로 판별하여 connect_poll() 함수를 호출합니다.
-
poll() system call을 통해 socket이 write 가능한 상태인지 판별합니다.
-
poll() system call이 interrupt에 의해 실패한 경우에는 최대 5회까지 재시도를 합니다.
-
그 외의 에러가 발생한 경우에는 연결 실패로 간주합니다.
connect_poll() 함수에서 poll() system call이 성공했다면 network_connect() 함수에서 연결 수립이 완료되었다고 판별합니다.
network_connect() 함수에서 연결이 수립된 이후, arcus-memcached 서버 version에 따라 통신 프로토콜 다르게 하기 위해서 memcached_version_instance() 함수를 통해 내부적으로 version 연산을 수행합니다.
내부적으로 수행하는 연산이라는 점을 제외하면 arcus-c-client를 통한 version 연산 호출과 동일한 원리로 동작합니다.
network_connect() 함수에서 연결이 수립되지 않았을 경우에 호출하는 함수입니다.
server 객체의 상태를 timeout으로 마크하고 연결을 재시도할 시간을 결정합니다.
기본 설정 값은 연결에 실패하고 1초 뒤에 재시도 하도록 되어 있으나, 조건에 따라서는 곧바로 재시도 할 수 있게 설정합니다.
어떤 경우에 곧바로 재시도 할 수 있도록 설정하는 지는 response 모듈에서 다루도록 하겠습니다.