API
본 장에서는 실제 애플리케이션 개발을 위한 API의 사용법에 대해서 설명한다.
1. 개요
사용하는 API는 RQ에서 사용하는 API와 RQ의 사용을 보조하는 API로 구분할 수 있다. 모든 API는 서버와 클라이언트에서 사용 가능하다.
-
RQ 사용 API
API 설명 RQ에 데이터를 저장한다.
RQ로부터 데이터를 로드한다.
해당 RQ의 Fail 큐에 쌓인 요청 데이터를 다시 Request 큐에 넣어준다.
-
RQ 사용 보조 API
API 설명 tpdeq()로 RQ에서 데이터를 읽은 경우 해당 데이터의 서비스명을 제공한다.
tpdeq()로 RQ에서 데이터를 읽은 경우 해당 데이터에 대한 상세한 정보를 제공한다.
RQ에 저장된 데이터의 통계를 요청한다.
RQ에 저장된 데이터 중 지정한 서비스에 대한 통계를 요청하는 함수로 현재 RQ에 적체되어 있는 데이터의 통계를 구한다.
트랜잭션을 지원하며 RQ 데이터를 저장한다.
트랜잭션을 지원하며 RQ로부터 데이터를 로드한다.
-
기타
API 설명 deq time 관련 callback 함수이다.
2. RQ 사용 API
2.1. tpenq
서버와 클라이언트에서 RQ에 데이터를 저장하는 함수로 Tmax 시스템은 시스템의 장애나 에러로 인한 서비스가 불가능한 상태에서도 RQ에 저장된 데이터는 정합성을 보장할 수 있다. RQ에 데이터를 저장해 두었다가 여러 가지 상황으로 시스템이 다운되고 복구 이후 다시 실행되면 이전에 처리하지 못한 데이터를 계속해서 처리할 수 있다.
tpcall()이나 tpacall()로 서비스를 요청한 경우 해당 서비스가 수행할 데이터가 누적되어 있다면 서비스를 요청한 데이터도 대기(waiting)한다. 이때 시스템의 장애나 에러로 인해 시스템이 다운되면 대기 중인 데이터는 분실된다. 이러한 문제점을 보안하고 데이터의 정합성을 보장할 수 있도록 tpenq()는 서비스를 요청하는 경우 데이터를 RQ에 저장한다. 트랜잭션 모드에서 수행해도 트랜잭션 모드에서 제외되기 때문에 트랜잭션 모드에서 함수를 수행 도중 에러가 발생해도 트랜잭션에는 영향을 미치지 않는다.
-
프로토타입
# include <tmaxapi.h> int tpenq (char *qname, char *svc, char *data, long len, long flags)
-
파라미터
파라미터 설명 qname
qname은 데이터를 저장할 RQ의 이름으로 config 파일에 등록된 이름이어야 한다.
svc
데이터를 RQ에 저장하고, svc 이름이 NULL이 아니면 즉시 서비스를 요청한다.
svc 이름이 NULL이면 데이터는 RQ에 저장되고 서비스는 수행되지 않는다. 이 경우 나중에 tpdeq()를 이용하여 서비스를 요청해야 한다. svc로 명명된 서비스가 없거나 또는 서비스를 수행하고 처리 결과를 받지 않은 상태에서 시스템 장애가 발생할 경우에는 이 데이터는 내부적으로 Fail 큐에 저장된다. 데이터는 tpdeq()로 서비스를 재요청하거나 에러 처리를 해야 한다.
data
NULL 값인 경우를 제외하고 반드시 tpalloc()으로 할당된 버퍼에 대한 포인터이어야 한다. data의 유형(type)과 하위 유형(subtype)은 svc가 지원하는 유형이어야 한다.
len
송신하는 데이터의 길이이다.
-
data가 가리키는 버퍼가 특별한 길이 명시가 필요없는 버퍼 유형(STRING, STRUCT, X_COMMON, X_C_TYPE)인 경우 len은 무시되고 0이 사용된다.
-
data가 가리키는 버퍼가 길이 명시가 반드시 필요한 버퍼 유형(X_OCTET, CARRAY, MULTI STRUCTURE)인 경우 len은 0이 될 수 없다.
-
data가 NULL인 경우 len은 무시되고 데이터 없이 서비스 요청이 송신된다.
flags
flags에 사용 가능한 값은 다음과 같다.
-
TPRQS
svc가 NULL이 아닌 경우 svc로 명명된 서비스를 요청하고, 처리 결과를 RQ에 저장된다. 서비스 처리 결과는 tpdeq()를 이용해서 받는다. svc가 NULL인 경우 데이터는 단지 RQ에 저장되고 서비스는 수행하지 않는다.
-
TPNOREPLY
svc가 NULL이 아닌 경우 svc로 명명된 서비스는 요청하지만, 처리 결과는 RQ에 저장하지 않겠다는 의미이다. svc가 NULL인 경우 데이터는 단지 RQ에 저장되고 서비스는 수행하지 않는다.
-
TPFUNC
서비스별 RQ 데이터를 관리할 때 사용한다. flags가 설정되지 않았다면 처음 tpenq()를 통해 저장된 데이터가 제거된다. 데이터가 저장되기 전에 제거해야 할 경우에는 tpenq() 호출할 때 TPFUNC를 같이 설정한다.
-
0(zero)
서비스 처리 결과를 RQ에 저장하지 않고, 함수 호출자가 접속되어 있는 Tmax 시스템의 클라이언트 버퍼에 저장한다. 서비스는 RQ를 통해 요구하지만 결과는 tpcall()처럼 함수 호출자가 접속한 클라이언트의 버퍼에서 가져올 때 사용한다. 0(zero)flags가 설정되면 나중에 처리 결과를 받기 위해서는 tpdeq() 호출할 때 flags에 0(zero)을 설정해야 한다.
-
-
반환값
반환값 설명 -1
함수 호출에 실패한 경우이다. tperrno에 에러 코드가 설정된다.
-
오류
tpenq()가 정상적으로 수행되지 않을 경우 tperrno에 다음 값 중 하나가 설정된다.
에러 코드 설명 [TPEINVAL]
파라미터가 유효하지 않다. 예를 들어 데이터가 tpalloc()으로 할당되지 않은 버퍼를 가리키거나, 또는 flags가 유효하지 않은 경우에 발생한다.
[TPENOENT]
존재하지 않는 qname이 사용되었다.
[TPEQFULL]
지속적인 서비스 결과로 지정된 큐의 크기를 넘는 경우에 발생한다.
[TPGOTSIG]
TPSIGRSTRT가 설정되지 않은 상태에서 시그널이 수신되었다.
[TPEPROTO]
tpenq()이 부적절한 상황에서 호출되었다.
[TPESYSTEM]
Tmax 시스템 에러가 발생한 경우로 자세한 정보는 로그 파일에 기록된다.
[TPEOS]
운영 시스템에 에러가 발생하였다.
-
예제
#include <stdio.h> #include <usrinc/atmi.h> #include <usrinc/tmaxapi.h> void main(int argc, char *argv[]) { int ret; char *buf; long len; ret=tpstart((TPSTART_T *)NULL); if (ret==-1) { error processing } buf = (char *)tpalloc(“STRING”, NULL, 0); if (buf==NULL) { error processing } data process.... ret=tpenq(“RQ”, “SERVICE”, (char *)buf, strlen(buf), TPRQS); if (ret==-1) { error processing } data process.... ret=tpdeq(“RQ”, “SERVICE”, (char **)&buf, (long *)&len, TPRQS); if (ret==-1) { error processing } data process.... tpfree(buf); tpend(); }
-
관련함수
tpdeq(), tpqstat()
2.2. tpdeq
서버와 클라이언트에서 RQ로부터 데이터를 로드하는 함수로 tpenq()를 이용하여 서비스를 요청한 결과를 받거나 서비스명을 NULL로 해서 저장한 데이터를 읽는다. tpenq()를 호출할 때 flags에 TPNOREPLY를 설정하면 서비스는 결과를 받을 수 없다. 그러므로 트랜잭션 모드에서 tpdeq()를 수행 도중 에러가 발생해도 트랜잭션에는 영향을 미치지 않는다.
-
프로토타입
# include <tmaxapi.h> int tpdeq (char *qname, char *svc, char **data, long *len, long flags)
-
파라미터
파라미터 설명 qname
데이터를 저장할 RQ의 이름으로 config 파일에 등록된 이름이어야 한다.
svc
tpenq()를 호출하는 경우 svc에 전달한 이름이어야 한다. 서비스명으로 tpenq()를 호출한 경우 서비스가 자동 요청되고, 결과가 RQ에 저장된다. 서비스 결과를 받기 위해서는 tpdeq()도 동일한 서비스명을 입력해야 한다.
서비스명을 NULL로 tpenq()를 호출한 경우 tpdeq()도 동일한 서비스명을 입력한다. 서비스명이 NULL인 경우 서비스명에 상관없이 큐에 쌓여있는 모든 데이터를 하나씩 로드할 수 있다.
tpenq()의 경우 에러나 시스템 장애로 인해 Fail 큐에 저장된 데이터를 tpdeq()하기 위해서는 svc에 _rq_sub_queue_name[TMAX_FAIL_QUEUE]를 주고 deq해야 한다.
*data
tpalloc()에 의해 할당된 버퍼에 대한 포인터이다. 함수가 성공적으로 반환되면 *data는 수신된 데이터가 저장된다.
len
tpdeq()가 성공적으로 수신한 데이터의 길이이다. tpdeq()는 필요하다면 응답 내용이 지정된 버퍼에 수신될 수 있도록 버퍼 크기를 증가시킨다.
len은 *data의 데이터의 길이로 *data는 수신 데이터가 커서 변경될 수도 있고, 이 외에 다른 이유에 의해서도 변경될 수 있다. len이 호출 전 버퍼의 총 크기보다 크다면, len이 그 버퍼의 새로운 크기가 된다. len이 0으로 반환되었다면, 어떤 데이터도 수신되지 않고 *data와 len이 지시하는 버퍼 모두 아무런 변화가 없다.
*data나 len이 NULL이 되는 것은 에러이다.
flags
flags에 사용 가능한 값은 다음과 같다.
-
TPRQS
RQ에서 데이터를 가져올 때 사용된다. reply 큐로부터 서비스의 결과를 가져오기 위해서 설정된다.
-
TPFUNC
서비스별 RQ 데이터를 관리할 때 사용한다. flags가 설정되지 않았다면 처음 tpenq()를 통해 저장된 데이터가 제거된다. 데이터가 저장되기 전에 제거해야 할 경우에는 tpenq() 호출할 때 TPFUNC를 같이 설정한다.
-
TPBLOCK
tpdeq() 호출할 때 블록 타임아웃 시간 동안 메시지가 올 때까지 기다린다.
-
TPNOTIME
TPBLOCK과 함께 사용되면 블록 타임아웃 시간에 관계없이 응답이 올 때까지 기다리게 된다.
-
0(zero)
데이터를 자신이 접속한 클라이언트의 버퍼에서 가져오려고 할 때 사용한다.
-
-
반환값
반환값 설명 -1
함수 호출에 실패한 경우이다. tperrno에 에러 코드가 설정된다.
-
오류
tpdeq()가 정상적으로 수행되지 않을 경우 tperrno에 다음 값 중 하나가 설정된다.
에러 코드 설명 [TPEINVAL]
파라미터가 유효하지 않다. 예를 들어 데이터가 tpalloc()으로 할당되지 않은 버퍼를 가리키거나 또는 flags가 유효하지 않은 경우에 발생한다.
[TPGOTSIG]
TPSIGRSTRT가 설정되지 않은 상태에서 시그널이 수신되었다.
[TPEMATCH]
서비스명이 잘못되었거나 제거할 데이터가 없는 경우 해당 조건을 만족하는 제거할 데이터를 찾지 못했다.
[TPENOENT]
존재하지 않는 qname이 사용되었다.
[TPEPROTO]
tpdeq()이 부적절한 상황에서 호출되었다.
[TPESYSTEM]
Tmax 시스템 에러가 발생하였다. 자세한 정보는 로그 파일에 기록된다.
[TPEOS]
운영 시스템에 에러가 발생하였다.
-
예제
#include <stdio.h> #include <usrinc/atmi.h> #include <usrinc/tmaxapi.h> void main(int argc, char *argv[]) { int ret; char *buf; long len; ret=tpstart((TPSTART_T *)NULL); if (ret==-1) { error processing } buf = (char *)tpalloc(“STRING”, NULL, 0); if (buf==NULL) { error processing } data process.... ret=tpenq(“RQ”, “SERVICE”, (char *)buf, strlen(buf), TPRQS); if (ret==-1) { error processing } data process.... ret=tpdeq(“RQ”, “SERVICE”, (char **)&buf, (long *)&len, TPRQS); if (ret==-1) { error processing } data process.... tpfree(buf); tpend(); }
-
관련함수
tpenq(), tpqstat()
2.3. tpreissue
서버와 클라이언트에서 사용되는 함수로 해당 RQ의 Fail 큐에 쌓인 요청 데이터를 다시 Request 큐에 넣어준다. tpenq() 등으로 RQ를 통한 서비스 수행 중 네트워크 불안정이나 기타 서버 측의 오류로 서비스 수행을 실패하여 Fail 큐에 쌓인 클라이언트의 서비스 요청 데이터를 다시 Request 큐에 넣어주는 함수이다. 저장된 데이터를 해당 서비스로 전달해서 결과를 Reply 큐에 저장한다.
-
프로토타입
#include <tmaxapi.h> int tpreissue(char *qname, char *filter, long flags)
-
파라미터
파라미터 설명 qname
Tmax 시스템에 등록된 RQ의 이름이다.
filter
현재 지원하지 않으며 NULL로 설정해야 한다.
flags
현재 버전에서는 지원하지 않으나 TPNOFLAGS으로 설정한다.
-
반환값
반환값 설명 0
함수 호출에 성공한 경우이다.
-1
함수 호출에 실패한 경우이다. tperrno에 에러 코드가 설정된다.
-
오류
tpreissue()가 정상적으로 수행되지 않을 경우 tperrno에 다음 값 중 하나가 설정된다.
에러 코드 설명 [TPEINVAL]
파라미터가 유효하지 않다. 예를 들어 qname이 NULL이거나 현재 지원하지 않는 필터나 flags에 위에서 언급한 값 이외의 값을 설정했을 경우 발생한다.
[TPENOENT]
qname에 해당하는 RQ가 존재하지 않는다.
[TPESYSTEM]
Tmax 시스템에 에러가 발생한 경우로 네트워크 상태가 불량한 경우 발생한다.
-
관련 함수
tpenq(), tpdeq()
3. RQ 사용 보조
3.1. tpextsvcname
서버와 클라이언트에서 tpdeq()로 RQ에서 데이터를 읽은 경우 해당 데이터의 서비스명을 알려고 할 때 사용한다. tpextsvcname()은 _Fail 큐에 저장되어 있는 데이터를 tpdeq()로 읽은 경우에 사용한다.
-
프로토타입
# include <tmaxapi.h> int tpextsvcname (char *data, char *svc)
-
파라미터
파라미터 설명 data
tpdeq()를 이용하여 RQ로부터 읽은 데이터가 저장되어 있는 포인터로 tpalloc()으로 할당된다.
svc
해당 데이터의 서비스명을 받아오기 위한 포인터이다.
-
반환값
반환값 설명 -1
함수 호출에 실패한 경우이다. tperrno에 에러 코드가 설정된다.
-
오류
tpextsvcname()이 정상적으로 수행되지 않을 경우 tperrno에 다음 값 중 하나가 설정된다.
에러 코드 설명 [TPEINVAL]
파라미터가 유효하지 않다. 예를 들면 data에 tpalloc()으로 할당되지 않은 버퍼가 전달되는 경우에 발생한다.
[TPESYSTEM]
Tmax 시스템 에러가 발생하였다. 자세한 정보는 로그 파일에 기록된다.
[TPEOS]
운영 시스템에 에러가 발생하였다.
-
예제
#include <stdio.h> #include <usrinc/atmi.h> #include <usrinc/tmaxapi.h> void main(int argc, char *argv[]) { int ret; char *buf, *svc_name; long len; ret=tpstart((TPSTART_T *)NULL); if (ret==-1) { error processing } buf = (char *)tpalloc(“STRING”, NULL, 0); if (buf==NULL) { error processing } data process.... ret=tpenq(“RQ”, “SERVICE”, (char *)buf, strlen(buf), TPRQS); if (ret==-1) { error processing } data process.... ret=tpdeq(“RQ”, “SERVICE”, (char **)&buf, (long *)&len, TPRQS); if (ret==-1) { error processing } ret=tpextsvcname(buf, svc_name); if (ret==-1) { error processing } printf(“svc name : %s ,”,svc_name); data process.... tpfree(buf); tpend(); }
-
관련함수
tpenq(), tpdeq()
3.2. tpextsvcinfo
서버와 클라이언트에서 tpdeq()로 RQ에서 데이터를 읽은 경우 해당 데이터에 대한 상세한 정보를 제공하는 함수이다.
-
프로토타입
# include <tmaxapi.h> int tpextsvcinfo (char *data, char *svc, , int *type, int *errcode )
-
파라미터
파라미터 설명 data
tpalloc()으로 할당되어 tpdeq()를 이용하여 RQ로부터 읽은 데이터가 저장되어 있는 포인터이다.
svc
해당 데이터의 서비스명을 받아오기 위한 포인터이다.
type
해당 데이터의 처리 결과를 나타낸다.
다음은 type에 설정 가능한 값에 대한 설명이다.
-
TPREQ(0)
tpenq()를 수행할 때 두 번째 인자로 NULL을 지정한 경우 tpenq가 정상적으로 된 경우 이와 같이 type에 TPREQ가 설정된다.
-
TPFAIL(1)
tpenq()를 수행할 때 두 번째 인자로 서비스명을 지정한 경우 서비스에서 tpreturn의 첫 번째 인자로 TPFAIL이 호출된 경우에 이와 같이 type에 TPFAIL이 설정된다.
-
TPSUCCESS(2)
tpenq()를 수행할 때 두 번째 인자로 서비스명을 지정한 경우 서비스에서 tpreturn의 첫 번째 인자로 TPSUCCESS가 호출된 경우에 이와 같이 type에 TPSUCCESS가 설정된다.
-
TPERR(-1)
tpenq()가 실패하여 Fail 큐에 송신된 경우 이와 같이 type에 TPERR이 설정된다.
errcode
에러가 발생하는 경우 해당되는 에러 코드 값이 저장된다.
-
-
반환값
반환값 설명 -1
함수 호출에 실패한 경우이다. tperrno에 에러 코드가 설정된다.
-
오류
tpextsvcinfo()이 정상 처리되지 않을 경우 tperrno에 아래 값 중 하나가 설정된다.
에러 코드 설명 [TPEINVAL]
인수가 유효하지 않다. 예를 들면 data나 svc가 NULL이다.
[TPEITYPE]
인수가 유효하지 않다. 예를 들면 data가 RQ에서 받아온 data가 아니다.
[TPESYSTEM]
Tmax 시스템 에러가 발생하였다. 자세한 정보는 로그 파일에 기록된다.
[TPEOS]
운영 시스템에 에러가 발생하였다.
-
관련 함수
tpenq(), tpdeq(), tpextsvcname()
3.3. tpqstat
서버와 클라이언트에서 사용되는 함수로 RQ에 저장된 데이터의 통계를 요청한다. RQ는 내부적으로 _fail queue, _request queue, _reply queue의 3부분으로 구성되어 있다. flags 값을 이용하여 각 큐에 저장된 데이터 통계를 구할 수 있다.
-
프로토타입
# include <tmaxapi.h> int tpqstat (char *qname, long flags)
-
파라미터
파라미터 설명 qname
Tmax 환경 파일에 등록된 RQ 이름을 나타낸다.
flags
대상 데이터의 type을 설정한다.
flags로 사용 가능한 값은 다음과 같다.
-
0(TMAX_ANY_QUEUE) _fail queue, _request queue, _reply queue의 데이터 통계를 낼 때 사용한다.
-
1(TMAX_FAIL_QUEUE) : _fail queue의 데이터 통계를 낼 때 사용한다.
-
2(TMAX_REQ_QUEUE) : _request queue의 데이터 통계를 낼 때 사용한다.
-
3(TMAX_RPLY_QUEUE) : _reply queue의 데이터 통계를 낼 때 사용한다.
-
-
반환값
반환값 설명 -1
함수 호출에 실패한 경우이다. tperrno에 에러 코드가 설정된다.
-
오류
tpqstat()가 정상적으로 수행되지 않을 경우 tperrno에 다음 값 중 하나가 설정된다.
에러 코드 설명 [TPEINVAL]
파라미터가 유효하지 않다. 예를 들어 qname이 NULL이거나 qname에 해당하는 큐가 없거나 flags가 유효하지 않은 경우에 발생한다.
[TPEPROTO]
tpqstat()가 부적절한 상황에서 호출되었다.
[TPESYSTEM]
Tmax 시스템 에러가 발생하였다. 자세한 정보는 로그 파일에 기록된다.
[TPEOS]
운영 시스템에 에러가 발생하였다.
-
예제
#include <stdio.h> #include <usrinc/atmi.h> #include <usrinc/tmaxapi.h> void main(int argc, char *argv[]) { int ret, i; char *buf; if (argc!=2) { error processing } ret=tpstart((TPSTART_T *)NULL); if (ret==-1) {error processing } buf = (char *)tpalloc(“STRING”, NULL, 0); if (buf==NULL) { error processing } strcpy(buf, argv[1]); data process… ret=tpenq(“RQ”, NULL, (char *)buf, strlen(buf), TPRQS); if (ret==-1) {error processing } printf(“qstat :”); for (i=0;i<4;i++) { ret=tpqstat(“rq”, i); if (ret==-1) {error processing } printf(“ %d”,ret); /* qstat : 1 0 0 1 */ } printf(“\n”); data process… ret=tpenq(“RQ”, “SERVICE”, (char *)buf, strlen(buf), TPRQS); if (ret==-1) {error processing } printf(”qstat :”); for (i=0;i<4;i++) { ret=tpqstat(“rq”, i); if (ret==-1) {error processing } printf(” %d”,ret); /* qstat : 2 0 0 2 */ } printf(“\n”); tpfree((char *)buf); tpend(); }
-
관련함수
tpenq(), tpdeq()
3.4. tpqsvcstat
서버와 클라이언트에서 사용되는 함수로 RQ에 저장된 데이터 중 지정한 서비스에 대한 통계를 요청한다. RQ는 내부적으로 _fail queue, _request queue, _ reply queue의 3부분으로 구성되어 있다.
flags값을 이용하여 각 큐에 저장된 데이터 통계를 구할 수 있다.
-
프로토타입
# include <tmaxapi.h> int tpqsvcstat (char *qname, char * svc, long flags )
-
파라미터
파라미터 설명 qname
Tmax 환경 파일에 등록된 RQ 이름을 설정한다.
svc
통계 정보를 얻을 서비스 이름으로 NULL인 경우 tpqstat()과 동일한 의미를 갖는다.
flags
데이터 통계의 유형을 설정한다.
다음은 flags에 설정 가능한 값에 대한 설명이다.
-
0(TMAX_ANY_QUEUE) : _fail queue, _request queue, _reply queue의 데이터 통계를 낼 때 사용한다.
-
1(TMAX_FAIL_QUEUE) : _fail queue의 데이터 통계를 낼 때 사용한다.
-
2(TMAX_REQ_QUEUE) : _request queue의 데이터 통계를 낼 때 사용한다.
-
3(TMAX_RPLY_QUEUE) : _reply queue의 데이터 통계를 낼 때 사용한다.
-
-
반환값
반환값 설명 -1 이외의 값
함수 호출에 성공한 경우이다.
-1
함수 호출에 실패한 경우이다. tperrno에 에러 코드가 설정된다.
-
오류
tpqscvstat()가 정상 처리되지 않을 경우 tperrno에 아래 값 중 하나가 설정된다.
에러 코드 설명 [TPEINVAL]
인수가 유효하지 않다. 예를 들어 qname이 NULL이거나, qname에 해당하는 큐가 없거나 type이 유효하지 않은 경우이다.
[TPEPROTO]
tpqscvstat()가 부적절한 상황에서 호출되었다.
[TPESYSTEM]
Tmax 시스템 에러가 발생하였다. 자세한 정보는 로그 파일에 기록된다.
[TPEOS]
운영 시스템에 에러가 발생하였다.
-
관련 함수
tpenq(), tpdeq(), tpqstat()
3.5. tpenq_ctl
서버와 클라이언트에서 트랜잭션을 지원하며 RQ 데이터를 저장하는 함수이다. Tmax 시스템은 시스템의 장애나 에러로 인한 서비스가 불가능한 상태에서도 RQ에 저장된 데이터는 정합성을 보장할 수 있다. RQ에 데이터를 저장해 두었다가, 여러 가지 상황으로 시스템이 다운되고, 복구 이후 다시 실행되면 이전에 처리하지 못한 데이터를 계속해서 처리할 수 있도록 한다.
tpcall()이나 tpacall()로 서비스를 요청한 경우나 해당 서비스가 수행할 데이터가 누적된 경우에 방금 서비스를 요청한 데이터도 대기(wating)한다. 이 때 시스템의 장애나 에러로 인해 시스템이 다운되면 대기 중인 데이터는 분실된다. 이러한 문제점을 보안하고 데이터의 정합성을 보장할 수 있도록 tpenq_ctl()는 서비스를 요청할 때 데이터를 RQ에 저장하는 함수이다.
tpenq_ctl() 함수는 트랜잭션 모드에서 수행하면, 데이터를 RQ에 저장하기까지 트랜잭션으로 처리된다. 2번 이상의 tpenq_ctl()을 하나의 트랜잭션으로 묶은 경우 모든 데이터가 RQ에 저장되기까지 tpdeq_ctl()를 통해 데이터를 로드할 수 없으며, 저장되는 도중 에러가 발생하면 rollback된다.
-
프로토타입
#include <usrinc/tmaxapi.h> int tpenq_ctl(char *qname, char *svc, TMQCTL *ctl, char *data, long len, long flags);
-
파라미터
파라미터 설명 qname
데이터를 저장할 RQ의 이름으로 환경 파일에 등록된 이름이어야 한다.
svc
데이터를 RQ에 저장하고, svc 이름이 NULL이 아니면 즉시 서비스를 요청한다.
svc 이름이 NULL이면 데이터는 RQ에 저장되고 서비스는 수행되지 않는다. 이 경우 나중에 tpdeq_ctl()를 이용하여 서비스를 요청해야 한다. svc로 명명된 서비스가 없거나 또는 서비스를 수행하고 처리 결과를 받지 않은 상태에서 시스템 장애가 발생할 경우에 이 데이터는 내부적으로 Fail 큐에 저장된다. 이 데이터도 tpdeq_ctl()로 서비스를 재요청하거나 에러 처리를 해야 한다.
ctl
TMQCTL의 det_time를 사용하여 일정시간을 설정하면 그 시간 이후에 svc call한다.
deq_time을 설정할 때는 현재시간에 delay_time를 설정해야 한다.
delay_time을 3으로 설정하고 싶은 경우 'cur_time + 3’과 같이 설정해야 한다. TMQCTL의 기능 중 현재는 deq_time만 지원하며, deq_time는 트랜잭션과 함께 사용할 수 없다.
flags 항목에 TPRQS_NON_PERSISTENT로 설정할 경우 메시지를 파일에 기록하지 않고 메모리에만 기록한다.
data
NULL인 경우를 제외하고 반드시 tpalloc()으로 할당된 버퍼에 대한 포인터이어야 한다. data의 유형(type)과 하위 유형(subtype)은 svc가 지원하는 유형들이어야 한다.
len
송신하는 데이터의 길이이다.
-
data가 가리키는 버퍼가 특별한 길이 명시가 필요 없는 버퍼 유형(STRING, STRUCT, X_COMMON, X_C_TYPE)이라면 len은 무시되고 보통 0이 사용된다.
-
data가 가리키는 버퍼가 길이 명시가 반드시 필요한 버퍼 유형( X_OCTET, CARRAY, MULTI STRUCTURE)이라면 len은 0이 될 수 없다.
-
data가 NULL인 경우 len은 무시되고 데이터 없이 서비스 요청이 송신된다.
flags
데이터 처리 유형을 설정한다.
다음은 flags에 설정 가능한 값에 대한 설명이다.
-
TPRQS
svc가 NULL이 아닌 경우 svc로 명명된 서비스를 요청하고, 처리 결과를 RQ에 저장된다. 서비스 처리 결과를 받으려면 tpdeq_deq() 함수을 이용하여 받는다. svc가 NULL인 경우 데이터는 단지 RQ에 저장되고 서비스는 수행하지 않는다.
-
TPNOREPLY
svc가 NULL이 아닌 경우 svc로 명명된 서비스는 요청하지만, 처리 결과는 RQ에 저장하지 않는다. svc가 NULL인 경우 데이터는 단지 RQ에 저장되고 서비스는 수행하지 않는다.
-
TPFUNC
서비스별 RQ 데이터를 관리할 때 사용한다. TPFUNC flags가 설정되지 않았다면 처음 tpenq_ctl()를 통해 저장된 데이터가 제거(dequeued)된다. 데이터가 저장되기 전에 해야할 경우에는 tpenq_ctl()를 호출될 때 TPFUNC를 같이 설정한다.
-
0(zero)
서비스 처리 결과를 RQ에 저장하지 않고, 함수 호출자가 접속되어 있는 Tmax 시스템의 클라이언트 버퍼에 저장한다. 서비스는 RQ를 통해 요구하지만 결과는 tpcall()처럼 함수 호출자가 접속한 클라이언트의 버퍼에서 가져올 때 사용한다. 처리 결과를 받기 위해서 tpdeq_ctl()를 호출할 때 flags에 0(zero)을 설정해야 한다.
-
-
반환값
반환값 설명 -1
함수 호출에 실패한 경우이다. tperrno에 에러 코드가 설정된다.
-
오류
tpenq_ctl()가 정상 처리되지 않을 경우 tperrno에 아래 값 중 하나가 설정된다.
에러 코드 설명 [TPEINVAL]
인수가 유효하지 않다. 예를 들어 data가 tpalloc()으로 할당되지 않은 버퍼를 가리키거나 또는 flags가 유효하지 않다.
[TPENOENT]
존재하지 않는 qname이 사용되었다.
[TPEQFULL]
지속적인 서비스 결과로 지정된 큐의 크기를 초과하는 경우에 발생한다.
[TPGOTSIG]
TPSIGRSTRT가 설정되지 않은 상태에서 시그널이 수신되었다.
[TPEPROTO]
tpenq_ctl()이 부적절한 상황에서 호출되었다.
[TPESYSTEM]
Tmax 시스템 에러가 발생하였다. 자세한 정보는 로그 파일에 기록된다.
[TPEOS]
운영 시스템에 에러가 발생하였다.
-
예제
#include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <string.h> #include <usrinc/atmi.h> #include <usrinc/tmaxapi.h> main(int argc, char *argv[]) { char *sndbuf, *rcvbuf; long rcvlen, sndlen, revent; int ret, i, cd; TMQCTL *ctl; long t; ctl = (TMQCTL*)malloc(sizeof(TMQCTL)); memset(ctl, 0, sizeof(TMQCTL)); time(&t); ctl->deq_time = (int)t + 3; if (argc != 2) { printf(“Usage: toupper string\n”); exit(1); } if ( (ret = tmaxreadenv( “tmax.env”,”TMAX” )) == -1 ){ printf( “tmax read env failed\n” ); exit(1); } if (tpstart((TPSTART_T *)NULL) == -1){ printf(“tpstart failed\n”); exit(1); } if ((sndbuf = (char *)tpalloc(“STRING”, NULL, 0)) == NULL) { printf(“sendbuf alloc failed !\n”); tpend(); exit(1); } if ((rcvbuf = (char *)tpalloc(“STRING”, NULL, 0)) == NULL) { printf(“recvbuf alloc failed !\n”); tpfree((char *)sndbuf); tpend(); exit(1); } ret = tx_begin(); if(ret < 0) { fprintf(stderr, “tx_begin() fail\n”); tpfree((char *)sndbuf); tpfree((char *)rcvbuf); exit(1); } strcpy(sndbuf, argv[1]); cd = tpenq_ctl(“txrq1”, “TOUPPER”, ctl, (char *)sndbuf, 0, TPRQS ); if (cd < 0) { printf(“tpenq failed [%s]\n”, tpstrerror(tperrno)); tpfree((char *)sndbuf); tpfree((char *)rcvbuf); tpend(); exit(1); } cd = tpenq_ctl(“txrq1”, “TOUPPER”, ctl, (char *)sndbuf, 0, TPRQS ); if (cd < 0) { printf(“tpenq failed [%s]\n”, tpstrerror(tperrno)); tpfree((char *)sndbuf); tpfree((char *)rcvbuf); tpend(); exit(1); } data process.... ret = tx_commit(); if(ret < 0) { fprintf(stderr, “tx_commit() fail\n”); tpfree((char *)sndbuf); tpfree((char *)rcvbuf); tx_rollback(); exit(1); } tpfree((char *)sndbuf); tpfree((char *)rcvbuf); tpend(); }
-
관련 함수
tpdeq_ctl(), tpqstat()
3.6. tpdeq_ctl
서버와 클라이언트에서 트랜잭션을 지원하며 RQ로부터 데이터를 로드하는 함수로 tpenq_ctl()를 이용하여 서비스를 요청한 결과나 서비스명을 NULL로 해서 저장한 데이터를 읽는 함수이다. tpenq_ctl()을 호출할 때 flags에 TPNOREPLY를 설정한 서비스는 결과를 받을 수 없다. tpdnq_ctl() 함수는 트랜잭션 모드에서 수행하면, 데이터를 RQ에서 로드하는 동안 트랜잭션으로 처리된다. 2번 이상의 tpdep_ctl()을 하나의 트랜잭션으로 묶은 경우 모든 데이터가 RQ에서 데이터를 로드하는 도중 에러가 발생하면 rollback된다.
-
프로토타입
#include <usrinc/tmaxapi.h> int tpdeq_ctl(char *qname, char *svc, TMQCTL *ctl, char **data, long *len, long flags);
-
파라미터
파라미터 설명 qname
데이터를 저장할 RQ의 이름으로 환경 파일에 등록된 이름이어야 한다.
svc
tpenq_ctl() 호출하는 경우 svc에 전달한 이름이어야 한다.
서비스명으로 tpenq_ctl()를 호출한 경우 서비스가 자동 요청되고, 결과가 RQ에 저장된다. 이때 서비스 결과를 받기 위해서는 tpdeq_ctl()도 동일한 서비스명을 입력한다. 서비스명을 NULL로 tpenq_ctl()를 호출한 경우 tpdeq_ctl()도 서비스명을 NULL로 한다. 서비스명이 NULL인 경우 서비스명에 상관없이 큐에 쌓여있는 모든 데이터를 하나씩 deq할 수 있다.
tpenq_ctl() 함수가 에러나 시스템 장애로 인해 Fail 큐에 저장된 데이터를 tpdeq_ctl()하려면 svc에 _rq_sub_queue_name [TMAX_FAIL_QUEUE]를 주고 deq해야 한다.
ctl
-
* flags
-
TPRQS_AUTOACK : deq하는 경우 별도로 ack을 주지 않아도 rqs에서 삭제되도록 한다.
-
TPRQS_NOAUTOACK : deq하는 경우 rqs에서 삭제되지 않도록 한다.
-
TPRQS_ACK_SUCCESS : ctl에 해당하는 q element를 ack을 주어 삭제하도록 한다.
-
TPRQS_ACK_FAIL : deq하는 경우 rqs에서 삭제되지 않도록 한다.
-
-
* exp_time
deq 이후 주어진 시간 이후까지 응답이 오지 않는다면 q element 가 다시 deq할 수 있는 상태로 돌아간다. (단위 : 초)
data
반드시 이전에 tpalloc()에 의해 할당된 버퍼에 대한 포인터이어야 한다. tpdeq_ctl()가 성공적으로 수행된 경우 수신된 데이터가 저장된다.
len
tpdeq_ctl()가 성공적으로 수신한 데이터의 길이이다. tpdeq_ctl()는 필요하다면 응답 내용이 지정된 버퍼에 수신될 수 있도록 버퍼 크기를 증가시킨다.
*data는 수신 데이터가 커서 변경될 수도 있고, 이 외에 다른 이유에 의해서도 변경될 수 있다. 만약 len이 호출 전 버퍼의 총 크기보다 크다면 len이 그 버퍼의 새로운 크기가 된다. len이 0으로 반환되었다면 어떤 데이터도 수신되지 않고 *data와 len이 지시하는 버퍼 모두 아무런 변화가 없다.
*data나 len이 NULL이 되는 것은 에러이다.
flags
데이터 처리 유형을 설정한다.
다음은 flags로 사용 가능한 값에 대한 설명이다.
-
TPRQS
RQ에서 data를 가져올 때 사용된다. Reply 큐로부터 서비스의 결과를 가져오기 위해서 설정된다.
-
TPFUNC
서비스별 RQ data를 관리할 때 사용한다.TPFUNC flags가 설정되지 않았다면 처음 tpenq()를 통해 저장된 데이터가 제거(dequeued)된다. 데이터가 저장되기 전에 해야할 경우에는 tpenq()를 호출할 때 TPFUNC를 같이 설정한다.
-
TPBLOCK
tpdeq_ctl()를 호출할 때 블록 타임아웃 시간 동안 메시지가 올 때까지 기다린다.
-
TPNOTIME
TPBLOCK과 함께 사용되면 블록 타임아웃 시간에 관계 없이 응답이 올 때까지 기다린다.
-
0(zero)
0(zero) flags는 데이터를 자신이 접속한 클라이언트의 버퍼에서 가져올 때 사용한다.
-
-
반환값
반환값 설명 -1
함수 호출에 실패한 경우이다. tperrno에 에러 코드가 설정된다.
-
오류
tpdeq_ctl()가 정상 처리되지 않을 경우 tperrno에 아래 값 중 하나가 설정된다.
에러 코드 설명 [TPEINVAL]
인수가 유효하지 않다. 예를 들어 데이터가 tpalloc()으로 할당되지 않은 버퍼를 가리키거나 또는 flags가 유효하지 않다.
[TPGOTSIG]
TPSIGRSTRT가 설정되지 않은 상태에서 시그널이 수신되었다.
[TPEMATCH]
서비스 이름이 잘못 되었거나 해당 조건을 만족하는 데이터를 찾지 못했다.
[TPENOENT]
존재하지 않는 qname이 사용되었다.
[TPEPROTO]
tpdeq_ctl()이 부적절한 상황에서 호출되었다.
[TPESYSTEM]
Tmax 시스템 에러가 발생하였다. 자세한 정보는 로그 파일에 기록된다.
[TPEOS]
운영 시스템에 에러가 발생하였다.
-
예제
#include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <string.h> #include <usrinc/atmi.h> #include <usrinc/tmaxapi.h> main(int argc, char *argv[]) { char *sndbuf, *rcvbuf; long rcvlen, sndlen, revent; int ret, i, cd; TMQCTL *ctl; ctl = (TMQCTL*)malloc(sizeof(TMQCTL)); memset(ctl, 0, sizeof(TMQCTL)); if (argc != 2) { printf(“Usage: toupper_rq string\n”); exit(1); } if ( (ret = tmaxreadenv( “tmax.env”,”TMAX” )) == -1 ){ printf( “tmax read env failed\n” ); exit(1); } if (tpstart((TPSTART_T *)NULL) == -1){ printf(“tpstart failed\n”); exit(1); } if ((sndbuf = (char *)tpalloc(“STRING”, NULL, 0)) == NULL) { printf(“sendbuf alloc failed !\n”); tpend(); exit(1); } if ((rcvbuf = (char *)tpalloc(“STRING”, NULL, 0)) == NULL) { printf(“recvbuf alloc failed !\n”); tpfree((char *)sndbuf); tpend(); exit(1); } ret = tx_begin(); if(ret < 0) { fprintf(stderr, “tx_begin() fail\n”); tpfree((char *)sndbuf); tpfree((char *)rcvbuf); exit(1); } strcpy(sndbuf, argv[1]); cd = tpdeq_ctl(“txrq1”, “TOUPPER”, ctl, &rcvbuf, &rcvlen, TPRQS ); if (cd < 0) { printf(“tpdeq failed [%s]\n”, tpstrerror(tperrno) ); tpfree((char *)sndbuf); tpfree((char *)rcvbuf); tpend(); exit(1); } cd = tpdeq_ctl(“txrq1”, “TOUPPER”, ctl, &rcvbuf, &rcvlen, TPRQS ); if (cd < 0) { printf(“tpdeq failed [%s]\n”, tpstrerror(tperrno) ); tpfree((char *)sndbuf); tpfree((char *)rcvbuf); tpend(); exit(1); } data process.... ret = tx_commit(); if(ret < 0) { fprintf(stderr, “tx_commit() fail\n”); tpfree((char *)sndbuf); tpfree((char *)rcvbuf); tx_rollback(); exit(1); } tpfree((char *)sndbuf); tpfree((char *)rcvbuf); tpend(); }
-
관련 함수
tpenq_ctl(), tpqstat()
4. 기타
4.1. compute_rq_deqtime
AnyLink 게이트웨이에서 deq_time을 정해서 줄 경우 RQ가 다운되면 deq_time을 reset해야 지연 없이 처리 될 수 있다. 그러나 RQ가 다운되고 기동되는 것을 AnyLink 게이트웨이가 알 수 없기 때문에 보정해 줄 수 없는 문제가 있다. AnyLink 게이트웨이가 down되는 경우 또한 deq_time이 초기화되기 때문에 순서를 보장할 수 없는 상황도 발생할 수 있다.
deq_time 적용을 AnyLink 게이트웨이가 아니라, RQ에서 할 수 있도록 한다. RQ가 deq_time을 스스로 결정할 수 없기 때문에 deq_time을 적용할 때 Callback 함수를 호출하여 AnyLink 라이브러리를 호출할 수 있도록 한다.
RQS가 기동하는 환경변수에 다음과 같이 설정한 후 사용할 수 있다.
RQ_DEQTIME_CALLBACK=libanme.so
이 설정이 있으면 해당하는 라이브러리를 dlopen하고 Callback 함수를 호출하여 deq_time을 적용한다.
-
프로토타입
int compute_rq_deqtime(TMQCTL *ctl, char *dp, int datasize);
-
파라미터
파라미터 설명 ctl
-
* deq_time : 함수 작성을 할 때 구조체 내의 deq_time에 기록하도록 작성해야 한다. (단위 : 초)
dp
검사할 메시지 전문의 포인터이다.
datasize
메시지의 길이이다.
-
-
반환값
반환값 설명 1
deq_time 계산에 성공한 경우 반환값이다.
0
Callback 함수로 전달된 데이터에 AnyLink 헤더의 매직 넘버가 존재하지 않거나 일치하지 않을 경우 반환값이다. (AnyLink 엔진 이외의 서비스에서 RQ를 호출했을 때를 가정)
-1
처리 중 에러가 발생한 경우 반환값이다.
-
관련 함수
tpenq_ctl(), tpenq()