-
Notifications
You must be signed in to change notification settings - Fork 16
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
INTERNAL: Call memcached_set_error() when version operation is failed on connect. #245
INTERNAL: Call memcached_set_error() when version operation is failed on connect. #245
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
리뷰 완료.
memcached_version_instance() 함수에 대해 검증하고 나서, 본 PR 처리하겠습니다.
9e38e1f
to
5716509
Compare
libmemcached/connect.cc
Outdated
@@ -662,6 +662,9 @@ memcached_return_t memcached_connect(memcached_server_write_instance_st server) | |||
{ | |||
memcached_mark_server_as_clean(server); | |||
rc= memcached_version_instance(server); | |||
if (memcached_failed(rc)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
memcached_version_instance 함수 또한 리턴 타입이
memcached_return_t 이므로
memcached_version_instance 함수에서 MEMCACHED_VERSION_FAILURE
을
리턴하는 것이 낫지 않나요?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
memcached_return_t memcached_version_instance(memcached_server_st *instance)
{
if (instance && instance->root)
{
if (instance->root->flags.use_udp)
{
return MEMCACHED_NOT_SUPPORTED;
}
if (instance->root->flags.binary_protocol)
{
return version_binary_instance(instance);
}
return version_ascii_instance(instance);
}
return MEMCACHED_INVALID_ARGUMENTS;
}
현재 memcached_version_instance
함수를 호출하고 있는 쪽은
memcached_connect
하나 뿐이며, 반환한다면 MEMCACHED_INVALID_ARGUMENTS
대신
MEMCACHED_VERSION_FAILURE
호출하는 편이 낫다고 생각됩니다.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
server 객체에 에러 메세지와 같이 에러에 관한 정보를 설정하는 함수가 memcached_set_error() 함수입니다.
MEMCACHED_VERSION_FAILURE 에러에 관한 정보를 server 객체에 저장하여 사용자가 MEMCACHED_VERSION_FAILURE 에러를 받았을 때 이에 관한 정보를 server 객체를 통해 확인하도록 하기 위함입니다.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
rc= memcached_connect(instance);
if (memcached_failed(rc))
{
memcached_set_error(*instance, rc, MEMCACHED_AT);
hosts_failed[serverkey]= true;
continue;
}
그 경우 memcached_connect 함수 호출 이후 위의 로직을 부르고 있는데,
이 때에 set_error가 되지 않나요?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
memcached_connect() 함수를 호출하는 부분이 거기에만 있는 것이 아니라서요.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
제가 확인한 부분에서는 memcached_connect를 사용하는 방식은
앞의 방식과 아래의 방식을 사용합니다.
if (memcached_failed(memcached_connect(instance)))
return 0;
자세한 에러 원인을 설정하지 않더라도 적어도 fail에 대해서 처리를 하고 있는데,
혹시 다른 사용 방식이 있나요?
해당 PR에 대한 제 생각과 @uhm0311 님과 offline으로 들었던 내용 정리입니다. 저는 Version_failure를 설정한다면, connect 쪽보다는 그리고 이에 대한 set_error의 경우 드는 생각은 다음 2가지 입니다.
궁금한 점
|
해당 경우를 상정한 것이 맞습니다. |
연산에서 연산 명령어 보내기 전 memcached_connect를 통해 version 명령어를 보내는데, 해당 연산의 write/read 결과 실패와 version 명령어 write/read 결과 실패를 나누어야 하는 이유에 대해 궁금했습니다;; 그리고 memcached_connect 는 외부 API로 사용하나요?
이 말은 중복으로 들어가게끔 만든 것이라는 말인가요? 아니면 중복으로 안 들어가게끔 구현한 것이라는 말인가요? |
저희가 디버그 하기에 더 용이해지고 사용자가 더 자세한 에러 원인을 알 수 있습니다.
그렇진 않습니다.
1개의 API 내에서 동일한 에러가 연속으로 발생하진 않을 것으로 보입니다. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
정확히 어느 부분에서 정리가 필요한지는 잘 이해하지 못했는데, 우선은 제 리뷰 의견을 추가하겠습니다.
이러한 분리를 통해 memcached_connect() 함수에서 connection 실패 시에 발생하는 에러 코드와 memcached_version_instance() 실패 시에 발생하는 에러 코드가 중복되어도 어느 쪽에서 문제가 생긴 것인지 알 수 있습니다.
에러 코드 추가 없이 memcached_set_error()
만 추가로 호출하는 구현은 어떤가요?
if (memcached_success(rc))
{
memcached_mark_server_as_clean(server);
rc= memcached_version_instance(server);
- return rc;
+ return memcached_set_error(*server, rc, MEMCACHED_AT);
}
-
memcached_version_instance()
는 문제 원인에 따라 리턴하는 에러 코드가 달라지는데,
이를MEMCACHED_VERSION_FAILURE
로 덮어쓰게 되면 오히려 세부 원인 파악은 더 어려워지는게 아닌가 생각합니다. -
MEMCACHED_AT
은 파일명과 코드 line에 대한 정보를 포함하기 때문에, 에러 코드가 중복되어도 메시지로 문제 발생 시점을 구분 가능할 것으로 생각합니다. -
한 곳에서만 사용하기 위한 용도로 에러 코드를 추가하는 것이 조금 걸립니다.
리턴하는 에러 코드는 덮어쓰기가 되고있는 상황이라면 가장 상위의 에러를 반환하는 것이 맞지 않나요?
arcus_vdo 에서는 memcached_connect를 다시 부릅니다. 이때에도 발생 코드 라인만으로도 중복 구분이 용이해지나요? @uhm0311 |
API 호출 시 아래의 에러들을 구분하는 것이 의미가 있다고 생각하고 PR을 올렸던 것으로 기억합니다.
|
어떤 부분을 이야기하고자 하는 것인지 잘 모르겠는데, 본인이 생각하는 맞는 구현 방향을 정리해서 올려 주면 좋겠습니다.
위 코멘트에 따르면
memcached_return_t memcached_version_instance(memcached_server_st *instance)
{
memcached_return_t rc;
if (instance && instance->root)
{
if (instance->root->flags.use_udp)
{
- return MEMCACHED_NOT_SUPPORTED;
+ return MEMCACHED_VERSION_FAILURE
}
if (instance->root->flags.binary_protocol)
{
- return version_binary_instance(instance);
+ rc =version_binary_instance(instance);
+ if (memcached_failed(rc)) {
+ return MEMCACHED_VERSION_FAILURE;
+ }
+ return rc;
}
- return version_ascii_instance(instance);
+ rc = version_ascii_instance(instance);
+ if (memcached_failed(rc)) {
+ return MEMCACHED_VERSION_FAILURE;
+ }
+ return rc;
}
- return MEMCACHED_INVALID_ARGUMENTS;
+ return MEMCACHED_VERSION_FAILURE
} |
올려주신 코드에서 모든 걸 memcached_return_t memcached_version_instance(memcached_server_st *instance)
{
memcached_return_t rc;
if (instance && instance->root)
{
if (instance->root->flags.use_udp)
{
return MEMCACHED_NOT_SUPPORTED;
}
if (instance->root->flags.binary_protocol)
{
- return version_binary_instance(instance);
+ rc =version_binary_instance(instance);
}
- return version_ascii_instance(instance);
+ else
+ {
+ rc = version_ascii_instance(instance);
+ }
+ if (memcached_failed(rc)) {
+ return MEMCACHED_VERSION_FAILURE;
+ }
+ return rc;
}
return MEMCACHED_INVALID_ARGUMENTS;
} 하지만 |
5716509
to
77b20cf
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
현재 기준 제 의견을 정리합니다. @uhm0311 최종 정리해 주시면 좋겠습니다.
아래 내용 외에 제 의견이 더 필요한 부분이 있으면 알려주시기 바랍니다.
- 문제 발생 시 디버깅을 위해 에러 발생 위치를 구분할 수 있도록 하는 것은 적절해 보입니다.
- 다만 한 곳에서만 사용하기 위한 목적으로 에러 코드를 추가하는 것이 조금 걸려서,
다른 방법(MEMCACHED_AT
등)을 사용한 구분이 가능한지를 확인하고자 했습니다. - @ing-eoking 어떤 부분에서 더 정리가 필요하다고 생각하는 것인지 잘 이해하지 못했습니다.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
제 의견 정리입니다.
- PR에서의
arcus_connect
에서set_error
는 connect에 성공했으나 version 명령어 실패에 대한 것입니다.- 어째서 connect에서 따로 version 명렁어를 보내는 것일까 궁금했습니다.
- 하위 호환성을 위한(바뀌거나 존재하지 않을 수 있는 명령어 mget, smget 등등) 것이 아닐까 생각됩니다.
- version_instance에서 version 정보를 받아와 parsing하고, 확인하는 로직이 있는지 궁금했습니다.
- 추후에 확인 예정
- 다른 케이스(단순히 K/V get을 쓰는 상황 등)를 생각해봤을 때는 디버깅에 도움을 주는지는 잘 모르겠습니다.
- 간단히 살펴봤을 때, 아래와 같은 상황에서
arcus_connect
실패에 대해 외부에서set_error
를 따로 설정합니다.arcus_connect
Fail에 대하여 외부에서set_error
를 설정하고 있는 명령어do_coll_get
do_coll_mget
do_bop_smget
arcus_connect
Fail에 대하여 외부에서 설정하고 있지 않은 명령어memcached_mget_by_key
- 어째서 connect에서 따로 version 명렁어를 보내는 것일까 궁금했습니다.
VERSION_FAILURE
라는 에러를 두는 것은 좋다고 생각됩니다.- 이 에러를 지금의 PR과 같은 상황에서 하는게 맞는지, 좀 더 세분화된 특정 상황으로 해야 할지는 아직 모르겠습니다.
@jhpark816 @namsic @ing-eoking 본 PR이 급한 변경 사항은 아닌 것 같은데, 모두 동의한다면 Close 하고 이슈로 올려두어도 될까요? |
정리 의견을 전달합니다.
그 외의 여러 문의에 대해 설명하면,
|
5716509 |
아래 코멘트에 있는 코드를 확인하세요. |
77b20cf
to
ee2e6b5
Compare
반영했습니다. |
MEMCACHED_VERSION_FAILURE
를 추가했습니다.