Phase 2b: 11개 모듈 전량 실동작 (333 서비스, 전서버 부팅)
- 10개 모듈 추가/확장(au py rc st lg cl mm vl mg cm), 각 30 서비스 = 330 + tmsrv - build.sh 자동발견으로 11 모듈서버 + dbio 라이브러리 23 + 배치 22 빌드 - schema.d 11파일 → 75 테이블, 모듈별 disjoint - 부팅 리소스 규명: fs.mqueue.queues_max=8192(330큐>256), NDRX_MSGSIZEMAX 16000· MSGMAX 50(큐당 5.6MB→0.8MB), msgqueue ulimit 2GB → 전 12서버 runok - 검증: xadmin psc 333 AVAIL, 매입체인 XA 커밋, prepared_xacts=0 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
8219b85f14
commit
bec83c721e
73 changed files with 10705 additions and 35 deletions
41
app/src/mg/dbio/mg_dbio.h
Normal file
41
app/src/mg/dbio/mg_dbio.h
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* mg_dbio.h - mg 모듈 (전문게이트웨이) DB 접근 계층 (libmgdbio.a).
|
||||
* ECPG (EXEC SQL) functions compiled into a static library and linked into
|
||||
* mg_svr and the mg batches. They run on the caller's XA branch/connection
|
||||
* (no EXEC SQL CONNECT); sqlca is the shared per-thread ECPG SQLCA.
|
||||
* Return convention: 0 = ok, -1 = SQL error (caller may also inspect sqlca).
|
||||
*/
|
||||
#ifndef MG_DBIO_H
|
||||
#define MG_DBIO_H
|
||||
|
||||
/* 채번 (STAN/전문 시퀀스) */
|
||||
long mgdb_next_stan(void);
|
||||
long mgdb_next_msg_id(void);
|
||||
long mgdb_next_queue_id(void);
|
||||
long mgdb_seq_bump(const char *name); /* mg_seq 이름있는 카운터 +1 -> 새 값 */
|
||||
|
||||
/* 전문 로그 (mg_msg_log) */
|
||||
int mgdb_insert_msg(long msg_id, long stan, const char *mti, const char *channel,
|
||||
const char *direction, const char *proc_code, const char *bitmap,
|
||||
long amount, const char *pan, const char *rc, const char *raw,
|
||||
const char *status, const char *bizdate);
|
||||
int mgdb_update_msg_rc(long msg_id, const char *rc, const char *status);
|
||||
int mgdb_get_msg_status(long msg_id, char *out /* >= 2 bytes */);
|
||||
long mgdb_find_msg_by_stan(long stan); /* msg_id 반환, 없으면 -1 */
|
||||
|
||||
/* 라우팅 (mg_route) */
|
||||
int mgdb_insert_route(long route_id, const char *channel, const char *mti,
|
||||
const char *dest, long priority, const char *bizdate);
|
||||
int mgdb_lookup_route(const char *channel, const char *mti, char *dest_out /* >= 64 */);
|
||||
|
||||
/* 채널 (mg_channel) */
|
||||
int mgdb_get_channel_status(const char *channel, char *status_out /* >= 16 */);
|
||||
int mgdb_set_channel_status(const char *channel, const char *status);
|
||||
int mgdb_set_channel_session(const char *channel, const char *session_key, long stan);
|
||||
|
||||
/* 큐 (mg_queue) */
|
||||
int mgdb_enqueue(long queue_id, long stan, const char *channel, const char *mti,
|
||||
const char *payload, const char *bizdate);
|
||||
int mgdb_set_queue_status(long queue_id, const char *status);
|
||||
|
||||
#endif /* MG_DBIO_H */
|
||||
200
app/src/mg/dbio/mg_msg_dbio.pgc
Normal file
200
app/src/mg/dbio/mg_msg_dbio.pgc
Normal file
|
|
@ -0,0 +1,200 @@
|
|||
/*
|
||||
* mg_msg_dbio.pgc - 전문 로그/채번/큐 DB 접근 (part of libmgdbio.a).
|
||||
* ECPG functions; run on the caller's XA branch. No EXEC SQL CONNECT.
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <userlog.h>
|
||||
#include "mg_dbio.h"
|
||||
|
||||
long mgdb_next_stan(void)
|
||||
{
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_id;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
|
||||
EXEC SQL SELECT nextval('mg_stan_seq') INTO :h_id;
|
||||
if (sqlca.sqlcode < 0) {
|
||||
userlog("mgdb_next_stan FAIL [%d] %s", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc);
|
||||
return -1;
|
||||
}
|
||||
return h_id;
|
||||
}
|
||||
|
||||
long mgdb_next_msg_id(void)
|
||||
{
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_id;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
|
||||
EXEC SQL SELECT nextval('mg_msg_seq') INTO :h_id;
|
||||
if (sqlca.sqlcode < 0) {
|
||||
userlog("mgdb_next_msg_id FAIL [%d] %s", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc);
|
||||
return -1;
|
||||
}
|
||||
return h_id;
|
||||
}
|
||||
|
||||
long mgdb_next_queue_id(void)
|
||||
{
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_id;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
|
||||
EXEC SQL SELECT nextval('mg_queue_seq') INTO :h_id;
|
||||
if (sqlca.sqlcode < 0) {
|
||||
userlog("mgdb_next_queue_id FAIL [%d] %s", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc);
|
||||
return -1;
|
||||
}
|
||||
return h_id;
|
||||
}
|
||||
|
||||
/* mg_seq 이름있는 카운터를 원자적으로 +1 하고 새 값을 돌려준다 (세션 시퀀스 채번). */
|
||||
long mgdb_seq_bump(const char *name)
|
||||
{
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_val;
|
||||
char h_name[32];
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
|
||||
strncpy(h_name, name, sizeof(h_name) - 1); h_name[sizeof(h_name)-1] = 0;
|
||||
|
||||
EXEC SQL UPDATE mg_seq SET seq_val = seq_val + 1, updated_at = now()
|
||||
WHERE seq_name = :h_name;
|
||||
if (sqlca.sqlcode < 0) {
|
||||
userlog("mgdb_seq_bump UPDATE FAIL [%d] %s", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc);
|
||||
return -1;
|
||||
}
|
||||
if (sqlca.sqlcode == 100) { /* 최초 사용: 행 생성 */
|
||||
EXEC SQL INSERT INTO mg_seq (seq_name, seq_val) VALUES (:h_name, 1);
|
||||
if (sqlca.sqlcode < 0) return -1;
|
||||
return 1;
|
||||
}
|
||||
EXEC SQL SELECT seq_val INTO :h_val FROM mg_seq WHERE seq_name = :h_name;
|
||||
if (sqlca.sqlcode < 0 || sqlca.sqlcode == 100) return -1;
|
||||
return h_val;
|
||||
}
|
||||
|
||||
int mgdb_insert_msg(long msg_id, long stan, const char *mti, const char *channel,
|
||||
const char *direction, const char *proc_code, const char *bitmap,
|
||||
long amount, const char *pan, const char *rc, const char *raw,
|
||||
const char *status, const char *bizdate)
|
||||
{
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_id = msg_id, h_stan = stan, h_amount = amount;
|
||||
char h_mti[8], h_chan[16], h_dir[8], h_proc[8], h_bitmap[40];
|
||||
char h_pan[24], h_rc[4], h_raw[512], h_status[4], h_bizdate[16];
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
|
||||
strncpy(h_mti, mti, sizeof(h_mti)-1); h_mti[sizeof(h_mti)-1] = 0;
|
||||
strncpy(h_chan, channel, sizeof(h_chan)-1); h_chan[sizeof(h_chan)-1] = 0;
|
||||
strncpy(h_dir, direction, sizeof(h_dir)-1); h_dir[sizeof(h_dir)-1] = 0;
|
||||
strncpy(h_proc, proc_code, sizeof(h_proc)-1); h_proc[sizeof(h_proc)-1] = 0;
|
||||
strncpy(h_bitmap, bitmap, sizeof(h_bitmap)-1); h_bitmap[sizeof(h_bitmap)-1] = 0;
|
||||
strncpy(h_pan, pan, sizeof(h_pan)-1); h_pan[sizeof(h_pan)-1] = 0;
|
||||
strncpy(h_rc, rc, sizeof(h_rc)-1); h_rc[sizeof(h_rc)-1] = 0;
|
||||
strncpy(h_raw, raw, sizeof(h_raw)-1); h_raw[sizeof(h_raw)-1] = 0;
|
||||
strncpy(h_status, status, sizeof(h_status)-1); h_status[sizeof(h_status)-1] = 0;
|
||||
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
|
||||
|
||||
EXEC SQL INSERT INTO mg_msg_log
|
||||
(msg_id, stan, mti, channel, direction, proc_code, bitmap, amount,
|
||||
pan, rc, raw_msg, status, biz_date)
|
||||
VALUES (:h_id, :h_stan, :h_mti, :h_chan, :h_dir, :h_proc, :h_bitmap,
|
||||
:h_amount, :h_pan, :h_rc, :h_raw, :h_status, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) {
|
||||
userlog("mgdb_insert_msg FAIL [%d] %s", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mgdb_update_msg_rc(long msg_id, const char *rc, const char *status)
|
||||
{
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_id = msg_id;
|
||||
char h_rc[4], h_status[4];
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
|
||||
strncpy(h_rc, rc, sizeof(h_rc)-1); h_rc[sizeof(h_rc)-1] = 0;
|
||||
strncpy(h_status, status, sizeof(h_status)-1); h_status[sizeof(h_status)-1] = 0;
|
||||
|
||||
EXEC SQL UPDATE mg_msg_log SET rc = :h_rc, status = :h_status WHERE msg_id = :h_id;
|
||||
if (sqlca.sqlcode < 0 || sqlca.sqlcode == 100) {
|
||||
userlog("mgdb_update_msg_rc FAIL [%d] %s", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mgdb_get_msg_status(long msg_id, char *out)
|
||||
{
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_id = msg_id;
|
||||
char h_status[4];
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
|
||||
EXEC SQL SELECT status INTO :h_status FROM mg_msg_log WHERE msg_id = :h_id;
|
||||
if (sqlca.sqlcode < 0 || sqlca.sqlcode == 100) {
|
||||
userlog("mgdb_get_msg_status FAIL [%d] %s", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc);
|
||||
return -1;
|
||||
}
|
||||
out[0] = h_status[0];
|
||||
out[1] = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
long mgdb_find_msg_by_stan(long stan)
|
||||
{
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_stan = stan, h_id;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
|
||||
EXEC SQL SELECT msg_id INTO :h_id FROM mg_msg_log
|
||||
WHERE stan = :h_stan ORDER BY msg_id DESC LIMIT 1;
|
||||
if (sqlca.sqlcode == 100) return -1;
|
||||
if (sqlca.sqlcode < 0) {
|
||||
userlog("mgdb_find_msg_by_stan FAIL [%d] %s", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc);
|
||||
return -1;
|
||||
}
|
||||
return h_id;
|
||||
}
|
||||
|
||||
int mgdb_enqueue(long queue_id, long stan, const char *channel, const char *mti,
|
||||
const char *payload, const char *bizdate)
|
||||
{
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_id = queue_id, h_stan = stan;
|
||||
char h_chan[16], h_mti[8], h_payload[512], h_bizdate[16];
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
|
||||
strncpy(h_chan, channel, sizeof(h_chan)-1); h_chan[sizeof(h_chan)-1] = 0;
|
||||
strncpy(h_mti, mti, sizeof(h_mti)-1); h_mti[sizeof(h_mti)-1] = 0;
|
||||
strncpy(h_payload, payload, sizeof(h_payload)-1); h_payload[sizeof(h_payload)-1] = 0;
|
||||
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
|
||||
|
||||
EXEC SQL INSERT INTO mg_queue (queue_id, stan, channel, mti, payload, status, biz_date)
|
||||
VALUES (:h_id, :h_stan, :h_chan, :h_mti, :h_payload, 'Q', :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) {
|
||||
userlog("mgdb_enqueue FAIL [%d] %s", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mgdb_set_queue_status(long queue_id, const char *status)
|
||||
{
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_id = queue_id;
|
||||
char h_status[4];
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
|
||||
strncpy(h_status, status, sizeof(h_status)-1); h_status[sizeof(h_status)-1] = 0;
|
||||
|
||||
EXEC SQL UPDATE mg_queue SET status = :h_status, updated_at = now()
|
||||
WHERE queue_id = :h_id;
|
||||
if (sqlca.sqlcode < 0 || sqlca.sqlcode == 100) {
|
||||
userlog("mgdb_set_queue_status FAIL [%d] %s", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
111
app/src/mg/dbio/mg_route_dbio.pgc
Normal file
111
app/src/mg/dbio/mg_route_dbio.pgc
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
/*
|
||||
* mg_route_dbio.pgc - 라우팅 룰 + 채널 세션 DB 접근 (part of libmgdbio.a).
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <userlog.h>
|
||||
#include "mg_dbio.h"
|
||||
|
||||
int mgdb_insert_route(long route_id, const char *channel, const char *mti,
|
||||
const char *dest, long priority, const char *bizdate)
|
||||
{
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_id = route_id, h_pri = priority;
|
||||
char h_chan[16], h_mti[8], h_dest[64], h_bizdate[16];
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
|
||||
strncpy(h_chan, channel, sizeof(h_chan)-1); h_chan[sizeof(h_chan)-1] = 0;
|
||||
strncpy(h_mti, mti, sizeof(h_mti)-1); h_mti[sizeof(h_mti)-1] = 0;
|
||||
strncpy(h_dest, dest, sizeof(h_dest)-1); h_dest[sizeof(h_dest)-1] = 0;
|
||||
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
|
||||
|
||||
EXEC SQL INSERT INTO mg_route (route_id, channel, mti, dest, priority, active, biz_date)
|
||||
VALUES (:h_id, :h_chan, :h_mti, :h_dest, :h_pri, true, :h_bizdate);
|
||||
if (sqlca.sqlcode < 0) {
|
||||
userlog("mgdb_insert_route FAIL [%d] %s", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* 채널+전문유형으로 활성 라우팅 목적지를 우선순위 순으로 1건 조회. */
|
||||
int mgdb_lookup_route(const char *channel, const char *mti, char *dest_out)
|
||||
{
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
char h_chan[16], h_mti[8], h_dest[64];
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
|
||||
strncpy(h_chan, channel, sizeof(h_chan)-1); h_chan[sizeof(h_chan)-1] = 0;
|
||||
strncpy(h_mti, mti, sizeof(h_mti)-1); h_mti[sizeof(h_mti)-1] = 0;
|
||||
|
||||
EXEC SQL SELECT dest INTO :h_dest FROM mg_route
|
||||
WHERE channel = :h_chan AND mti = :h_mti AND active = true
|
||||
ORDER BY priority ASC LIMIT 1;
|
||||
if (sqlca.sqlcode == 100) { dest_out[0] = 0; return -1; }
|
||||
if (sqlca.sqlcode < 0) {
|
||||
userlog("mgdb_lookup_route FAIL [%d] %s", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc);
|
||||
return -1;
|
||||
}
|
||||
strncpy(dest_out, h_dest, 63); dest_out[63] = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mgdb_get_channel_status(const char *channel, char *status_out)
|
||||
{
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
char h_chan[16], h_status[16];
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
|
||||
strncpy(h_chan, channel, sizeof(h_chan)-1); h_chan[sizeof(h_chan)-1] = 0;
|
||||
|
||||
EXEC SQL SELECT status INTO :h_status FROM mg_channel WHERE channel = :h_chan;
|
||||
if (sqlca.sqlcode == 100) { strcpy(status_out, "UNKNOWN"); return -1; }
|
||||
if (sqlca.sqlcode < 0) {
|
||||
userlog("mgdb_get_channel_status FAIL [%d] %s", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc);
|
||||
return -1;
|
||||
}
|
||||
strncpy(status_out, h_status, 15); status_out[15] = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mgdb_set_channel_status(const char *channel, const char *status)
|
||||
{
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
char h_chan[16], h_status[16];
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
|
||||
strncpy(h_chan, channel, sizeof(h_chan)-1); h_chan[sizeof(h_chan)-1] = 0;
|
||||
strncpy(h_status, status, sizeof(h_status)-1); h_status[sizeof(h_status)-1] = 0;
|
||||
|
||||
EXEC SQL UPDATE mg_channel SET status = :h_status, updated_at = now()
|
||||
WHERE channel = :h_chan;
|
||||
if (sqlca.sqlcode < 0) {
|
||||
userlog("mgdb_set_channel_status FAIL [%d] %s", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc);
|
||||
return -1;
|
||||
}
|
||||
if (sqlca.sqlcode == 100) { /* 신규 채널 등록 */
|
||||
EXEC SQL INSERT INTO mg_channel (channel, status) VALUES (:h_chan, :h_status);
|
||||
if (sqlca.sqlcode < 0) return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mgdb_set_channel_session(const char *channel, const char *session_key, long stan)
|
||||
{
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_stan = stan;
|
||||
char h_chan[16], h_key[64];
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
|
||||
strncpy(h_chan, channel, sizeof(h_chan)-1); h_chan[sizeof(h_chan)-1] = 0;
|
||||
strncpy(h_key, session_key, sizeof(h_key)-1); h_key[sizeof(h_key)-1] = 0;
|
||||
|
||||
EXEC SQL UPDATE mg_channel
|
||||
SET session_key = :h_key, last_stan = :h_stan, status = 'SIGNON',
|
||||
signon_at = now(), updated_at = now()
|
||||
WHERE channel = :h_chan;
|
||||
if (sqlca.sqlcode < 0 || sqlca.sqlcode == 100) {
|
||||
userlog("mgdb_set_channel_session FAIL [%d] %s", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue