创建
This commit is contained in:
14
server/CMakeLists.txt
Normal file
14
server/CMakeLists.txt
Normal file
@@ -0,0 +1,14 @@
|
||||
set (NIRVANA_PLATFORM_SRC doris_server_scandir.cpp doris_server_receive.cpp doris_server_http.cpp doris_server_main.cpp)
|
||||
|
||||
add_definitions(-fPIC -Wall -g)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D__FILENAME__='\"$(subst ${CMAKE_CURRENT_SOURCE_DIR}/,,$(abspath $<))\"'")
|
||||
|
||||
add_executable(doris ${NIRVANA_PLATFORM_SRC})
|
||||
target_link_libraries(doris doris_client_static libMesaMonitor libevent-static libevent-pthreads-static libcurl-static libevent-openssl-static openssl-ssl-static openssl-crypto-static cjson libLevelDB)
|
||||
target_link_libraries(doris MESA_handle_logger MESA_htable MESA_prof_load MESA_field_stat2 pthread z dl)
|
||||
set_target_properties(doris PROPERTIES CLEAN_DIRECT_OUTPUT 1)
|
||||
target_include_directories(doris PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)
|
||||
set_property(TARGET doris PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_CURRENT_SOURCE_DIR}/include)
|
||||
|
||||
INSTALL (DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/bin/ DESTINATION bin)
|
||||
INSTALL (TARGETS doris DESTINATION bin)
|
||||
57
server/bin/conf/doris_main.conf
Normal file
57
server/bin/conf/doris_main.conf
Normal file
@@ -0,0 +1,57 @@
|
||||
[DORIS_SERVER]
|
||||
worker_thread_num=2
|
||||
server_listen_port=9898
|
||||
manage_listen_port=2233
|
||||
|
||||
receive_config_way=2
|
||||
cache_file_frag_size=67108864
|
||||
store_config_path=./doris_store_path
|
||||
receive_config_path_full=./doris_receive_path/full/index
|
||||
receive_config_path_inc=./doris_receive_path/inc/index
|
||||
|
||||
run_log_dir=./log
|
||||
run_log_lv=20
|
||||
fsstat_log_appname=DorisServer
|
||||
fsstat_log_filepath=./log/doris_server.fs
|
||||
fsstat_log_interval=10
|
||||
fsstat_log_print_mode=1
|
||||
fsstat_log_dst_ip=192.168.10.90
|
||||
fsstat_log_dst_port=8125
|
||||
|
||||
|
||||
|
||||
[DORIS_CLIENT]
|
||||
fetch_fail_retry_interval=5
|
||||
fetch_fragmet_size=5242880
|
||||
fetch_confile_max_tries=3
|
||||
|
||||
fsstat_log_appname=DorisClient
|
||||
fsstat_log_filepath=./log/doris_client.fs
|
||||
fsstat_log_interval=2
|
||||
fsstat_log_print_mode=1
|
||||
fsstat_log_dst_ip=192.168.10.90
|
||||
fsstat_log_dst_port=8125
|
||||
|
||||
[DORIS_CLIENT.master_server]
|
||||
max_connection_per_host=1
|
||||
max_cnnt_pipeline_num=10
|
||||
https_connection_on=0
|
||||
max_curl_session_num=10
|
||||
|
||||
http_server_listen_port=9897
|
||||
http_server_manage_port=9897
|
||||
http_server_ip_list=192.168.10.8
|
||||
|
||||
[DORIS_CLIENT.backup1_server]
|
||||
max_connection_per_host=1
|
||||
max_cnnt_pipeline_num=10
|
||||
https_connection_on=0
|
||||
max_curl_session_num=10
|
||||
|
||||
http_server_listen_port=9897
|
||||
http_server_manage_port=9897
|
||||
http_server_ip_list=192.168.11.241
|
||||
|
||||
[DORIS_CLIENT.backup2_server]
|
||||
|
||||
|
||||
18
server/bin/doris_dmn.sh
Normal file
18
server/bin/doris_dmn.sh
Normal file
@@ -0,0 +1,18 @@
|
||||
#!/bin/bash
|
||||
while [ 1 ];
|
||||
do
|
||||
count=`ls -l core.* |wc -l`
|
||||
echo $count
|
||||
if [ $count -lt 3 ]
|
||||
then
|
||||
echo "set unlimited"
|
||||
ulimit -c unlimited
|
||||
else
|
||||
ulimit -c 0
|
||||
fi
|
||||
|
||||
./doris >> /dev/null
|
||||
echo program crashed, restart at `date +"%w %Y/%m/%d, %H:%M:%S"` >> RESTART.log
|
||||
sleep 30
|
||||
done
|
||||
|
||||
19
server/bin/doris_kill_by_mem.sh
Normal file
19
server/bin/doris_kill_by_mem.sh
Normal file
@@ -0,0 +1,19 @@
|
||||
#!/bin/sh
|
||||
|
||||
PROG="doris"
|
||||
|
||||
while true; do
|
||||
mem_used=`ps -C $PROG u | grep -v RSS | awk '{print $6}'`
|
||||
mem_rate=`ps -C $PROG -o %mem | tail -1`
|
||||
#cpu_used=`ps -C $PROG -o %cpu | tail -1`
|
||||
#echo "`date` -- $PROG used mem : $mem_used, $mem_rate%, $cpu_used%" >> doris_kill_by_mem.log
|
||||
if [ -z $mem_used ]; then
|
||||
mem_used=0
|
||||
elif [ $mem_used -gt 102400000 ]; then
|
||||
echo "`date` -- $PROG used mem : $mem_used, $mem_rate%, kill it!" >> RESTART.log
|
||||
killall $PROG;
|
||||
fi
|
||||
|
||||
sleep 10
|
||||
|
||||
done
|
||||
6
server/bin/doris_start.sh
Normal file
6
server/bin/doris_start.sh
Normal file
@@ -0,0 +1,6 @@
|
||||
#!/bin/bash
|
||||
source /etc/profile
|
||||
killall doris_kill_by_mem.sh doris_dmn.sh doris
|
||||
./doris_dmn.sh &>/dev/null &
|
||||
./doris_kill_by_mem.sh &>/dev/null &
|
||||
|
||||
2
server/bin/doris_stop.sh
Normal file
2
server/bin/doris_stop.sh
Normal file
@@ -0,0 +1,2 @@
|
||||
#!/bin/bash
|
||||
killall doris_kill_by_mem.sh doris_dmn.sh doris
|
||||
2
server/bin/memchk.sh
Normal file
2
server/bin/memchk.sh
Normal file
@@ -0,0 +1,2 @@
|
||||
#!/bin/sh
|
||||
valgrind --tool=memcheck --leak-check=full --leak-resolution=high --error-limit=no --undef-value-errors=yes --log-file=valgrind.log ./doris
|
||||
277
server/doris_server_http.cpp
Normal file
277
server/doris_server_http.cpp
Normal file
@@ -0,0 +1,277 @@
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <net/if.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <sys/prctl.h>
|
||||
#include <poll.h>
|
||||
|
||||
#include "doris_server_main.h"
|
||||
#include "doris_server_http.h"
|
||||
|
||||
|
||||
extern struct nirvana_global_info g_doris_server_info;
|
||||
|
||||
static inline void set_sockopt_keepalive(int sd, int keepidle, int keepintvl, int keepcnt)
|
||||
{
|
||||
int keepalive = 1;
|
||||
setsockopt(sd, SOL_SOCKET, SO_KEEPALIVE, (void*)&keepalive, sizeof(keepalive));
|
||||
setsockopt(sd, SOL_TCP, TCP_KEEPIDLE, (void*)&keepidle, sizeof(keepidle));
|
||||
setsockopt(sd, SOL_TCP, TCP_KEEPINTVL, (void*)&keepintvl, sizeof(keepintvl));
|
||||
setsockopt(sd, SOL_TCP, TCP_KEEPCNT, (void*)&keepcnt, sizeof(keepcnt));
|
||||
}
|
||||
|
||||
static inline void set_listen_sockopt(int sd)
|
||||
{
|
||||
if(g_doris_server_info.sock_recv_bufsize > 0)
|
||||
{
|
||||
setsockopt(sd, SOL_SOCKET, SO_RCVBUF, &g_doris_server_info.sock_recv_bufsize, sizeof(u_int32_t));
|
||||
}
|
||||
}
|
||||
|
||||
int doris_create_listen_socket(int bind_port)
|
||||
{
|
||||
evutil_socket_t listener;
|
||||
struct sockaddr_in sin;
|
||||
|
||||
listener = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if(listener < 0)
|
||||
{
|
||||
MESA_RUNTIME_LOGV3(g_doris_server_info.log_runtime, RLOG_LV_FATAL, "create socket error!\n");
|
||||
return -1;
|
||||
}
|
||||
set_sockopt_keepalive(listener, 300, 10, 2);
|
||||
set_listen_sockopt(listener);
|
||||
evutil_make_listen_socket_reuseable(listener);
|
||||
|
||||
sin.sin_family = AF_INET;
|
||||
sin.sin_addr.s_addr=htonl(INADDR_ANY);
|
||||
sin.sin_port = htons(bind_port);
|
||||
|
||||
if (bind(listener, (struct sockaddr *)&sin, sizeof(sin)) < 0)
|
||||
{
|
||||
printf("bind socket to port: %d error: %s!\n", bind_port, strerror(errno));
|
||||
MESA_RUNTIME_LOGV3(g_doris_server_info.log_runtime, RLOG_LV_FATAL, "bind socket to port: %d error: %s!\n", bind_port, strerror(errno));
|
||||
assert(0);return -2;
|
||||
}
|
||||
if (listen(listener, 1024)<0)
|
||||
{
|
||||
MESA_RUNTIME_LOGV3(g_doris_server_info.log_runtime, RLOG_LV_FATAL, "listen socket 1024 error!\n");
|
||||
return -3;
|
||||
}
|
||||
evutil_make_socket_nonblocking(listener);
|
||||
return listener;
|
||||
}
|
||||
|
||||
void doris_http_server_meta_cb(struct evhttp_request *req, void *arg)
|
||||
{
|
||||
struct worker_statistic_info *statistic=(struct worker_statistic_info *)arg;
|
||||
struct evkeyvalq params;
|
||||
const char *version;
|
||||
int64_t verlong;
|
||||
char *endptr=NULL, length[64];
|
||||
struct version_list_node *vernode;
|
||||
struct evbuffer *evbuf;
|
||||
|
||||
statistic->statistic.field[DRS_FSSTAT_CLIENT_META_REQ] += 1;
|
||||
if(evhttp_parse_query(evhttp_request_get_uri(req), ¶ms))
|
||||
{
|
||||
statistic->statistic.field[DRS_FSSTAT_CLIENT_INVALID_REQ] += 1;
|
||||
evhttp_send_error(req, HTTP_BADREQUEST, "Parameters invalid");
|
||||
return;
|
||||
}
|
||||
if(NULL == (version = evhttp_find_header(¶ms, "version")))
|
||||
{
|
||||
statistic->statistic.field[DRS_FSSTAT_CLIENT_INVALID_REQ] += 1;
|
||||
evhttp_send_error(req, HTTP_BADREQUEST, "Parameters invalid, no version found");
|
||||
return;
|
||||
}
|
||||
if(0==(verlong = strtol(version, &endptr, 10)) || *endptr!='\0')
|
||||
{
|
||||
statistic->statistic.field[DRS_FSSTAT_CLIENT_INVALID_REQ] += 1;
|
||||
evhttp_send_error(req, HTTP_BADREQUEST, "Parameter version invalid");
|
||||
return;
|
||||
}
|
||||
|
||||
pthread_rwlock_rdlock(&g_doris_server_info.rwlock);
|
||||
if(verlong > g_doris_server_info.cfgver_head->latest_version)
|
||||
{
|
||||
pthread_rwlock_unlock(&g_doris_server_info.rwlock);
|
||||
statistic->statistic.field[DRS_FSSTAT_SEND_META_NONEW] += 1;
|
||||
evhttp_send_error(req, HTTP_NOTMODIFIED, "No new configs found");
|
||||
return;
|
||||
}
|
||||
vernode = TAILQ_FIRST(&g_doris_server_info.cfgver_head->version_head);
|
||||
while(vernode->version < verlong)
|
||||
{
|
||||
vernode = TAILQ_NEXT(vernode, version_node);
|
||||
}
|
||||
evbuf = evbuffer_new();
|
||||
evbuffer_add(evbuf, vernode->metacont, vernode->metalen);
|
||||
sprintf(length, "%u", vernode->metalen);
|
||||
pthread_rwlock_unlock(&g_doris_server_info.rwlock);
|
||||
|
||||
statistic->statistic.field[DRS_FSSTAT_SEND_META_RES] += 1;
|
||||
evhttp_add_header(evhttp_request_get_output_headers(req), "Content-Type", "application/json");
|
||||
evhttp_add_header(evhttp_request_get_output_headers(req), "Connection", "keep-alive");
|
||||
evhttp_add_header(evhttp_request_get_output_headers(req), "Content-Length", length);
|
||||
evhttp_send_reply(req, HTTP_OK, "OK", evbuf);
|
||||
evbuffer_free(evbuf);
|
||||
}
|
||||
|
||||
void doris_response_file_range(struct evhttp_request *req, const char *tablename,
|
||||
int64_t verlong, size_t start, size_t end, bool range, struct worker_statistic_info *statistic)
|
||||
{
|
||||
struct version_list_node *vernode;
|
||||
struct table_list_node *tablenode;
|
||||
struct cont_frag_node *fragnode;
|
||||
struct evbuffer *evbuf;
|
||||
char length[128];
|
||||
size_t filesize, res_length=0, copy_len, offset=start;
|
||||
|
||||
pthread_rwlock_rdlock(&g_doris_server_info.rwlock);
|
||||
if(verlong > g_doris_server_info.cfgver_head->latest_version)
|
||||
{
|
||||
pthread_rwlock_unlock(&g_doris_server_info.rwlock);
|
||||
statistic->statistic.field[DRS_FSSTAT_SEND_FILE_RES_404] += 1;
|
||||
evhttp_send_error(req, HTTP_NOTFOUND, "Version too old");
|
||||
return;
|
||||
}
|
||||
vernode = TAILQ_FIRST(&g_doris_server_info.cfgver_head->version_head);
|
||||
while(vernode->version < verlong)
|
||||
{
|
||||
vernode = TAILQ_NEXT(vernode, version_node);
|
||||
}
|
||||
tablenode = TAILQ_FIRST(&vernode->table_head);
|
||||
while(tablenode!=NULL && strcmp(tablename, tablenode->tablename))
|
||||
{
|
||||
tablenode = TAILQ_NEXT(tablenode, table_node);
|
||||
}
|
||||
if(tablenode==NULL || start>tablenode->filesize)
|
||||
{
|
||||
pthread_rwlock_unlock(&g_doris_server_info.rwlock);
|
||||
statistic->statistic.field[DRS_FSSTAT_SEND_FILE_RES_404] += 1;
|
||||
evhttp_send_error(req, HTTP_NOTFOUND, "No valid content found");
|
||||
return;
|
||||
}
|
||||
filesize = tablenode->filesize;
|
||||
if(end==0 || end >= tablenode->filesize)
|
||||
{
|
||||
end = tablenode->filesize - 1;
|
||||
}
|
||||
evbuf = evbuffer_new();
|
||||
for(fragnode=TAILQ_FIRST(&tablenode->frag_head); fragnode!=NULL && fragnode->start<=end; fragnode=TAILQ_NEXT(fragnode, frag_node))
|
||||
{
|
||||
if(offset > fragnode->end)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
copy_len = (end>fragnode->end)?(fragnode->end-offset + 1):(end-offset + 1);
|
||||
evbuffer_add(evbuf, fragnode->content+(offset-fragnode->start), copy_len);
|
||||
offset += copy_len;
|
||||
res_length += copy_len;
|
||||
}
|
||||
pthread_rwlock_unlock(&g_doris_server_info.rwlock);
|
||||
|
||||
assert(res_length == end + 1 - start);
|
||||
sprintf(length, "%lu", res_length);
|
||||
statistic->statistic.field[DRS_FSSTAT_SEND_FILE_RES] += 1;
|
||||
statistic->statistic.field[DRS_FSSTAT_SEND_FILE_BYTES] += res_length;
|
||||
evhttp_add_header(evhttp_request_get_output_headers(req), "Content-Length", length);
|
||||
if(range)
|
||||
{
|
||||
sprintf(length, "bytes %lu-%lu/%lu", start, end, filesize);
|
||||
evhttp_add_header(evhttp_request_get_output_headers(req), "Content-Range", length);
|
||||
}
|
||||
evhttp_add_header(evhttp_request_get_output_headers(req), "Content-Type", "application/stream");
|
||||
evhttp_add_header(evhttp_request_get_output_headers(req), "Connection", "keep-alive");
|
||||
evhttp_send_reply(req, HTTP_OK, "OK", evbuf);
|
||||
}
|
||||
|
||||
void doris_http_server_file_cb(struct evhttp_request *req, void *arg)
|
||||
{
|
||||
struct worker_statistic_info *statistic=(struct worker_statistic_info *)arg;
|
||||
struct evkeyvalq params;
|
||||
const char *version, *tablename, *content_range;
|
||||
int64_t verlong;
|
||||
char *endptr=NULL;
|
||||
size_t req_start=0, req_end=0;
|
||||
|
||||
statistic->statistic.field[DRS_FSSTAT_CLIENT_FILE_REQ] += 1;
|
||||
if(evhttp_parse_query(evhttp_request_get_uri(req), ¶ms))
|
||||
{
|
||||
statistic->statistic.field[DRS_FSSTAT_CLIENT_INVALID_REQ] += 1;
|
||||
evhttp_send_error(req, HTTP_BADREQUEST, "Parameters invalid");
|
||||
return;
|
||||
}
|
||||
if(NULL==(version=evhttp_find_header(¶ms, "version")) || NULL==(tablename=evhttp_find_header(¶ms, "tablename")))
|
||||
{
|
||||
statistic->statistic.field[DRS_FSSTAT_CLIENT_INVALID_REQ] += 1;
|
||||
evhttp_send_error(req, HTTP_BADREQUEST, "Parameters invalid, no version/tablename found");
|
||||
return;
|
||||
}
|
||||
if(0==(verlong = strtol(version, &endptr, 10)) || *endptr!='\0')
|
||||
{
|
||||
statistic->statistic.field[DRS_FSSTAT_CLIENT_INVALID_REQ] += 1;
|
||||
evhttp_send_error(req, HTTP_BADREQUEST, "Parameter version invalid");
|
||||
return;
|
||||
}
|
||||
if(NULL!=(content_range = evhttp_find_header(evhttp_request_get_input_headers(req), "Range")) &&
|
||||
sscanf(content_range, "%*[^0-9]%lu-%lu", &req_start, &req_end)<1)
|
||||
{
|
||||
statistic->statistic.field[DRS_FSSTAT_CLIENT_INVALID_REQ] += 1;
|
||||
evhttp_send_error(req, HTTP_BADREQUEST, "Header Range invalid");
|
||||
return;
|
||||
}
|
||||
|
||||
doris_response_file_range(req, tablename, verlong, req_start, req_end, (content_range==NULL)?false:true, statistic);
|
||||
}
|
||||
|
||||
void doris_http_server_generic_cb(struct evhttp_request *req, void *arg)
|
||||
{
|
||||
evhttp_send_error(req, HTTP_BADREQUEST, "Not Supported.");
|
||||
}
|
||||
|
||||
void* thread_doris_http_server(void *arg)
|
||||
{
|
||||
struct event_base *worker_evbase;
|
||||
struct evhttp *worker_http;
|
||||
struct worker_statistic_info statistic;
|
||||
struct timeval tv;
|
||||
|
||||
prctl(PR_SET_NAME, "http_server");
|
||||
|
||||
memset(&statistic, 0, sizeof(struct worker_statistic_info));
|
||||
worker_evbase = event_base_new();
|
||||
|
||||
worker_http = evhttp_new(worker_evbase);
|
||||
|
||||
evhttp_set_cb(worker_http, "/configmeta", doris_http_server_meta_cb, &statistic);
|
||||
evhttp_set_cb(worker_http, "/configfile", doris_http_server_file_cb, &statistic);
|
||||
evhttp_set_gencb(worker_http, doris_http_server_generic_cb, &statistic);
|
||||
evhttp_set_allowed_methods(worker_http, EVHTTP_REQ_GET|EVHTTP_REQ_HEAD);
|
||||
|
||||
if(evhttp_accept_socket(worker_http, g_doris_server_info.listener))
|
||||
{
|
||||
printf("evhttp_accept_socket %d error!\n", g_doris_server_info.listener);
|
||||
assert(0); return NULL;
|
||||
}
|
||||
|
||||
evtimer_assign(&statistic.timer_statistic, worker_evbase, doris_worker_statistic_timer_cb, &statistic);
|
||||
tv.tv_sec = g_doris_server_info.fsstat_period;
|
||||
tv.tv_usec = 0;
|
||||
evtimer_add(&statistic.timer_statistic, &tv);
|
||||
|
||||
event_base_dispatch(worker_evbase);
|
||||
printf("Libevent dispath error, should not run here.\n");
|
||||
MESA_RUNTIME_LOGV3(g_doris_server_info.log_runtime, RLOG_LV_FATAL, "Libevent dispath error, should not run here.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
8
server/doris_server_http.h
Normal file
8
server/doris_server_http.h
Normal file
@@ -0,0 +1,8 @@
|
||||
#ifndef __DORIS_SERVER_HTTP_H__
|
||||
#define __DORIS_SERVER_HTTP_H__
|
||||
|
||||
int doris_create_listen_socket(int bind_port);
|
||||
void* thread_doris_http_server(void *arg);
|
||||
|
||||
#endif
|
||||
|
||||
306
server/doris_server_main.cpp
Normal file
306
server/doris_server_main.cpp
Normal file
@@ -0,0 +1,306 @@
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <event2/thread.h>
|
||||
|
||||
#include <MESA/MESA_prof_load.h>
|
||||
|
||||
#include "doris_client.h"
|
||||
#include "doris_server_main.h"
|
||||
#include "doris_server_http.h"
|
||||
|
||||
struct nirvana_global_info g_doris_server_info;
|
||||
static unsigned long doris_vesion_20210716=20210716L;
|
||||
|
||||
int doris_mkdir_according_path(const char * path)
|
||||
{
|
||||
char buffer[256];
|
||||
const char *ps=path, *pc;
|
||||
|
||||
if(*ps == '/')
|
||||
ps += 1;
|
||||
|
||||
while((pc = strchr(ps, '/')) != NULL)
|
||||
{
|
||||
while(*(pc+1) == '/')
|
||||
pc++;
|
||||
|
||||
memcpy(buffer, path, pc - path);
|
||||
buffer[pc-path] = '\0';
|
||||
|
||||
if(access(buffer, F_OK))
|
||||
{
|
||||
if(mkdir(buffer, 0777))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
ps = pc + 1;
|
||||
}
|
||||
if(access(path, F_OK))
|
||||
{
|
||||
if(mkdir(path, 0777))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t doris_read_profile_configs(const char *config_file)
|
||||
{
|
||||
char tmp_buf[4096], tmp_dir[512], tmp_dir2[512];
|
||||
|
||||
MESA_load_profile_string_def(config_file, "DORIS_SERVER", "run_log_dir", g_doris_server_info.root_log_dir, sizeof(g_doris_server_info.root_log_dir), "./log");
|
||||
MESA_load_profile_uint_def(config_file, "DORIS_SERVER", "run_log_lv", &g_doris_server_info.log_level, 10);
|
||||
MESA_load_profile_uint_def(config_file, "DORIS_SERVER", "statistic_log_interval", &g_doris_server_info.statistic_period, 300);
|
||||
/*runtimelog*/
|
||||
snprintf(tmp_dir, 256, "%s/runtime_log", g_doris_server_info.root_log_dir);
|
||||
if(doris_mkdir_according_path(tmp_dir))
|
||||
{
|
||||
printf("mkdir %s for duran runtimelog failed: %s\n", tmp_dir, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
snprintf(tmp_buf, 256, "%s/nirvana_runtime.log", tmp_dir);
|
||||
g_doris_server_info.log_runtime = MESA_create_runtime_log_handle(tmp_buf, g_doris_server_info.log_level);
|
||||
if(NULL==g_doris_server_info.log_runtime)
|
||||
{
|
||||
printf("MESA_create_runtime_log_handle %s failed: %s\n", tmp_buf, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*System*/
|
||||
MESA_load_profile_uint_def(config_file, "DORIS_SERVER", "worker_thread_num", &g_doris_server_info.iothreads, 1);
|
||||
if(g_doris_server_info.iothreads > 255)
|
||||
{
|
||||
printf("%s: [DORIS_SERVER]worker_thread_num=%d should not be bigger than 255!", config_file, g_doris_server_info.iothreads);
|
||||
MESA_RUNTIME_LOGV3(g_doris_server_info.log_runtime, RLOG_LV_FATAL, "%s: [DORIS_SERVER]worker_thread_num=%d should not be bigger than 255!", config_file, g_doris_server_info.iothreads);
|
||||
assert(0);return -1;
|
||||
}
|
||||
MESA_load_profile_uint_def(config_file, "DORIS_SERVER", "cache_file_frag_size", &g_doris_server_info.cache_frag_size, 67108864);
|
||||
MESA_load_profile_uint_def(config_file, "DORIS_SERVER", "doris_server_role_on", &g_doris_server_info.server_role_sw, 1);
|
||||
MESA_load_profile_uint_def(config_file, "DORIS_SERVER", "doris_write_file_on", &g_doris_server_info.write_file_sw, 1);
|
||||
|
||||
if(0>MESA_load_profile_string_nodef(config_file, "DORIS_SERVER", "store_config_path", g_doris_server_info.store_path_root, sizeof(g_doris_server_info.store_path_root)))
|
||||
{
|
||||
MESA_RUNTIME_LOGV3(g_doris_server_info.log_runtime, RLOG_LV_FATAL, "%s: [DORIS_SERVER]store_config_path not found!", config_file);
|
||||
assert(0);return -1;
|
||||
}
|
||||
snprintf(tmp_dir, 512, "%s/full/index", g_doris_server_info.store_path_root);
|
||||
snprintf(tmp_dir2,512, "%s/inc/index", g_doris_server_info.store_path_root);
|
||||
if(doris_mkdir_according_path(tmp_dir) || doris_mkdir_according_path(tmp_dir2))
|
||||
{
|
||||
MESA_RUNTIME_LOGV3(g_doris_server_info.log_runtime, RLOG_LV_FATAL, "mkdir %s failed: %s\n", tmp_dir, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
MESA_load_profile_uint_def(config_file, "DORIS_SERVER", "receive_config_way", &g_doris_server_info.recv_way, RECV_WAY_DRS_CLIENT);
|
||||
if(g_doris_server_info.recv_way == RECV_WAY_IDX_FILE)
|
||||
{
|
||||
if(0>MESA_load_profile_string_nodef(config_file, "DORIS_SERVER", "receive_config_path_full", g_doris_server_info.recv_path_full, sizeof(g_doris_server_info.recv_path_full)))
|
||||
{
|
||||
MESA_RUNTIME_LOGV3(g_doris_server_info.log_runtime, RLOG_LV_FATAL, "%s: [DORIS_SERVER]receive_config_path not found!", config_file);
|
||||
assert(0);return -1;
|
||||
}
|
||||
if(0>MESA_load_profile_string_nodef(config_file, "DORIS_SERVER", "receive_config_path_inc", g_doris_server_info.recv_path_inc, sizeof(g_doris_server_info.recv_path_inc)))
|
||||
{
|
||||
MESA_RUNTIME_LOGV3(g_doris_server_info.log_runtime, RLOG_LV_FATAL, "%s: [DORIS_SERVER]receive_config_path not found!", config_file);
|
||||
assert(0);return -1;
|
||||
}
|
||||
MESA_load_profile_uint_def(config_file, "DORIS_SERVER", "scan_index_file_interval", &g_doris_server_info.scan_idx_interval, 10);
|
||||
}
|
||||
|
||||
MESA_load_profile_uint_def(config_file, "DORIS_SERVER", "ssl_tcp_connection_on", &g_doris_server_info.ssl_conn_on, 0);
|
||||
if(g_doris_server_info.ssl_conn_on)
|
||||
{
|
||||
MESA_load_profile_string_def(config_file, "DORIS_SERVER", "ssl_trusted_ca_path", g_doris_server_info.ssl_CA_path, 256, "./conf/ssl_CA_path/");
|
||||
MESA_load_profile_string_def(config_file, "DORIS_SERVER", "ssl_certificate_file", g_doris_server_info.ssl_cert_file, 256, "./conf/server_cert.pem");
|
||||
MESA_load_profile_string_def(config_file, "DORIS_SERVER", "ssl_private_key_file", g_doris_server_info.ssl_key_file, 256, "./conf/server_key.pem");
|
||||
MESA_load_profile_string_def(config_file, "DORIS_SERVER", "ssl_private_key_passwd", g_doris_server_info.ssl_key_passwd, 64, "12345678");
|
||||
}
|
||||
|
||||
/*FiledStat*/
|
||||
MESA_load_profile_string_def(config_file, "DORIS_SERVER", "fsstat_log_appname", g_doris_server_info.fsstat_appname, 16, "DORIS_SERVER_S");
|
||||
MESA_load_profile_string_def(config_file, "DORIS_SERVER", "fsstat_log_filepath", g_doris_server_info.fsstat_filepath, 256, "./log/nirvana_server.fs");
|
||||
MESA_load_profile_uint_def(config_file, "DORIS_SERVER", "fsstat_log_interval", &g_doris_server_info.fsstat_period, 10);
|
||||
MESA_load_profile_int_def(config_file, "DORIS_SERVER", "fsstat_log_print_mode", &g_doris_server_info.fsstat_print_mode, 1);
|
||||
MESA_load_profile_string_def(config_file, "DORIS_SERVER", "fsstat_log_dst_ip", g_doris_server_info.fsstat_dst_ip, 64, "127.0.0.1");
|
||||
MESA_load_profile_int_def(config_file, "DORIS_SERVER", "fsstat_log_dst_port", &g_doris_server_info.fsstat_dst_port, 8125);
|
||||
|
||||
//LIBEVENT
|
||||
MESA_load_profile_int_def(config_file, "DORIS_SERVER", "server_listen_port", &g_doris_server_info.server_port, 9898);
|
||||
MESA_load_profile_int_def(config_file, "DORIS_SERVER", "manage_listen_port", &g_doris_server_info.manager_port, 2233);
|
||||
MESA_load_profile_int_def(config_file, "DORIS_SERVER", "socket_recv_bufsize", &g_doris_server_info.sock_recv_bufsize, 524288);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int doris_server_register_field_stat(struct nirvana_global_info *param)
|
||||
{
|
||||
const char *field_names[DRS_FSSTAT_FIELD_NUM]={"RecvFullVer", "RecvIncVer", "RecvErrVer", "FileStarts", "FileComplete",
|
||||
"ClientInvReq", "ClientMetaReq", "SendResMeta", "SendNoNewMeta", "ClientFileReq", "SendFiles", "SendBytes", "SendFile404"};
|
||||
const char *status_names[DRS_FSSTAT_STATUS_NUM]={"MemoryUsed", "CurFullVer", "CurIncVer", "TotalCfgNum"};
|
||||
int value;
|
||||
|
||||
param->fsstat_handle = FS_create_handle();
|
||||
FS_set_para(param->fsstat_handle, OUTPUT_DEVICE, param->fsstat_filepath, strlen(param->fsstat_filepath)+1);
|
||||
if(param->fsstat_print_mode == 1)
|
||||
{
|
||||
FS_set_para(param->fsstat_handle, PRINT_MODE, ¶m->fsstat_print_mode, sizeof(param->fsstat_print_mode));
|
||||
}
|
||||
else
|
||||
{
|
||||
FS_set_para(param->fsstat_handle, PRINT_MODE, ¶m->fsstat_print_mode, sizeof(param->fsstat_print_mode));
|
||||
value = 1;
|
||||
FS_set_para(param->fsstat_handle, FLUSH_BY_DATE, &value, sizeof(value));
|
||||
}
|
||||
value = param->fsstat_period;
|
||||
FS_set_para(param->fsstat_handle, STAT_CYCLE, &value, sizeof(value));
|
||||
value = 0;
|
||||
FS_set_para(param->fsstat_handle, CREATE_THREAD, &value, sizeof(value));
|
||||
FS_set_para(param->fsstat_handle, APP_NAME, param->fsstat_appname, strlen(param->fsstat_appname)+1);
|
||||
FS_set_para(param->fsstat_handle, STATS_SERVER_IP, param->fsstat_dst_ip, strlen(param->fsstat_dst_ip)+1);
|
||||
FS_set_para(param->fsstat_handle, STATS_SERVER_PORT, ¶m->fsstat_dst_port, sizeof(param->fsstat_dst_port));
|
||||
|
||||
for(int i=0; i<DRS_FSSTAT_FIELD_NUM; i++)
|
||||
{
|
||||
param->fsstat_field[i] = FS_register(param->fsstat_handle, FS_STYLE_FIELD, FS_CALC_CURRENT, field_names[i]);
|
||||
}
|
||||
for(int i=0; i<DRS_FSSTAT_STATUS_NUM; i++)
|
||||
{
|
||||
param->fsstat_status[i] = FS_register(param->fsstat_handle, FS_STYLE_STATUS, FS_CALC_CURRENT, status_names[i]);
|
||||
}
|
||||
FS_start(param->fsstat_handle);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void instance_fsstat_output_timer_cb(int fd, short kind, void *userp)
|
||||
{
|
||||
struct timeval tv;
|
||||
|
||||
FS_passive_output(g_doris_server_info.fsstat_handle);
|
||||
|
||||
tv.tv_sec = g_doris_server_info.fsstat_period;
|
||||
tv.tv_usec = 0;
|
||||
event_add((struct event*)userp, &tv);
|
||||
}
|
||||
|
||||
static void manager_statistic_threads_requests_cb(struct evhttp_request *req, void *arg)
|
||||
{
|
||||
evhttp_send_error(req, HTTP_BADREQUEST, "Not Supported.");
|
||||
}
|
||||
|
||||
static void manager_statistic_status_requests_cb(struct evhttp_request *req, void *arg)
|
||||
{
|
||||
evhttp_send_error(req, HTTP_BADREQUEST, "Not Supported.");
|
||||
}
|
||||
|
||||
static void manager_statistic_field_requests_cb(struct evhttp_request *req, void *arg)
|
||||
{
|
||||
evhttp_send_error(req, HTTP_BADREQUEST, "Not Supported.");
|
||||
}
|
||||
|
||||
void manager_generic_requests_cb(struct evhttp_request *req, void *arg)
|
||||
{
|
||||
evhttp_send_error(req, HTTP_BADREQUEST, "Not Supported.");
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
struct event_base *manage_evbase;
|
||||
pthread_t thread_desc;
|
||||
pthread_attr_t attr;
|
||||
struct timeval tv;
|
||||
struct event timer_statistic_fsstat;
|
||||
struct evhttp *manager_http;
|
||||
|
||||
if(doris_read_profile_configs(NIRVANA_CONFIG_FILE) || doris_server_register_field_stat(&g_doris_server_info))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
g_doris_server_info.cfgver_head = config_version_handle_new();
|
||||
pthread_rwlock_init(&g_doris_server_info.rwlock, NULL);
|
||||
evthread_use_pthreads();
|
||||
manage_evbase = event_base_new();
|
||||
|
||||
pthread_attr_init(&attr);
|
||||
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
|
||||
if(g_doris_server_info.recv_way == RECV_WAY_DRS_CLIENT)
|
||||
{
|
||||
if(pthread_create(&thread_desc, &attr, thread_doris_client_recv_cfg, manage_evbase))
|
||||
{
|
||||
MESA_RUNTIME_LOGV3(g_doris_server_info.log_runtime, RLOG_LV_FATAL, "pthread_create(): %s", strerror(errno));
|
||||
assert(0);return -4;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(pthread_create(&thread_desc, &attr, thread_index_file_recv_cfg, NULL))
|
||||
{
|
||||
MESA_RUNTIME_LOGV3(g_doris_server_info.log_runtime, RLOG_LV_FATAL, "pthread_create(): %s", strerror(errno));
|
||||
assert(0);return -4;
|
||||
}
|
||||
}
|
||||
|
||||
/*Doris manager server*/
|
||||
g_doris_server_info.manager = doris_create_listen_socket(g_doris_server_info.manager_port);
|
||||
if(g_doris_server_info.manager < 0)
|
||||
{
|
||||
return -6;
|
||||
}
|
||||
if(NULL == (manager_http = evhttp_new(manage_evbase)))
|
||||
{
|
||||
printf("evhttp_new error!\n");
|
||||
assert(0); return -2;
|
||||
}
|
||||
evhttp_set_cb(manager_http, "/doris/statistic/field", manager_statistic_field_requests_cb, NULL);
|
||||
evhttp_set_cb(manager_http, "/doris/statistic/status", manager_statistic_status_requests_cb, NULL);
|
||||
evhttp_set_cb(manager_http, "/doris/statistic/threads", manager_statistic_threads_requests_cb, NULL);
|
||||
evhttp_set_gencb(manager_http, manager_generic_requests_cb, NULL);
|
||||
g_doris_server_info.monitor = MESA_Monitor_instance_evhttp_new(manager_http, doris_vesion_20210716);
|
||||
g_doris_server_info.mm_latest_ver = MESA_Monitor_register(g_doris_server_info.monitor, "latest_cfg_version", MONITOR_METRICS_GAUGE, "Latest doris config version.");
|
||||
g_doris_server_info.mm_total_cfgnum = MESA_Monitor_register(g_doris_server_info.monitor, "total_config_num", MONITOR_METRICS_GAUGE, "Total config num from latest full version till now.");
|
||||
|
||||
if(evhttp_accept_socket(manager_http, g_doris_server_info.manager))
|
||||
{
|
||||
printf("evhttp_accept_socket %d error!\n", g_doris_server_info.manager);
|
||||
MESA_RUNTIME_LOGV3(g_doris_server_info.log_runtime, RLOG_LV_FATAL, "evhttp_accept_socket %d error!\n", g_doris_server_info.manager);
|
||||
assert(0); return -7;
|
||||
}
|
||||
|
||||
/*Doris http server*/
|
||||
if(g_doris_server_info.server_role_sw)
|
||||
{
|
||||
g_doris_server_info.listener = doris_create_listen_socket(g_doris_server_info.server_port);
|
||||
if(g_doris_server_info.listener < 0)
|
||||
{
|
||||
return -5;
|
||||
}
|
||||
for(u_int32_t i=0; i<g_doris_server_info.iothreads; i++)
|
||||
{
|
||||
if(pthread_create(&thread_desc, &attr, thread_doris_http_server, NULL))
|
||||
{
|
||||
MESA_RUNTIME_LOGV3(g_doris_server_info.log_runtime, RLOG_LV_FATAL, "pthread_create(): %s", strerror(errno));
|
||||
assert(0);return -4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tv.tv_sec = g_doris_server_info.fsstat_period;
|
||||
tv.tv_usec = 0;
|
||||
evtimer_assign(&timer_statistic_fsstat, manage_evbase, instance_fsstat_output_timer_cb, &timer_statistic_fsstat);
|
||||
evtimer_add(&timer_statistic_fsstat, &tv);
|
||||
|
||||
event_base_dispatch(manage_evbase);
|
||||
printf("Libevent dispath error, should not run here.\n");
|
||||
MESA_RUNTIME_LOGV3(g_doris_server_info.log_runtime, RLOG_LV_FATAL, "Libevent dispath error, should not run here.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
87
server/doris_server_main.h
Normal file
87
server/doris_server_main.h
Normal file
@@ -0,0 +1,87 @@
|
||||
#ifndef __DORIS_SERVER_MAIN_H__
|
||||
#define __DORIS_SERVER_MAIN_H__
|
||||
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/crypto.h>
|
||||
#include <openssl/x509.h>
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/rsa.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include <event.h>
|
||||
#include <evhttp.h>
|
||||
|
||||
#include <MESA/field_stat2.h>
|
||||
#include <MESA/MESA_htable.h>
|
||||
#include <MESA/MESA_handle_logger.h>
|
||||
|
||||
#include "MESA_Monitor.h"
|
||||
|
||||
#include "doris_server_receive.h"
|
||||
|
||||
#ifndef __FILENAME__
|
||||
#define __FILENAME__ __FILE__
|
||||
#endif
|
||||
#define MESA_RUNTIME_LOGV3(handle, lv, fmt, args...) \
|
||||
MESA_handle_runtime_log((handle), (lv), "DorisServer", "%s:%d, " fmt, __FILENAME__, __LINE__, ##args)
|
||||
|
||||
#define NIRVANA_CONFIG_FILE "./conf/doris_main.conf"
|
||||
|
||||
#define RECV_WAY_DRS_CLIENT 1
|
||||
#define RECV_WAY_IDX_FILE 2
|
||||
|
||||
struct nirvana_global_info
|
||||
{
|
||||
u_int32_t iothreads;
|
||||
int32_t server_port;
|
||||
int32_t manager_port;
|
||||
int32_t sock_recv_bufsize;
|
||||
u_int32_t ssl_conn_on;
|
||||
u_int32_t recv_way;
|
||||
char recv_path_full[256];
|
||||
char recv_path_inc[256];
|
||||
char store_path_root[256];
|
||||
char store_path_inc[256];
|
||||
u_int32_t scan_idx_interval;
|
||||
u_int32_t cache_frag_size;
|
||||
u_int32_t server_role_sw;
|
||||
u_int32_t write_file_sw;
|
||||
|
||||
char ssl_CA_path[256];
|
||||
char ssl_cert_file[256];
|
||||
char ssl_key_file[256];
|
||||
char ssl_key_passwd[64];
|
||||
pthread_mutex_t *lock_cs;
|
||||
SSL_CTX *ssl_instance;
|
||||
|
||||
struct version_list_handle *cfgver_head;
|
||||
evutil_socket_t listener;
|
||||
evutil_socket_t manager;
|
||||
pthread_rwlock_t rwlock;
|
||||
|
||||
struct MESA_MonitorHandler *monitor;
|
||||
int32_t mm_latest_ver;
|
||||
int32_t mm_total_cfgnum;
|
||||
|
||||
/*logs*/
|
||||
u_int32_t log_level;
|
||||
u_int32_t statistic_period;
|
||||
char root_log_dir[256];
|
||||
void *log_runtime;
|
||||
|
||||
screen_stat_handle_t fsstat_handle;
|
||||
char fsstat_dst_ip[64];
|
||||
char fsstat_appname[16];
|
||||
char fsstat_filepath[256];
|
||||
u_int32_t fsstat_period;
|
||||
int32_t fsstat_print_mode;
|
||||
int32_t fsstat_dst_port;
|
||||
int32_t fsstat_field[DRS_FSSTAT_FIELD_NUM];
|
||||
int32_t fsstat_status[DRS_FSSTAT_STATUS_NUM];
|
||||
};
|
||||
|
||||
int doris_mkdir_according_path(const char * path);
|
||||
|
||||
#endif
|
||||
|
||||
739
server/doris_server_receive.cpp
Normal file
739
server/doris_server_receive.cpp
Normal file
@@ -0,0 +1,739 @@
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
#include <string.h>
|
||||
#include <sys/prctl.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "doris_server_main.h"
|
||||
#include "doris_server_scandir.h"
|
||||
#include "doris_server_receive.h"
|
||||
|
||||
struct scanner_timer_priv
|
||||
{
|
||||
struct doris_callbacks doris_cbs;
|
||||
struct doris_arguments doris_args;
|
||||
struct doris_idxfile_scanner *scanner;
|
||||
struct event timer_scanner;
|
||||
};
|
||||
|
||||
extern struct nirvana_global_info g_doris_server_info;
|
||||
|
||||
|
||||
void doris_worker_statistic_timer_cb(int fd, short kind, void *userp)
|
||||
{
|
||||
struct worker_statistic_info *statistic = (struct worker_statistic_info *)userp;
|
||||
struct timeval tv;
|
||||
struct doris_srv_statistics incr_statistic;
|
||||
long long *plast_statistic = (long long*)&statistic->statistic_last;
|
||||
long long *pnow_statistic = (long long*)&statistic->statistic;
|
||||
long long *pinc_statistic = (long long*)&incr_statistic;
|
||||
|
||||
for(u_int32_t i=0; i<sizeof(struct doris_srv_statistics)/sizeof(long long); i++)
|
||||
{
|
||||
pinc_statistic[i] = pnow_statistic[i] - plast_statistic[i];
|
||||
}
|
||||
statistic->statistic_last = statistic->statistic;
|
||||
|
||||
for(u_int32_t i=0; i<DRS_FSSTAT_FIELD_NUM; i++)
|
||||
{
|
||||
FS_operate(g_doris_server_info.fsstat_handle, g_doris_server_info.fsstat_field[i], 0, FS_OP_ADD, incr_statistic.field[i]);
|
||||
}
|
||||
for(u_int32_t i=0; i<DRS_FSSTAT_STATUS_NUM; i++)
|
||||
{
|
||||
FS_operate(g_doris_server_info.fsstat_handle, g_doris_server_info.fsstat_status[i], 0, FS_OP_ADD, incr_statistic.status[i]);
|
||||
}
|
||||
tv.tv_sec = g_doris_server_info.fsstat_period;
|
||||
tv.tv_usec = 0;
|
||||
event_add(&statistic->timer_statistic, &tv);
|
||||
}
|
||||
|
||||
void config_frag_node_cleanup(struct confile_save *save, struct cont_frag_node *fragnode)
|
||||
{
|
||||
if(fragnode == NULL) return;
|
||||
|
||||
save->statistic.statistic.status[DRS_FSSTAT_MEMORY_USED] -= fragnode->totalsize;
|
||||
free(fragnode->content);
|
||||
free(fragnode);
|
||||
}
|
||||
|
||||
void config_table_node_cleanup(struct confile_save *save, struct table_list_node *table_node)
|
||||
{
|
||||
struct cont_frag_node *fragnode;
|
||||
|
||||
if(table_node == NULL) return;
|
||||
|
||||
while(NULL != (fragnode = TAILQ_FIRST(&table_node->frag_head)))
|
||||
{
|
||||
TAILQ_REMOVE(&table_node->frag_head, fragnode, frag_node);
|
||||
config_frag_node_cleanup(save, fragnode);
|
||||
}
|
||||
free(table_node);
|
||||
}
|
||||
|
||||
void config_version_node_cleanup(struct confile_save *save, struct version_list_node *vernode)
|
||||
{
|
||||
struct table_list_node *tablenode;
|
||||
|
||||
if(vernode == NULL) return;
|
||||
|
||||
while(NULL != (tablenode = TAILQ_FIRST(&vernode->table_head)))
|
||||
{
|
||||
TAILQ_REMOVE(&vernode->table_head, tablenode, table_node);
|
||||
config_table_node_cleanup(save, tablenode);
|
||||
}
|
||||
free(vernode->metacont);
|
||||
cJSON_Delete(vernode->metajson);
|
||||
cJSON_Delete(vernode->arrayjson);
|
||||
free(vernode);
|
||||
}
|
||||
|
||||
void config_version_handle_cleanup(struct confile_save *save, struct version_list_handle *version)
|
||||
{
|
||||
struct version_list_node *vernode;
|
||||
|
||||
while(NULL != (vernode = TAILQ_FIRST(&version->version_head)))
|
||||
{
|
||||
TAILQ_REMOVE(&version->version_head, vernode, version_node);
|
||||
config_version_node_cleanup(save, vernode);
|
||||
}
|
||||
free(version);
|
||||
}
|
||||
|
||||
struct version_list_handle *config_version_handle_new(void)
|
||||
{
|
||||
struct version_list_handle *handle;
|
||||
|
||||
handle = (struct version_list_handle *)calloc(1, sizeof(struct version_list_handle));
|
||||
TAILQ_INIT(&handle->version_head);
|
||||
return handle;
|
||||
}
|
||||
|
||||
static void doris_common_timer_start(struct event *time_event)
|
||||
{
|
||||
struct timeval tv;
|
||||
|
||||
tv.tv_sec = 2;
|
||||
tv.tv_usec = 0;
|
||||
evtimer_add(time_event, &tv);
|
||||
}
|
||||
|
||||
static void cfgver_delay_destroy_timer_cb(int fd, short kind, void *userp)
|
||||
{
|
||||
struct common_timer_event *delay_event=(struct common_timer_event *)userp;
|
||||
struct version_list_handle *handle = (struct version_list_handle *)delay_event->data;
|
||||
|
||||
if(handle->references != 0)
|
||||
{
|
||||
doris_common_timer_start(&delay_event->timer_event);
|
||||
return;
|
||||
}
|
||||
config_version_handle_cleanup(delay_event->save, handle);
|
||||
free(delay_event);
|
||||
}
|
||||
|
||||
static void cfgver_handle_delay_destroy(struct confile_save *save, struct event_base *evbase, struct version_list_handle *version)
|
||||
{
|
||||
struct common_timer_event *delay_event;
|
||||
|
||||
delay_event = (struct common_timer_event *)malloc(sizeof(struct common_timer_event));
|
||||
delay_event->data = version;
|
||||
delay_event->save = save;
|
||||
evtimer_assign(&delay_event->timer_event, evbase, cfgver_delay_destroy_timer_cb, delay_event);
|
||||
doris_common_timer_start(&delay_event->timer_event);
|
||||
}
|
||||
|
||||
/*fileϵ<65>к<EFBFBD><D0BA><EFBFBD><EFBFBD><EFBFBD>д<EFBFBD><D0B4><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>*/
|
||||
void doris_config_file_version_start(struct doris_instance *instance, cJSON *meta, void *userdata)
|
||||
{
|
||||
struct confile_save *save=(struct confile_save *)userdata;
|
||||
|
||||
if(save->type == CFG_UPDATE_TYPE_FULL)
|
||||
{
|
||||
snprintf(save->inc_index_path, 512, "%s/inc/index/full_config_index.%010lu", g_doris_server_info.store_path_root, save->version);
|
||||
snprintf(save->tmp_index_path, 512, "%s/inc/full_config_index.%010lu.ing", g_doris_server_info.store_path_root, save->version);
|
||||
snprintf(save->full_index_path, 512, "%s/full/index/full_config_index.%010lu", g_doris_server_info.store_path_root, save->version);
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf(save->inc_index_path, 512, "%s/inc/index/inc_config_index.%010lu", g_doris_server_info.store_path_root, save->version);
|
||||
snprintf(save->tmp_index_path, 512, "%s/inc/full_config_index.%010lu.ing", g_doris_server_info.store_path_root, save->version);
|
||||
}
|
||||
save->fp_idx_file = fopen(save->tmp_index_path, "w+");
|
||||
}
|
||||
|
||||
void doris_config_file_version_finish(struct doris_instance *instance, void *userdata)
|
||||
{
|
||||
struct confile_save *save=(struct confile_save *)userdata;
|
||||
|
||||
fclose(save->fp_idx_file);
|
||||
if(rename(save->tmp_index_path, save->inc_index_path))
|
||||
{
|
||||
assert(0);
|
||||
MESA_RUNTIME_LOGV3(g_doris_server_info.log_runtime, RLOG_LV_FATAL, "rename %s to %s failed: %s", save->tmp_index_path, save->inc_index_path, strerror(errno));
|
||||
}
|
||||
if(save->type == CFG_UPDATE_TYPE_FULL)
|
||||
{
|
||||
if(link(save->inc_index_path, save->full_index_path) && errno!=EEXIST) //<2F><><EFBFBD><EFBFBD>Ӳ<EFBFBD><D3B2><EFBFBD><EFBFBD>
|
||||
{
|
||||
assert(0);
|
||||
MESA_RUNTIME_LOGV3(g_doris_server_info.log_runtime, RLOG_LV_FATAL, "rename %s to %s failed: %s", save->tmp_index_path, save->inc_index_path, strerror(errno));
|
||||
}
|
||||
}
|
||||
MESA_RUNTIME_LOGV3(g_doris_server_info.log_runtime, RLOG_LV_INFO, "Version %lu write finished, index file: %s", save->version, save->inc_index_path);
|
||||
}
|
||||
|
||||
void doris_config_file_version_error(struct doris_instance *instance, void *userdata)
|
||||
{
|
||||
struct confile_save *save=(struct confile_save *)userdata;
|
||||
|
||||
if(save->fp_idx_file != NULL)
|
||||
{
|
||||
fclose(save->fp_idx_file);
|
||||
remove(save->tmp_index_path);
|
||||
}
|
||||
if(save->fp_cfg_file != NULL)
|
||||
{
|
||||
fclose(save->fp_cfg_file);
|
||||
remove(save->cfg_file_path);
|
||||
}
|
||||
MESA_RUNTIME_LOGV3(g_doris_server_info.log_runtime, RLOG_LV_FATAL, "Version %llu error, rolling back...", save->version);
|
||||
}
|
||||
|
||||
void doris_config_file_cfgfile_start(struct doris_instance *instance, const char *tablename, size_t size, u_int32_t cfgnum, void *userdata)
|
||||
{
|
||||
struct confile_save *save=(struct confile_save *)userdata;
|
||||
struct tm *localtm, savetime;
|
||||
time_t now;
|
||||
const char *type;
|
||||
char dir[256];
|
||||
|
||||
type = (save->type == CFG_UPDATE_TYPE_FULL)?"full":"inc";
|
||||
now = time(NULL);
|
||||
localtm = localtime_r(&now, &savetime);
|
||||
snprintf(dir, 256, "%s/%s/%04d-%02d-%02d", g_doris_server_info.store_path_root, type, localtm->tm_year+1900, localtm->tm_mon+1, localtm->tm_mday);
|
||||
if(access(dir, F_OK))
|
||||
{
|
||||
doris_mkdir_according_path(dir);
|
||||
}
|
||||
snprintf(save->cfg_file_path, 256, "%s/%s.%010lu", dir, tablename, save->version);
|
||||
fprintf(save->fp_idx_file, "%s\t%u\t%s\n", tablename, cfgnum, save->cfg_file_path);
|
||||
|
||||
save->fp_cfg_file = fopen(save->cfg_file_path, "w+");
|
||||
MESA_RUNTIME_LOGV3(g_doris_server_info.log_runtime, RLOG_LV_INFO, "File %s start writing...", save->cfg_file_path);
|
||||
}
|
||||
|
||||
|
||||
void doris_config_file_cfgfile_update(struct doris_instance *instance, const char *data, size_t len, void *userdata)
|
||||
{
|
||||
struct confile_save *save=(struct confile_save *)userdata;
|
||||
size_t writen_len;
|
||||
|
||||
writen_len = fwrite(data, 1, len, save->fp_cfg_file);
|
||||
assert(writen_len==len);
|
||||
}
|
||||
|
||||
void doris_config_file_cfgfile_finish(struct doris_instance *instance, void *userdata)
|
||||
{
|
||||
struct confile_save *save=(struct confile_save *)userdata;
|
||||
fclose(save->fp_cfg_file);
|
||||
|
||||
MESA_RUNTIME_LOGV3(g_doris_server_info.log_runtime, RLOG_LV_INFO, "File %s write finished", save->cfg_file_path);
|
||||
}
|
||||
|
||||
/*memϵ<6D>к<EFBFBD><D0BA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD>*/
|
||||
void doris_config_mem_version_start(struct doris_instance *instance, cJSON *meta, void *userdata)
|
||||
{
|
||||
struct confile_save *save=(struct confile_save *)userdata;
|
||||
|
||||
save->cur_vernode = (struct version_list_node *)calloc(1, sizeof(struct version_list_node));
|
||||
TAILQ_INIT(&save->cur_vernode->table_head);
|
||||
save->cur_vernode->metajson = cJSON_CreateObject();
|
||||
save->cur_vernode->arrayjson= cJSON_CreateArray();
|
||||
|
||||
save->cur_vernode->version = save->version;
|
||||
cJSON_AddNumberToObject(save->cur_vernode->metajson, "version", save->cur_vernode->version);
|
||||
|
||||
save->cur_vernode->cfg_type = save->type;
|
||||
cJSON_AddNumberToObject(save->cur_vernode->metajson, "type", save->cur_vernode->cfg_type);
|
||||
}
|
||||
|
||||
void doris_config_mem_version_finish(struct doris_instance *instance, void *userdata)
|
||||
{
|
||||
struct confile_save *save=(struct confile_save *)userdata;
|
||||
struct version_list_handle *cur_version;
|
||||
struct version_list_handle *tmplist;
|
||||
|
||||
cJSON_AddItemToObject(save->cur_vernode->metajson, "configs", save->cur_vernode->arrayjson);
|
||||
save->cur_vernode->arrayjson = NULL;
|
||||
save->cur_vernode->metacont = cJSON_PrintUnformatted(save->cur_vernode->metajson);
|
||||
save->cur_vernode->metalen = strlen(save->cur_vernode->metacont);
|
||||
cJSON_Delete(save->cur_vernode->metajson);
|
||||
save->cur_vernode->metajson = NULL;
|
||||
|
||||
MESA_RUNTIME_LOGV3(g_doris_server_info.log_runtime, RLOG_LV_FATAL, "Version %lu mem finished, info: %s", save->version, save->cur_vernode->metacont);
|
||||
|
||||
if(save->cur_vernode->cfg_type==CFG_UPDATE_TYPE_FULL && g_doris_server_info.cfgver_head->latest_version!=0)
|
||||
{
|
||||
cur_version = config_version_handle_new();
|
||||
cur_version->latest_version = save->cur_vernode->version;
|
||||
TAILQ_INSERT_TAIL(&cur_version->version_head, save->cur_vernode, version_node);
|
||||
|
||||
pthread_rwlock_wrlock(&g_doris_server_info.rwlock);
|
||||
tmplist = g_doris_server_info.cfgver_head;
|
||||
g_doris_server_info.cfgver_head = cur_version;
|
||||
pthread_rwlock_unlock(&g_doris_server_info.rwlock);
|
||||
cfgver_handle_delay_destroy(save, save->evbase, tmplist);
|
||||
}
|
||||
else
|
||||
{
|
||||
TAILQ_INSERT_TAIL(&g_doris_server_info.cfgver_head->version_head, save->cur_vernode, version_node);
|
||||
g_doris_server_info.cfgver_head->latest_version = save->cur_vernode->version;
|
||||
}
|
||||
save->cur_vernode = NULL;
|
||||
}
|
||||
|
||||
void doris_config_mem_version_error(struct doris_instance *instance, void *userdata)
|
||||
{
|
||||
struct confile_save *save=(struct confile_save *)userdata;
|
||||
|
||||
config_frag_node_cleanup(save, save->cur_frag);
|
||||
config_table_node_cleanup(save, save->cur_table);
|
||||
config_version_node_cleanup(save, save->cur_vernode);
|
||||
save->cur_frag = NULL;
|
||||
save->cur_table = NULL;
|
||||
save->cur_vernode = NULL;
|
||||
}
|
||||
|
||||
void doris_config_mem_cfgfile_start(struct doris_instance *instance, const char *tablename, size_t size, u_int32_t cfgnum, void *userdata)
|
||||
{
|
||||
struct confile_save *save=(struct confile_save *)userdata;
|
||||
cJSON *table_meta;
|
||||
|
||||
table_meta = cJSON_CreateObject();
|
||||
cJSON_AddStringToObject(table_meta, "tablename", tablename);
|
||||
cJSON_AddNumberToObject(table_meta, "cfg_num", cfgnum);
|
||||
cJSON_AddNumberToObject(table_meta, "size", size);
|
||||
cJSON_AddItemToArray(save->cur_vernode->arrayjson, table_meta);
|
||||
|
||||
save->cur_table = (struct table_list_node *)calloc(1, sizeof(struct table_list_node));
|
||||
snprintf(save->cur_table->tablename, 64, "%s", tablename);
|
||||
save->cur_table->filesize = size;
|
||||
TAILQ_INIT(&save->cur_table->frag_head);
|
||||
|
||||
MESA_RUNTIME_LOGV3(g_doris_server_info.log_runtime, RLOG_LV_INFO, "table %s.%010llu start loading to memory...", tablename, save->version);
|
||||
}
|
||||
|
||||
void doris_config_mem_cfgfile_update(struct doris_instance *instance, const char *data, size_t len, void *userdata)
|
||||
{
|
||||
struct confile_save *save=(struct confile_save *)userdata;
|
||||
size_t cache_len, offset=0;
|
||||
|
||||
save->statistic.statistic.status[DRS_FSSTAT_MEMORY_USED] += len;
|
||||
while(len > 0)
|
||||
{
|
||||
if(save->cur_frag == NULL)
|
||||
{
|
||||
save->cur_frag = (struct cont_frag_node *)calloc(1, sizeof(struct cont_frag_node));
|
||||
save->cur_frag->start = save->cur_table->cur_totallen;
|
||||
save->cur_frag->totalsize = save->cur_table->filesize - save->cur_table->cur_totallen;
|
||||
if(save->cur_frag->totalsize > g_doris_server_info.cache_frag_size)
|
||||
{
|
||||
save->cur_frag->totalsize = g_doris_server_info.cache_frag_size;
|
||||
}
|
||||
save->cur_frag->end = save->cur_frag->start + save->cur_frag->totalsize - 1;
|
||||
save->cur_frag->content = (char *)malloc(save->cur_frag->totalsize);
|
||||
}
|
||||
|
||||
if(save->cur_frag->totalsize > save->cur_frag->cur_fraglen + len)
|
||||
{
|
||||
memcpy(save->cur_frag->content+save->cur_frag->cur_fraglen, data+offset, len);
|
||||
save->cur_frag->cur_fraglen += len;
|
||||
save->cur_table->cur_totallen += len;
|
||||
offset += len;
|
||||
len = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
cache_len = save->cur_frag->totalsize - save->cur_frag->cur_fraglen;
|
||||
memcpy(save->cur_frag->content+save->cur_frag->cur_fraglen, data+offset, cache_len);
|
||||
save->cur_frag->cur_fraglen += cache_len;
|
||||
save->cur_table->cur_totallen += cache_len;
|
||||
offset += cache_len;
|
||||
len -= cache_len;
|
||||
TAILQ_INSERT_TAIL(&save->cur_table->frag_head, save->cur_frag, frag_node);
|
||||
assert(save->cur_frag->cur_fraglen == save->cur_frag->end - save->cur_frag->start + 1);
|
||||
save->cur_frag = NULL;
|
||||
}
|
||||
}
|
||||
assert(save->cur_table->cur_totallen <= save->cur_table->filesize);
|
||||
}
|
||||
|
||||
void doris_config_mem_cfgfile_finish(struct doris_instance *instance, void *userdata)
|
||||
{
|
||||
struct confile_save *save=(struct confile_save *)userdata;
|
||||
|
||||
if(save->cur_frag != NULL)
|
||||
{
|
||||
TAILQ_INSERT_TAIL(&save->cur_table->frag_head, save->cur_frag, frag_node);
|
||||
assert(save->cur_frag->cur_fraglen == save->cur_frag->end - save->cur_frag->start + 1);
|
||||
save->cur_frag = NULL;
|
||||
}
|
||||
assert(save->cur_table->cur_totallen == save->cur_table->filesize);
|
||||
TAILQ_INSERT_TAIL(&save->cur_vernode->table_head, save->cur_table, table_node);
|
||||
MESA_RUNTIME_LOGV3(g_doris_server_info.log_runtime, RLOG_LV_INFO, "table %s.%010llu load to memory finished", save->cur_table->tablename, save->version);
|
||||
save->cur_table = NULL;
|
||||
}
|
||||
|
||||
/*commonϵ<6E>к<EFBFBD><D0BA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>*/
|
||||
void doris_config_common_version_start(struct confile_save *save, cJSON *meta)
|
||||
{
|
||||
cJSON *sub;
|
||||
|
||||
sub = cJSON_GetObjectItem(meta, "version");
|
||||
save->version = sub->valuedouble;
|
||||
sub = cJSON_GetObjectItem(meta, "type");
|
||||
save->type = sub->valueint;
|
||||
assert(save->type==CFG_UPDATE_TYPE_FULL || save->type==CFG_UPDATE_TYPE_INC);
|
||||
save->version_cfgnum = 0;
|
||||
MESA_RUNTIME_LOGV3(g_doris_server_info.log_runtime, RLOG_LV_INFO, "Version %lu start updating...", save->version);
|
||||
}
|
||||
|
||||
void doris_config_common_version_finish(struct confile_save *save)
|
||||
{
|
||||
if(save->type == CFG_UPDATE_TYPE_FULL)
|
||||
{
|
||||
save->statistic.statistic.status[DRS_FSSTAT_CUR_FULL_VERSION] = save->version;
|
||||
save->statistic.statistic.status[DRS_FSSTAT_CONFIG_TOTAL_NUM] = save->version_cfgnum;
|
||||
save->statistic.statistic.field[DRS_FSSTAT_RECV_FULL_VER] += 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
save->statistic.statistic.status[DRS_FSSTAT_CUR_INC_VERSION] = save->version;
|
||||
save->statistic.statistic.status[DRS_FSSTAT_CONFIG_TOTAL_NUM] += save->version_cfgnum;
|
||||
save->statistic.statistic.field[DRS_FSSTAT_RECV_INC_VER] += 1;
|
||||
}
|
||||
MESA_Monitor_operation(g_doris_server_info.monitor, g_doris_server_info.mm_latest_ver, MONITOR_VALUE_SET, save->version);
|
||||
MESA_Monitor_operation(g_doris_server_info.monitor, g_doris_server_info.mm_total_cfgnum, MONITOR_VALUE_SET,
|
||||
save->statistic.statistic.status[DRS_FSSTAT_CONFIG_TOTAL_NUM]);
|
||||
MESA_RUNTIME_LOGV3(g_doris_server_info.log_runtime, RLOG_LV_INFO, "Version %lu update finished", save->version);
|
||||
|
||||
}
|
||||
|
||||
void doris_config_common_version_error(struct confile_save *save)
|
||||
{
|
||||
save->statistic.statistic.field[DRS_FSSTAT_RECV_ERR_VER] += 1;
|
||||
}
|
||||
|
||||
void doris_config_common_cfgfile_start(struct confile_save *save, u_int32_t cfgnum)
|
||||
{
|
||||
save->version_cfgnum += cfgnum;
|
||||
save->statistic.statistic.field[DRS_FSSTAT_RECV_START_FILES] += 1;
|
||||
}
|
||||
|
||||
void doris_config_common_cfgfile_finish(struct confile_save *save)
|
||||
{
|
||||
save->statistic.statistic.field[DRS_FSSTAT_RECV_CMPLT_FILES] += 1;
|
||||
}
|
||||
|
||||
/*localmemϵ<6D>к<EFBFBD><D0BA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD>ӱ<EFBFBD><D3B1>ػ<EFBFBD><D8BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ļص<C4BB>*/
|
||||
void doris_config_localmem_version_start(struct doris_instance *instance, cJSON *meta, void *userdata)
|
||||
{
|
||||
doris_config_common_version_start((struct confile_save *)userdata, meta);
|
||||
if(g_doris_server_info.server_role_sw)
|
||||
{
|
||||
doris_config_mem_version_start(instance, meta, userdata);
|
||||
}
|
||||
}
|
||||
|
||||
void doris_config_localmem_version_finish(struct doris_instance *instance, void *userdata)
|
||||
{
|
||||
if(g_doris_server_info.server_role_sw)
|
||||
{
|
||||
doris_config_mem_version_finish(instance, userdata);
|
||||
}
|
||||
doris_config_common_version_finish((struct confile_save *)userdata);
|
||||
}
|
||||
|
||||
void doris_config_localmem_version_error(struct doris_instance *instance, void *userdata)
|
||||
{
|
||||
doris_config_common_version_error((struct confile_save *)userdata);
|
||||
if(g_doris_server_info.server_role_sw)
|
||||
{
|
||||
doris_config_mem_version_error(instance, userdata);
|
||||
}
|
||||
}
|
||||
|
||||
void doris_config_localmem_cfgfile_start(struct doris_instance *instance, const char *tablename, size_t size, u_int32_t cfgnum, void *userdata)
|
||||
{
|
||||
doris_config_common_cfgfile_start((struct confile_save *)userdata, cfgnum);
|
||||
if(g_doris_server_info.server_role_sw)
|
||||
{
|
||||
doris_config_mem_cfgfile_start(instance, tablename, size, cfgnum, userdata);
|
||||
}
|
||||
}
|
||||
|
||||
void doris_config_localmem_cfgfile_update(struct doris_instance *instance, const char *data, size_t len, void *userdata)
|
||||
{
|
||||
if(g_doris_server_info.server_role_sw)
|
||||
{
|
||||
doris_config_mem_cfgfile_update(instance, data, len, userdata);
|
||||
}
|
||||
}
|
||||
|
||||
void doris_config_localmem_cfgfile_finish(struct doris_instance *instance, void *userdata)
|
||||
{
|
||||
doris_config_common_cfgfile_finish((struct confile_save *)userdata);
|
||||
if(g_doris_server_info.server_role_sw)
|
||||
{
|
||||
doris_config_mem_cfgfile_finish(instance, userdata);
|
||||
}
|
||||
}
|
||||
|
||||
/*<2A>ޱ<EFBFBD><DEB1><EFBFBD>ϵ<EFBFBD>к<EFBFBD><D0BA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD>ص<EFBFBD>*/
|
||||
void doris_config_version_start(struct doris_instance *instance, cJSON *meta, void *userdata)
|
||||
{
|
||||
doris_config_common_version_start((struct confile_save *)userdata, meta);
|
||||
if(g_doris_server_info.write_file_sw)
|
||||
{
|
||||
doris_config_file_version_start(instance, meta, userdata);
|
||||
}
|
||||
if(g_doris_server_info.server_role_sw)
|
||||
{
|
||||
doris_config_mem_version_start(instance, meta, userdata);
|
||||
}
|
||||
}
|
||||
|
||||
void doris_config_version_finish(struct doris_instance *instance, void *userdata)
|
||||
{
|
||||
if(g_doris_server_info.write_file_sw)
|
||||
{
|
||||
doris_config_file_version_finish(instance, userdata);
|
||||
}
|
||||
if(g_doris_server_info.server_role_sw)
|
||||
{
|
||||
doris_config_mem_version_finish(instance, userdata);
|
||||
}
|
||||
doris_config_common_version_finish((struct confile_save *)userdata);
|
||||
}
|
||||
|
||||
void doris_config_version_error(struct doris_instance *instance, void *userdata)
|
||||
{
|
||||
doris_config_common_version_error((struct confile_save *)userdata);
|
||||
if(g_doris_server_info.write_file_sw)
|
||||
{
|
||||
doris_config_file_version_error(instance, userdata);
|
||||
}
|
||||
if(g_doris_server_info.server_role_sw)
|
||||
{
|
||||
doris_config_mem_version_error(instance, userdata);
|
||||
}
|
||||
}
|
||||
|
||||
void doris_config_cfgfile_start(struct doris_instance *instance, const char *tablename, size_t size, u_int32_t cfgnum, void *userdata)
|
||||
{
|
||||
doris_config_common_cfgfile_start((struct confile_save *)userdata, cfgnum);
|
||||
if(g_doris_server_info.write_file_sw)
|
||||
{
|
||||
doris_config_file_cfgfile_start(instance, tablename, size, cfgnum, userdata);
|
||||
}
|
||||
if(g_doris_server_info.server_role_sw)
|
||||
{
|
||||
doris_config_mem_cfgfile_start(instance, tablename, size, cfgnum, userdata);
|
||||
}
|
||||
}
|
||||
|
||||
void doris_config_cfgfile_update(struct doris_instance *instance, const char *data, size_t len, void *userdata)
|
||||
{
|
||||
if(g_doris_server_info.write_file_sw)
|
||||
{
|
||||
doris_config_file_cfgfile_update(instance, data, len, userdata);
|
||||
}
|
||||
if(g_doris_server_info.server_role_sw)
|
||||
{
|
||||
doris_config_mem_cfgfile_update(instance, data, len, userdata);
|
||||
}
|
||||
}
|
||||
|
||||
void doris_config_cfgfile_finish(struct doris_instance *instance, void *userdata)
|
||||
{
|
||||
doris_config_common_cfgfile_finish((struct confile_save *)userdata);
|
||||
if(g_doris_server_info.write_file_sw)
|
||||
{
|
||||
doris_config_file_cfgfile_finish(instance, userdata);
|
||||
}
|
||||
if(g_doris_server_info.server_role_sw)
|
||||
{
|
||||
doris_config_mem_cfgfile_finish(instance, userdata);
|
||||
}
|
||||
}
|
||||
|
||||
void* thread_doris_client_recv_cfg(void *arg)
|
||||
{
|
||||
struct event_base *manage_evbase=(struct event_base *)arg, *client_evbase;
|
||||
struct doris_parameter *param;
|
||||
struct doris_instance *instance;
|
||||
struct doris_callbacks doris_cbs;
|
||||
struct doris_arguments doris_args={0, 0, 0};
|
||||
struct doris_idxfile_scanner *scanner;
|
||||
enum DORIS_UPDATE_TYPE update_type;
|
||||
struct confile_save save;
|
||||
char stored_path[512];
|
||||
struct timeval tv;
|
||||
|
||||
prctl(PR_SET_NAME, "client_recv");
|
||||
|
||||
client_evbase = event_base_new();
|
||||
|
||||
memset(&save, 0, sizeof(struct confile_save));
|
||||
save.source_from = RECV_WAY_IDX_FILE;
|
||||
save.evbase = client_evbase;
|
||||
|
||||
scanner = doris_index_file_scanner(0);
|
||||
|
||||
/*Retaive latest config to memory from Stored configs*/
|
||||
doris_cbs.version_start = doris_config_localmem_version_start;
|
||||
doris_cbs.version_finish = doris_config_localmem_version_finish;
|
||||
doris_cbs.version_error = doris_config_localmem_version_error;
|
||||
doris_cbs.cfgfile_start = doris_config_localmem_cfgfile_start;
|
||||
doris_cbs.cfgfile_update = doris_config_localmem_cfgfile_update;
|
||||
doris_cbs.cfgfile_finish = doris_config_localmem_cfgfile_finish;
|
||||
doris_cbs.userdata = &save;
|
||||
|
||||
snprintf(stored_path, 512, "%s/full/index", g_doris_server_info.store_path_root);
|
||||
update_type = doris_index_file_traverse(scanner, stored_path, &doris_cbs, NULL, g_doris_server_info.log_runtime);
|
||||
assert(update_type!=CFG_UPDATE_TYPE_ERR);
|
||||
snprintf(stored_path, 512, "%s/inc/index", g_doris_server_info.store_path_root);
|
||||
do {
|
||||
update_type = doris_index_file_traverse(scanner, stored_path, &doris_cbs, NULL, g_doris_server_info.log_runtime);
|
||||
assert(update_type!=CFG_UPDATE_TYPE_ERR);
|
||||
}while(update_type != CFG_UPDATE_TYPE_NONE);
|
||||
|
||||
|
||||
/*Check new configs*/
|
||||
doris_cbs.version_start = doris_config_version_start;
|
||||
doris_cbs.version_finish = doris_config_version_finish;
|
||||
doris_cbs.version_error = doris_config_version_error;
|
||||
doris_cbs.cfgfile_start = doris_config_cfgfile_start;
|
||||
doris_cbs.cfgfile_update = doris_config_cfgfile_update;
|
||||
doris_cbs.cfgfile_finish = doris_config_cfgfile_finish;
|
||||
|
||||
save.source_from = RECV_WAY_DRS_CLIENT;
|
||||
doris_args.current_version = scanner->cur_version;
|
||||
param = doris_parameter_new(NIRVANA_CONFIG_FILE, manage_evbase, &doris_cbs, &doris_args, g_doris_server_info.log_runtime);
|
||||
if(param == NULL)
|
||||
{
|
||||
assert(0);return NULL;
|
||||
}
|
||||
|
||||
instance = doris_instance_new(param, client_evbase, g_doris_server_info.log_runtime);
|
||||
if(instance == NULL)
|
||||
{
|
||||
assert(0);return NULL;
|
||||
}
|
||||
|
||||
evtimer_assign(&save.statistic.timer_statistic, client_evbase, doris_worker_statistic_timer_cb, &save.statistic);
|
||||
tv.tv_sec = g_doris_server_info.fsstat_period;
|
||||
tv.tv_usec = 0;
|
||||
evtimer_add(&save.statistic.timer_statistic, &tv);
|
||||
|
||||
event_base_dispatch(client_evbase);
|
||||
printf("Libevent dispath error, should not run here.\n");
|
||||
MESA_RUNTIME_LOGV3(g_doris_server_info.log_runtime, RLOG_LV_FATAL, "Libevent dispath error, should not run here.");
|
||||
assert(0);return NULL;
|
||||
}
|
||||
|
||||
static void doris_scanner_timer_cb(int fd, short kind, void *userp)
|
||||
{
|
||||
struct scanner_timer_priv *timer_priv=(struct scanner_timer_priv *)userp;
|
||||
enum DORIS_UPDATE_TYPE update_type;
|
||||
struct timeval tv;
|
||||
|
||||
do {
|
||||
update_type = doris_index_file_traverse(timer_priv->scanner, g_doris_server_info.recv_path_inc,
|
||||
&timer_priv->doris_cbs, NULL, g_doris_server_info.log_runtime);
|
||||
}while(update_type != CFG_UPDATE_TYPE_NONE);
|
||||
|
||||
tv.tv_sec = g_doris_server_info.scan_idx_interval;
|
||||
tv.tv_usec = 0;
|
||||
evtimer_add(&timer_priv->timer_scanner, &tv);
|
||||
}
|
||||
|
||||
void* thread_index_file_recv_cfg(void *arg)
|
||||
{
|
||||
struct event_base *client_evbase;
|
||||
struct confile_save save;
|
||||
struct timeval tv;
|
||||
struct scanner_timer_priv timer_priv;
|
||||
enum DORIS_UPDATE_TYPE update_type;
|
||||
char stored_path[256];
|
||||
|
||||
prctl(PR_SET_NAME, "index_file");
|
||||
|
||||
memset(&save, 0, sizeof(struct confile_save));
|
||||
memset(&timer_priv, 0, sizeof(struct scanner_timer_priv));
|
||||
|
||||
client_evbase = event_base_new();
|
||||
|
||||
save.source_from = RECV_WAY_IDX_FILE;
|
||||
save.evbase = client_evbase;
|
||||
|
||||
timer_priv.scanner = doris_index_file_scanner(0);
|
||||
|
||||
/*Retaive latest config to memory from Stored configs*/
|
||||
timer_priv.doris_cbs.version_start = doris_config_localmem_version_start;
|
||||
timer_priv.doris_cbs.version_finish = doris_config_localmem_version_finish;
|
||||
timer_priv.doris_cbs.version_error = doris_config_localmem_version_error;
|
||||
timer_priv.doris_cbs.cfgfile_start = doris_config_localmem_cfgfile_start;
|
||||
timer_priv.doris_cbs.cfgfile_update = doris_config_localmem_cfgfile_update;
|
||||
timer_priv.doris_cbs.cfgfile_finish = doris_config_localmem_cfgfile_finish;
|
||||
timer_priv.doris_cbs.userdata = &save;
|
||||
|
||||
snprintf(stored_path, 512, "%s/full/index", g_doris_server_info.store_path_root);
|
||||
update_type = doris_index_file_traverse(timer_priv.scanner, stored_path, &timer_priv.doris_cbs, NULL, g_doris_server_info.log_runtime);
|
||||
assert(update_type!=CFG_UPDATE_TYPE_ERR);
|
||||
snprintf(stored_path, 512, "%s/inc/index", g_doris_server_info.store_path_root);
|
||||
do{
|
||||
update_type = doris_index_file_traverse(timer_priv.scanner, stored_path, &timer_priv.doris_cbs, NULL, g_doris_server_info.log_runtime);
|
||||
assert(update_type!=CFG_UPDATE_TYPE_ERR);
|
||||
}while(update_type!=CFG_UPDATE_TYPE_NONE && update_type!=CFG_UPDATE_TYPE_ERR);
|
||||
|
||||
|
||||
/*Check new configs*/
|
||||
timer_priv.doris_cbs.version_start = doris_config_version_start;
|
||||
timer_priv.doris_cbs.version_finish = doris_config_version_finish;
|
||||
timer_priv.doris_cbs.version_error = doris_config_version_error;
|
||||
timer_priv.doris_cbs.cfgfile_start = doris_config_cfgfile_start;
|
||||
timer_priv.doris_cbs.cfgfile_update = doris_config_cfgfile_update;
|
||||
timer_priv.doris_cbs.cfgfile_finish = doris_config_cfgfile_finish;
|
||||
|
||||
update_type = doris_index_file_traverse(timer_priv.scanner, g_doris_server_info.recv_path_full,
|
||||
&timer_priv.doris_cbs, NULL, g_doris_server_info.log_runtime);
|
||||
assert(update_type!=CFG_UPDATE_TYPE_ERR);
|
||||
if(update_type!=CFG_UPDATE_TYPE_NONE && update_type!=CFG_UPDATE_TYPE_ERR)
|
||||
{
|
||||
tv.tv_sec = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
tv.tv_sec = g_doris_server_info.scan_idx_interval;
|
||||
}
|
||||
tv.tv_usec = 0;
|
||||
evtimer_assign(&timer_priv.timer_scanner, client_evbase, doris_scanner_timer_cb, &timer_priv);
|
||||
evtimer_add(&timer_priv.timer_scanner, &tv);
|
||||
|
||||
evtimer_assign(&save.statistic.timer_statistic, client_evbase, doris_worker_statistic_timer_cb, &save.statistic);
|
||||
tv.tv_sec = g_doris_server_info.fsstat_period;
|
||||
tv.tv_usec = 0;
|
||||
evtimer_add(&save.statistic.timer_statistic, &tv);
|
||||
|
||||
event_base_dispatch(client_evbase);
|
||||
printf("Libevent dispath error, should not run here.\n");
|
||||
MESA_RUNTIME_LOGV3(g_doris_server_info.log_runtime, RLOG_LV_FATAL, "Libevent dispath error, should not run here.");
|
||||
return NULL;
|
||||
}
|
||||
129
server/doris_server_receive.h
Normal file
129
server/doris_server_receive.h
Normal file
@@ -0,0 +1,129 @@
|
||||
#ifndef __DORIS_SERVER_RECEIVE_H__
|
||||
#define __DORIS_SERVER_RECEIVE_H__
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/queue.h>
|
||||
#include <event.h>
|
||||
|
||||
#include <cjson/cJSON.h>
|
||||
|
||||
|
||||
enum DORIS_SERVER_FS_FILED
|
||||
{
|
||||
DRS_FSSTAT_RECV_FULL_VER=0,
|
||||
DRS_FSSTAT_RECV_INC_VER,
|
||||
DRS_FSSTAT_RECV_ERR_VER,
|
||||
DRS_FSSTAT_RECV_START_FILES,
|
||||
DRS_FSSTAT_RECV_CMPLT_FILES,
|
||||
|
||||
DRS_FSSTAT_CLIENT_INVALID_REQ,
|
||||
DRS_FSSTAT_CLIENT_META_REQ,
|
||||
DRS_FSSTAT_SEND_META_RES,
|
||||
DRS_FSSTAT_SEND_META_NONEW,
|
||||
DRS_FSSTAT_CLIENT_FILE_REQ,
|
||||
DRS_FSSTAT_SEND_FILE_RES,
|
||||
DRS_FSSTAT_SEND_FILE_BYTES,
|
||||
DRS_FSSTAT_SEND_FILE_RES_404,
|
||||
|
||||
DRS_FSSTAT_FIELD_NUM,
|
||||
};
|
||||
|
||||
enum DORIS_SERVER_FS_STATUS
|
||||
{
|
||||
DRS_FSSTAT_MEMORY_USED=0,
|
||||
DRS_FSSTAT_CUR_FULL_VERSION,
|
||||
DRS_FSSTAT_CUR_INC_VERSION,
|
||||
DRS_FSSTAT_CONFIG_TOTAL_NUM,
|
||||
|
||||
DRS_FSSTAT_STATUS_NUM,
|
||||
};
|
||||
|
||||
struct cont_frag_node
|
||||
{
|
||||
size_t start;
|
||||
size_t end;
|
||||
size_t totalsize;
|
||||
size_t cur_fraglen;
|
||||
char *content;
|
||||
|
||||
TAILQ_ENTRY(cont_frag_node) frag_node;
|
||||
};
|
||||
|
||||
struct table_list_node
|
||||
{
|
||||
char tablename[64];
|
||||
size_t filesize;
|
||||
size_t cur_totallen;
|
||||
|
||||
TAILQ_HEAD(__table_cont_node, cont_frag_node) frag_head;
|
||||
TAILQ_ENTRY(table_list_node) table_node;
|
||||
};
|
||||
|
||||
struct version_list_node
|
||||
{
|
||||
int64_t version;
|
||||
char *metacont;
|
||||
int32_t metalen;
|
||||
int32_t cfg_type; //1-full, 2-inc
|
||||
cJSON *metajson, *arrayjson;
|
||||
|
||||
TAILQ_HEAD(__table_list_node, table_list_node) table_head;
|
||||
TAILQ_ENTRY(version_list_node) version_node;
|
||||
};
|
||||
|
||||
struct version_list_handle
|
||||
{
|
||||
TAILQ_HEAD(__version_list_node, version_list_node) version_head;
|
||||
int64_t latest_version;
|
||||
int32_t references;
|
||||
};
|
||||
|
||||
struct version_list_handle *config_version_handle_new(void);
|
||||
|
||||
struct doris_srv_statistics
|
||||
{
|
||||
long long field[DRS_FSSTAT_FIELD_NUM];
|
||||
long long status[DRS_FSSTAT_STATUS_NUM];
|
||||
};
|
||||
|
||||
struct worker_statistic_info
|
||||
{
|
||||
struct event timer_statistic;
|
||||
struct doris_srv_statistics statistic, statistic_last;
|
||||
};
|
||||
|
||||
struct confile_save
|
||||
{
|
||||
struct event_base *evbase;
|
||||
int64_t version;
|
||||
int32_t source_from;
|
||||
int32_t type;
|
||||
int64_t version_cfgnum;
|
||||
char inc_index_path[256]; //incĿ¼<C4BF>µ<EFBFBD><C2B5><EFBFBD><EFBFBD><EFBFBD>ȫ<EFBFBD><C8AB>
|
||||
char tmp_index_path[256]; //incĿ¼<C4BF>µ<EFBFBD><C2B5><EFBFBD><EFBFBD><EFBFBD>ȫ<EFBFBD><C8AB>
|
||||
char full_index_path[256]; //fullĿ¼<C4BF>µ<EFBFBD>ȫ<EFBFBD><C8AB>
|
||||
char cfg_file_path[256];
|
||||
FILE *fp_cfg_file;
|
||||
FILE *fp_idx_file;
|
||||
|
||||
struct worker_statistic_info statistic;
|
||||
|
||||
struct version_list_node *cur_vernode;
|
||||
struct table_list_node *cur_table;
|
||||
struct cont_frag_node *cur_frag;
|
||||
};
|
||||
|
||||
struct common_timer_event
|
||||
{
|
||||
struct event timer_event;
|
||||
struct confile_save *save;
|
||||
void *data;
|
||||
};
|
||||
|
||||
void doris_worker_statistic_timer_cb(int fd, short kind, void *userp);
|
||||
|
||||
void* thread_doris_client_recv_cfg(void *arg);
|
||||
void* thread_index_file_recv_cfg(void *arg);
|
||||
|
||||
#endif
|
||||
|
||||
318
server/doris_server_scandir.cpp
Normal file
318
server/doris_server_scandir.cpp
Normal file
@@ -0,0 +1,318 @@
|
||||
#include <dirent.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <MESA/MESA_handle_logger.h>
|
||||
|
||||
#include "doris_server_scandir.h"
|
||||
|
||||
#ifndef __FILENAME__
|
||||
#define __FILENAME__ __FILE__
|
||||
#endif
|
||||
#define MESA_RUNTIME_LOGV4(handle, lv, fmt, args...) \
|
||||
MESA_handle_runtime_log((handle), (lv), "DorisServer", "%s:%d, " fmt, __FILENAME__, __LINE__, ##args)
|
||||
|
||||
//replacement of glibc scandir, to adapt dictator malloc wrap
|
||||
#define ENLARGE_STEP 1024
|
||||
int my_scandir(const char *dir, struct dirent ***namelist,
|
||||
int(*filter)(const struct dirent *),
|
||||
int(*compar)(const void *, const void *))
|
||||
{
|
||||
DIR * od;
|
||||
int n = 0;
|
||||
int DIR_ENT_SIZE=ENLARGE_STEP;
|
||||
struct dirent ** list = NULL;
|
||||
struct dirent * p;
|
||||
struct dirent entry,*result;
|
||||
|
||||
if((dir == NULL) || (namelist == NULL) || (od = opendir(dir))==NULL)
|
||||
return -1;
|
||||
|
||||
list = (struct dirent **)malloc(DIR_ENT_SIZE*sizeof(struct dirent *));
|
||||
while(0==readdir_r(od,&entry,&result))
|
||||
{
|
||||
if(result==NULL)
|
||||
{
|
||||
break;
|
||||
}
|
||||
if( filter && !filter(&entry))
|
||||
continue;
|
||||
|
||||
p = (struct dirent *)malloc(sizeof(struct dirent));
|
||||
memcpy((void *)p,(void *)(&entry),sizeof(struct dirent));
|
||||
list[n] = p;
|
||||
|
||||
n++;
|
||||
if(n >= DIR_ENT_SIZE)
|
||||
{
|
||||
DIR_ENT_SIZE+=ENLARGE_STEP;
|
||||
list=(struct dirent **)realloc((void*)list,DIR_ENT_SIZE*sizeof(struct dirent *));
|
||||
}
|
||||
}
|
||||
closedir(od);
|
||||
*namelist = list;
|
||||
|
||||
if(compar)
|
||||
{
|
||||
qsort((void *)*namelist,n,sizeof(struct dirent *),compar);
|
||||
}
|
||||
return n;
|
||||
|
||||
}
|
||||
|
||||
int filter_fn(const struct dirent * ent)
|
||||
{
|
||||
// files in xfs are not DT_REG.
|
||||
// if(ent->d_type != DT_REG)
|
||||
// return 0;
|
||||
|
||||
return (strncmp(ent->d_name,"full_config_index",strlen("full_config_index")) == 0||
|
||||
strncmp(ent->d_name,"inc_config_index",strlen("inc_config_index")) == 0);
|
||||
}
|
||||
|
||||
enum DORIS_UPDATE_TYPE get_new_idx_path(long long current_version, const char *file_dir, void *logger, struct index_path_array **idx_path, int *idx_num)
|
||||
{
|
||||
struct dirent **namelist;
|
||||
char update_str[32]={0};
|
||||
long long latest_ful_version=0,latest_inc_version=0,config_seq=0;
|
||||
int n=0,i=0, full_file_idx=0,inc_idx_num=0;
|
||||
enum DORIS_UPDATE_TYPE update_type=CFG_UPDATE_TYPE_NONE;
|
||||
struct index_path_array *tmpidx_path_array;
|
||||
struct index_version_array *tmpidx_ver_array;
|
||||
|
||||
n = my_scandir(file_dir, &namelist, filter_fn, (int (*)(const void*, const void*))alphasort);
|
||||
if(n < 0)
|
||||
{
|
||||
MESA_RUNTIME_LOGV4(logger,RLOG_LV_FATAL, "scan dir error");
|
||||
return update_type;
|
||||
}
|
||||
|
||||
tmpidx_ver_array = (struct index_version_array*)calloc(sizeof(struct index_version_array), n);
|
||||
inc_idx_num=0;
|
||||
for(i=0;i<n;i++)
|
||||
{
|
||||
if((strcmp(namelist[i]->d_name, ".") == 0) || (strcmp(namelist[i]->d_name, "..") == 0))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if(strlen(namelist[i]->d_name) > 42)
|
||||
{
|
||||
MESA_RUNTIME_LOGV4(logger,RLOG_LV_FATAL, "config file %s filename too long,should like full_config_index.00000000000000000001", namelist[i]->d_name);
|
||||
continue;
|
||||
}
|
||||
if(sscanf(namelist[i]->d_name,"%[a-zA-Z]_config_index.%lld",update_str,&config_seq) != 2)
|
||||
{
|
||||
MESA_RUNTIME_LOGV4(logger,RLOG_LV_FATAL, "config file %s filename error,should like full_config_index.00000000000000000001", namelist[i]->d_name);
|
||||
continue;
|
||||
}
|
||||
if(strncasecmp(update_str,"full",strlen(update_str))==0)
|
||||
{
|
||||
if(config_seq>latest_ful_version)
|
||||
{
|
||||
latest_ful_version=config_seq;
|
||||
full_file_idx=i;
|
||||
}
|
||||
}
|
||||
else if(strncasecmp(update_str,"inc",strlen(update_str))==0)
|
||||
{
|
||||
if(config_seq > current_version)
|
||||
{
|
||||
tmpidx_ver_array[inc_idx_num].file_inx = i;
|
||||
tmpidx_ver_array[inc_idx_num].version = config_seq;
|
||||
inc_idx_num++;
|
||||
if(config_seq > latest_inc_version)
|
||||
{
|
||||
latest_inc_version = config_seq;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MESA_RUNTIME_LOGV4(logger,RLOG_LV_FATAL, "config file %s,not full or inc config", namelist[i]->d_name);
|
||||
}
|
||||
}
|
||||
|
||||
//full update
|
||||
if(latest_ful_version > current_version)
|
||||
{
|
||||
tmpidx_path_array = (struct index_path_array *)malloc(sizeof(struct index_path_array));
|
||||
snprintf(tmpidx_path_array->path, MAX_CONFIG_FN_LEN, "%s/%s", file_dir, namelist[full_file_idx]->d_name);
|
||||
tmpidx_path_array->version = latest_ful_version;
|
||||
*idx_num = 1;
|
||||
update_type = CFG_UPDATE_TYPE_FULL;
|
||||
}
|
||||
//inc update,it's possible that do inc after full update in this function,but we'll process it at next loop.
|
||||
else if(latest_inc_version > current_version)
|
||||
{
|
||||
tmpidx_path_array = (struct index_path_array *)malloc(sizeof(struct index_path_array)*inc_idx_num);
|
||||
for(i=0;i<inc_idx_num;i++)
|
||||
{
|
||||
snprintf(tmpidx_path_array[i].path, MAX_CONFIG_FN_LEN, "%s/%s", file_dir, namelist[tmpidx_ver_array[i].file_inx]->d_name);
|
||||
tmpidx_path_array[i].version = tmpidx_ver_array[i].version;
|
||||
}
|
||||
*idx_num = inc_idx_num;
|
||||
update_type = CFG_UPDATE_TYPE_INC;
|
||||
}
|
||||
*idx_path = tmpidx_path_array;
|
||||
|
||||
free(tmpidx_ver_array);
|
||||
for(i=0;i<n;i++)
|
||||
{
|
||||
free(namelist[i]);
|
||||
}
|
||||
free(namelist);
|
||||
return update_type;
|
||||
}
|
||||
|
||||
int cm_read_cfg_index_file(const char* path, struct cfg_table_info* idx/*OUT*/, int size, void* logger)
|
||||
{
|
||||
FILE* fp=NULL;
|
||||
int ret=0,i=0;
|
||||
char line[MAX_CONFIG_LINE];
|
||||
struct stat file_info;
|
||||
|
||||
fp=fopen(path, "r");
|
||||
while(!feof(fp))
|
||||
{
|
||||
memset(line, 0, sizeof(line));
|
||||
fgets(line, sizeof(line), fp);
|
||||
ret=sscanf(line,"%s\t%d\t%s\t%s", idx[i].table_name, &(idx[i].cfg_num), idx[i].cfg_path, idx[i].encryp_algorithm);
|
||||
if((ret!=3 && ret!=4) || idx[i].cfg_num==0)//jump over empty line
|
||||
{
|
||||
continue;
|
||||
}
|
||||
ret=stat(idx[i].cfg_path, &file_info);
|
||||
if(ret!=0)
|
||||
{
|
||||
MESA_RUNTIME_LOGV4(logger,RLOG_LV_FATAL, "%s of %s not exisit", idx[i].cfg_path, path);
|
||||
fclose(fp);
|
||||
return -1;
|
||||
}
|
||||
idx[i].filesize = file_info.st_size;
|
||||
i++;
|
||||
if(i==size)
|
||||
{
|
||||
MESA_RUNTIME_LOGV4(logger,RLOG_LV_FATAL, "Too much lines in %s", path);
|
||||
break;
|
||||
}
|
||||
}
|
||||
fclose(fp);
|
||||
return i;
|
||||
}
|
||||
|
||||
bool doris_read_table_file(struct doris_idxfile_scanner *scanner, struct cfg_table_info *table,
|
||||
struct doris_callbacks *doris_cbs, const char* dec_key, void* logger)
|
||||
{
|
||||
FILE *fp;
|
||||
size_t readlen, remainlen, oncesize;
|
||||
|
||||
if((fp = fopen(table->cfg_path, "r")) == NULL)
|
||||
{
|
||||
MESA_RUNTIME_LOGV4(logger,RLOG_LV_FATAL, "fopen table file %s failed: %s", table->cfg_path, strerror(errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
doris_cbs->cfgfile_start(NULL, table->table_name, table->filesize, table->cfg_num, doris_cbs->userdata);
|
||||
remainlen = table->filesize;
|
||||
while(remainlen > 0)
|
||||
{
|
||||
oncesize = (remainlen >= ONCE_BUF_SIZE)?ONCE_BUF_SIZE:remainlen;
|
||||
readlen = fread(scanner->oncebuf, 1, oncesize, fp);
|
||||
assert(readlen == oncesize);
|
||||
remainlen -= readlen;
|
||||
doris_cbs->cfgfile_update(NULL, scanner->oncebuf, readlen, doris_cbs->userdata);
|
||||
}
|
||||
doris_cbs->cfgfile_finish(NULL, doris_cbs->userdata);
|
||||
fclose(fp);
|
||||
return true;
|
||||
}
|
||||
|
||||
cJSON *doris_index_version_start(int64_t version, struct cfg_table_info *table_array, int table_num,
|
||||
enum DORIS_UPDATE_TYPE update_type, struct doris_callbacks *doris_cbs)
|
||||
{
|
||||
cJSON *meta, *array, *tmp;
|
||||
|
||||
meta = cJSON_CreateObject();
|
||||
cJSON_AddNumberToObject(meta, "type", update_type);
|
||||
cJSON_AddNumberToObject(meta, "version", version);
|
||||
|
||||
array = cJSON_CreateArray();
|
||||
for(int i=0; i<table_num; i++)
|
||||
{
|
||||
tmp = cJSON_CreateObject();
|
||||
cJSON_AddStringToObject(tmp, "tablename", table_array[i].table_name);
|
||||
cJSON_AddNumberToObject(tmp, "size", table_array[i].filesize);
|
||||
cJSON_AddNumberToObject(tmp, "cfg_num", table_array[i].cfg_num);
|
||||
cJSON_AddItemToArray(array, tmp);
|
||||
}
|
||||
cJSON_AddItemToObject(meta, "configs", array);
|
||||
|
||||
doris_cbs->version_start(NULL, meta, doris_cbs->userdata);
|
||||
return meta;
|
||||
}
|
||||
|
||||
enum DORIS_UPDATE_TYPE doris_index_file_traverse(struct doris_idxfile_scanner *scanner, const char*idx_dir,
|
||||
struct doris_callbacks *doris_cbs, const char* dec_key, void* logger)
|
||||
{
|
||||
enum DORIS_UPDATE_TYPE update_type;
|
||||
struct index_path_array *idx_path_array=NULL;
|
||||
int idx_num=0,table_num=0,i=0,j=0;
|
||||
struct cfg_table_info table_array[CM_MAX_TABLE_NUM];
|
||||
bool update_rslt;
|
||||
|
||||
memset(table_array,0,sizeof(table_array));
|
||||
update_type=get_new_idx_path(scanner->cur_version, idx_dir,logger, &idx_path_array, &idx_num);
|
||||
if(update_type == CFG_UPDATE_TYPE_NONE)
|
||||
{
|
||||
MESA_RUNTIME_LOGV4(logger,RLOG_LV_DEBUG, "Scan over, no new configs found, waiting next.", idx_path_array[i].path);
|
||||
return update_type;
|
||||
}
|
||||
|
||||
update_rslt = true;
|
||||
for(i=0; i<idx_num; i++)
|
||||
{
|
||||
MESA_RUNTIME_LOGV4(logger, RLOG_LV_INFO, "load %s", idx_path_array[i].path);
|
||||
table_num=cm_read_cfg_index_file(idx_path_array[i].path, table_array, CM_MAX_TABLE_NUM, logger);
|
||||
if(table_num<0)
|
||||
{
|
||||
MESA_RUNTIME_LOGV4(logger,RLOG_LV_INFO, "load %s faild, abandon udpate.", idx_path_array[i].path);
|
||||
update_type = CFG_UPDATE_TYPE_ERR;
|
||||
break;
|
||||
}
|
||||
|
||||
cJSON *meta = doris_index_version_start(idx_path_array[i].version, table_array, table_num, update_type, doris_cbs);
|
||||
for(j=0; j<table_num && update_rslt; j++)
|
||||
{
|
||||
update_rslt = update_rslt && doris_read_table_file(scanner, table_array+j, doris_cbs, dec_key, logger);
|
||||
}
|
||||
if(update_rslt)
|
||||
{
|
||||
scanner->cur_version = idx_path_array[i].version;
|
||||
doris_cbs->version_finish(NULL, doris_cbs->userdata);
|
||||
}
|
||||
else
|
||||
{
|
||||
update_type = CFG_UPDATE_TYPE_ERR;
|
||||
doris_cbs->version_error(NULL, doris_cbs->userdata);
|
||||
cJSON_Delete(meta);
|
||||
break;
|
||||
}
|
||||
cJSON_Delete(meta);
|
||||
}
|
||||
free(idx_path_array);
|
||||
return update_type;
|
||||
}
|
||||
|
||||
struct doris_idxfile_scanner *doris_index_file_scanner(int64_t start_version)
|
||||
{
|
||||
struct doris_idxfile_scanner *scanner;
|
||||
|
||||
scanner = (struct doris_idxfile_scanner *)malloc(sizeof(struct doris_idxfile_scanner));
|
||||
scanner->cur_version = start_version;
|
||||
return scanner;
|
||||
}
|
||||
|
||||
52
server/doris_server_scandir.h
Normal file
52
server/doris_server_scandir.h
Normal file
@@ -0,0 +1,52 @@
|
||||
#ifndef __DORIS_SERVER_SCANDIR_H__
|
||||
#define __DORIS_SERVER_SCANDIR_H__
|
||||
|
||||
#include "doris_client.h"
|
||||
|
||||
#define CM_MAX_TABLE_NUM 256
|
||||
#define MAX_CONFIG_FN_LEN 256
|
||||
#define MAX_CONFIG_LINE (1024*16)
|
||||
|
||||
#define ONCE_BUF_SIZE 1048576
|
||||
|
||||
enum DORIS_UPDATE_TYPE
|
||||
{
|
||||
CFG_UPDATE_TYPE_NONE=0,
|
||||
CFG_UPDATE_TYPE_FULL=1,
|
||||
CFG_UPDATE_TYPE_INC=2,
|
||||
CFG_UPDATE_TYPE_ERR=-1,
|
||||
};
|
||||
|
||||
struct index_version_array
|
||||
{
|
||||
int32_t file_inx;
|
||||
int64_t version;
|
||||
};
|
||||
|
||||
struct index_path_array
|
||||
{
|
||||
char path[MAX_CONFIG_FN_LEN];
|
||||
int64_t version;
|
||||
};
|
||||
|
||||
struct cfg_table_info
|
||||
{
|
||||
char table_name[MAX_CONFIG_FN_LEN];
|
||||
char cfg_path[MAX_CONFIG_FN_LEN];
|
||||
int cfg_num;
|
||||
size_t filesize;
|
||||
char encryp_algorithm[MAX_CONFIG_FN_LEN];
|
||||
};
|
||||
|
||||
struct doris_idxfile_scanner
|
||||
{
|
||||
int64_t cur_version;
|
||||
char oncebuf[ONCE_BUF_SIZE];
|
||||
};
|
||||
|
||||
struct doris_idxfile_scanner *doris_index_file_scanner(int64_t start_version);
|
||||
enum DORIS_UPDATE_TYPE doris_index_file_traverse(struct doris_idxfile_scanner *scanner, const char*idx_dir,
|
||||
struct doris_callbacks *doris_cbs, const char* dec_key, void* logger);
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user