포스트

[OSSCA] 과제 #4 echo 함수 만들기

[OSSCA] 과제 #4 echo 함수 만들기

과제 내용

1. echo와 동일한 echo{아이디}로 echoCommand 추가
1-1 commands.def 에 새 명령어 등록
1-2 새 명령어가 호출할 command 함수 구현
1-3 서버 시작 시 command table에 등록 클라이언트 요청 시 lookup 후 c->cmd->proc(c) 에서 실행

2. ossca-2026-valkey에 PR을 보내기

3. 전체 과정 블로깅

commands.def 에 각 명령어가 MAKE_CMD() 형태로 들어있다.

1
{MAKE_CMD("name", function, arity, flags,ACL, keys/args)}
  • name: 클라이언트가 호출할 때 사용하는 명령어 문자열
    소스 코드 상에서는 소문자로 정의, 클라이언트가 대문자로 호출하더라도 구분 없이 매칭
  • function: 해당 명령어가 호출되었을 때 실제로 실행될 함수 포인터
    보통 void commandName(client *c)의 형태. 예) echo -> echoCommand
  • arity: 명령어에 전달될 수 있는 인자의 개수를 정의
    양수일 경우, 인자의 개수가 정확히 n개이어야 한다.
    음수을 경우, 인자의 개수가 최소 n개 이상이어야 한다.
  • flags: 해당 명령어가 시스템에 어떤 영향을 주는지 비트 플래그로 설정
    CMD_WRITE: 데이터를 변경하는 명령어 (Read-only 복제본에서 실행 불가).
    CMD_READONLY: 데이터를 읽기만 하는 명령어.
    CMD_ADMIN: 서버 설정 변경 등 관리자 권한이 필요한 명령어.
    CMD_NOSCRIPT: Lua 스크립트 내에서 실행을 금지할 때 사용.
  • ACL: 명령어가 어떤 카테고리에 속하는지 정의
    @read, @write, @slow, @fast, @string, @list 등

echo로 확인해보면 아래와 같이 나눌 수 있다. 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
	MAKE_CMD(
    	"echo","Returns the given string.","O(1)","1.0.0",CMD_DOC_NONE,NULL,NULL,"connection",COMMAND_GROUP_CONNECTION,ECHO_History,0,ECHO_Tips,0,
        echoCommand,
        2,
        CMD_LOADING|CMD_STALE|CMD_FAST,
        ACL_CATEGORY_CONNECTION|ACL_CATEGORY_FAST,
        NULL,
        ECHO_Keyspecs,0,
        NULL,
        1
	),
    .args = ECHO_Args
},

그리고 server.c에는 아래와 같이 echoCommand 함수가 구현되어 있다.

echoJihoon 구현

1-1 commands.def에 새 명령어 등록

기존 echo를 그대로 복사하기엔 변화가 있어야 알아보기도 쉬우니 jihoon이 포함된다면 hello! + String의 형태로 만들어보자

1
2
3
4
5
6
7
8
9
10
11
12
/* ossca assignment 4 */
{
	MAKE_CMD(
		"echoJihoon","Returns 'hello!' + string if it contains 'jihoon', otherwise returns the given string.",
		"O(N)","1.0.0",CMD_DOC_NONE,NULL,NULL,"connection",COMMAND_GROUP_CONNECTION,ECHO_History,0,ECHO_Tips,0,
		echoJihoonCommand,
		2,
		CMD_LOADING|CMD_STALE|CMD_FAST,
		ACL_CATEGORY_CONNECTION|ACL_CATEGORY_FAST,
		NULL,ECHO_Keyspecs,0,NULL,1
	),
	.args=ECHO_Args},

1-2 새 명령어가 호출할 command 함수 구현

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/* ossca assignment 4 */

void echoJihoonCommand(client *c) {
    robj *o = c->argv[1];
    
    robj *decoded = getDecodedObject(o);
    char *payload = (char*)objectGetVal(decoded);

    if (payload && strcasestr(payload, "jihoon") != NULL) {
        sds response = sdsnew("hello! ");
        response = sdscat(response, payload); 

        addReplyBulkSds(c, response);
    } else {
        addReplyBulk(c, o);
    }

    decrRefCount(decoded);
}

*robj: redis object

*sdsnew: 새로운 동적 문자열 메모리 할당

c -> argv[0] : ECHOJIHOON

c -> argv[1] : MESSAGE

문자열에서 대소문자 상관없이 jihoon을 찾으면 해당 위치를 반환하는 strcasestr을 사용하여 if문을 작성했다.

sds를 사용하면 메모리 공간이 부족할때 자동으로 크기를 늘린다고 한다.

1-3 서버 시작 시 command table에 등록 클라이언트 요청 시 lookup 후 c->cmd->proc(c) 에서 실행

commands.def 파일에 구문 추가 진행

server.h 파일에 함수 선언

성공!

2. ossca-2026-valkey에 PR을 보내기

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.