MEDIUM: da: new optional data file download scheduler service.
New specialized service to daily handle the update of download file without interruption of service and to be preemptively started before HAProxy. It consists on a standalone utility which shared a memory block with the DeviceAtlas module which handles the JSON data file update on a daily basis. Signed-off-by: David Carlier <dcarlier@deviceatlas.com>
This commit is contained in:
parent
74904a4792
commit
e9cff619c1
48
addons/deviceatlas/Makefile
Normal file
48
addons/deviceatlas/Makefile
Normal file
@ -0,0 +1,48 @@
|
||||
# DEVICEATLAS_SRC : DeviceAtlas API source root path
|
||||
|
||||
|
||||
OS := $(shell uname -s)
|
||||
OBJS := dadwsch.o
|
||||
CFLAGS := -g -O2
|
||||
LDFLAGS :=
|
||||
|
||||
CURL_CONFIG := curl-config
|
||||
CURLDIR := $(shell $(CURL_CONFIG) --prefix 2>/dev/null || echo /usr/local)
|
||||
CURL_INC := $(CURLDIR)/include
|
||||
CURL_LIB := $(CURLDIR)/lib
|
||||
CURL_LDFLAGS := $(shell $(CURL_CONFIG) --libs 2>/dev/null || echo -L /usr/local/lib -lcurl)
|
||||
|
||||
PCRE2_CONFIG := pcre2-config
|
||||
PCRE2DIR := $(shell $(PCRE2_CONFIG) --prefix 2>/dev/null || echo /usr/local)
|
||||
PCRE2_INC := $(PCRE2DIR)/include
|
||||
PCRE2_LIB := $(PCRE2DIR)/lib
|
||||
PCRE2_LDFLAGS := $(shell $(PCRE2_CONFIG) --libs8 2>/dev/null || echo /usr/local)
|
||||
|
||||
ifeq ($(DEVICEATLAS_SRC),)
|
||||
dadwsch: dadwsch.c
|
||||
$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
|
||||
|
||||
LDFLAGS += -lda
|
||||
else
|
||||
DEVICEATLAS_INC = $(DEVICEATLAS_SRC)
|
||||
DEVICEATLAS_LIB = $(DEVICEATLAS_SRC)
|
||||
CFLAGS += -DDA_REGEX_HDR=\"dac_pcre2.c\" -DDA_REGEX_TAG=2
|
||||
CFLAGS += -DMOBI_CURL -DMOBI_CURLSSET -DMOBI_GZ -DMOBI_ZIP
|
||||
CFLAGS += -I$(DEVICEATLAS_INC) -I$(CURL_INC) -I$(PCRE2DIR)
|
||||
LDFLAGS += $(CURL_LDFLAGS) $(PCRE2_LDFLAGS) -lz -lzip -lpthread
|
||||
|
||||
dadwsch: dadwsch.c $(DEVICEATLAS_SRC)/dac.c $(DEVICEATLAS_SRC)/dasch.c $(DEVICEATLAS_SRC)/dadwarc.c $(DEVICEATLAS_SRC)/dadwcom.c $(DEVICEATLAS_SRC)/dadwcurl.c $(DEVICEATLAS_SRC)/json.c $(DEVICEATLAS_SRC)/Os/daunix.c
|
||||
$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
|
||||
endif
|
||||
|
||||
ifeq ($(OS), Linux)
|
||||
LDFLAGS += -lrt
|
||||
endif
|
||||
ifeq ($(OS), SunOS)
|
||||
LDFLAGS += -lrt
|
||||
endif
|
||||
|
||||
clean:
|
||||
rm -f *.o
|
||||
rm -f $(DEVICEATLAS_LIB)*.o
|
||||
rm -f dadwsch
|
195
addons/deviceatlas/dadwsch.c
Normal file
195
addons/deviceatlas/dadwsch.c
Normal file
@ -0,0 +1,195 @@
|
||||
#define _GNU_SOURCE
|
||||
#include <dac.h>
|
||||
#include <dadwcurl.h>
|
||||
#include <dadwarc.h>
|
||||
#include <getopt.h>
|
||||
#include <stdlib.h>
|
||||
#include <signal.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#define ATLASTOKSZ PATH_MAX
|
||||
#define ATLASMAPNM "/hapdeviceatlas"
|
||||
|
||||
const char *__pgname;
|
||||
|
||||
static struct {
|
||||
da_dwatlas_t o;
|
||||
int ofd;
|
||||
void* atlasmap;
|
||||
} global_deviceatlassch = {
|
||||
.ofd = -1,
|
||||
.atlasmap = NULL
|
||||
};
|
||||
|
||||
|
||||
void usage(void)
|
||||
{
|
||||
fprintf(stderr, "%s -u download URL [-d hour (in H:M:S format) current hour by default] [-p path for the downloaded file, /tmp by default]\n", __pgname);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
static size_t jsonread(void *ctx, size_t count, char *buf)
|
||||
{
|
||||
return fread(buf, 1, count, ctx);
|
||||
}
|
||||
|
||||
static da_status_t jsonseek(void *ctx, off_t pos)
|
||||
{
|
||||
return fseek(ctx, pos, SEEK_SET) != -1 ? DA_OK : DA_SYS;
|
||||
}
|
||||
|
||||
static void dadwlog(dw_config_t cfg, const char* msg)
|
||||
{
|
||||
time_t now = time(NULL);
|
||||
char buf[26] = {0};
|
||||
ctime_r(&now, buf);
|
||||
buf[24] = 0;
|
||||
fprintf(stderr, "%s: %s\n", buf, msg);
|
||||
}
|
||||
|
||||
static dw_status_t dadwnot(void *a, dw_config_t *cfg)
|
||||
{
|
||||
da_dwatlas_t *o = (da_dwatlas_t *)a;
|
||||
if (!o)
|
||||
return DW_ERR;
|
||||
char *e;
|
||||
char jsondbuf[26] = {0}, buf[26] = {0}, atlasp[ATLASTOKSZ] = {0};
|
||||
time_t now = time(NULL);
|
||||
time_t jsond;
|
||||
int fd = -1;
|
||||
(void)a;
|
||||
jsond = da_getdatacreation(&o->atlas);
|
||||
dwgetfinalp(o->dcfg.info, atlasp, sizeof(atlasp));
|
||||
ctime_r(&jsond, jsondbuf);
|
||||
ctime_r(&now, buf);
|
||||
jsondbuf[24] = 0;
|
||||
buf[24] = 0;
|
||||
|
||||
printf("%s: data file generated on `%s`\n", buf, jsondbuf);
|
||||
int val = 1;
|
||||
unsigned char *ptr = (unsigned char *)global_deviceatlassch.atlasmap;
|
||||
memset(ptr, 0, sizeof(atlasp));
|
||||
strcpy(ptr, atlasp);
|
||||
return DW_OK;
|
||||
}
|
||||
|
||||
static da_status_t dadwinit(void)
|
||||
{
|
||||
if ((global_deviceatlassch.ofd = shm_open(ATLASMAPNM, O_RDWR | O_CREAT, 0660)) == -1) {
|
||||
fprintf(stderr, "%s\n", strerror(errno));
|
||||
return DA_SYS;
|
||||
}
|
||||
|
||||
if (ftruncate(global_deviceatlassch.ofd, ATLASTOKSZ) == -1) {
|
||||
close(global_deviceatlassch.ofd);
|
||||
return DA_SYS;
|
||||
}
|
||||
lseek(global_deviceatlassch.ofd, 0, SEEK_SET);
|
||||
global_deviceatlassch.atlasmap = mmap(0, ATLASTOKSZ, PROT_READ | PROT_WRITE, MAP_SHARED, global_deviceatlassch.ofd, 0);
|
||||
if (global_deviceatlassch.atlasmap == MAP_FAILED) {
|
||||
fprintf(stderr, "%s\n", strerror(errno));
|
||||
return DA_SYS;
|
||||
} else {
|
||||
memset(global_deviceatlassch.atlasmap, 0, ATLASTOKSZ);
|
||||
return DA_OK;
|
||||
}
|
||||
}
|
||||
|
||||
static void dadwexit(int sig __attribute__((unused)), siginfo_t *s __attribute__((unused)), void *ctx __attribute__((unused)))
|
||||
{
|
||||
ssize_t w;
|
||||
|
||||
fprintf(stderr, "%s: exit\n", __pgname);
|
||||
dw_daatlas_close(&global_deviceatlassch.o);
|
||||
da_fini();
|
||||
munmap(global_deviceatlassch.atlasmap, ATLASTOKSZ);
|
||||
close(global_deviceatlassch.ofd);
|
||||
shm_unlink(ATLASMAPNM);
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char *opts = "u:p:d:h";
|
||||
bool dset = false;
|
||||
size_t i;
|
||||
int ch;
|
||||
|
||||
da_property_decl_t extraprops[1] = {
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
__pgname = argv[0];
|
||||
|
||||
dw_df_dainit_fn = curldwinit;
|
||||
dw_df_dacleanup_fn = curldwcleanup;
|
||||
|
||||
da_init();
|
||||
memset(&global_deviceatlassch.o.dcfg, 0, sizeof(global_deviceatlassch.o.dcfg));
|
||||
while ((ch = getopt(argc, argv, opts)) != -1) {
|
||||
switch (ch) {
|
||||
case 'u':
|
||||
global_deviceatlassch.o.dcfg.info.url = strdup(optarg);
|
||||
break;
|
||||
case 'p':
|
||||
global_deviceatlassch.o.dcfg.info.path = strdup(optarg);
|
||||
break;
|
||||
case 'd':
|
||||
if (strptime(optarg, "%H:%M:%S", &global_deviceatlassch.o.dcfg.info.rtm) != NULL)
|
||||
dset = true;
|
||||
else
|
||||
usage();
|
||||
break;
|
||||
case 'h':
|
||||
default:
|
||||
usage();
|
||||
}
|
||||
}
|
||||
|
||||
if (!dset) {
|
||||
time_t now = time(NULL);
|
||||
struct tm *cnow = gmtime(&now);
|
||||
memcpy(&global_deviceatlassch.o.dcfg.info.rtm, cnow, offsetof(struct tm, tm_mday));
|
||||
}
|
||||
|
||||
if (!global_deviceatlassch.o.dcfg.info.url)
|
||||
usage();
|
||||
|
||||
struct sigaction sa;
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
sa.sa_flags = SA_SIGINFO | SA_RESTART;
|
||||
sa.sa_sigaction = dadwexit;
|
||||
|
||||
global_deviceatlassch.o.dcfg.info.datatm = 1;
|
||||
global_deviceatlassch.o.dcfg.info.chksum = 1;
|
||||
global_deviceatlassch.o.dcfg.info.reload = 1;
|
||||
global_deviceatlassch.o.dcfg.info.tobin = 1;
|
||||
global_deviceatlassch.o.dcfg.ep = extraprops;
|
||||
global_deviceatlassch.o.dcfg.dwproc = curldwproc;
|
||||
global_deviceatlassch.o.dcfg.dwextract = dadwextract;
|
||||
global_deviceatlassch.o.dcfg.lptr = (void *)stderr;
|
||||
global_deviceatlassch.o.dcfg.dwlog = &dadwlog;
|
||||
global_deviceatlassch.o.dcfg.dwnotify_n = &dadwnot;
|
||||
global_deviceatlassch.o.rfn = jsonread;
|
||||
global_deviceatlassch.o.posfn = jsonseek;
|
||||
|
||||
if (dadwinit() != DA_OK) {
|
||||
fprintf(stderr, "%s init failed\n", __pgname);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (da_atlas_open_schedule(&global_deviceatlassch.o) != DA_OK) {
|
||||
fprintf(stderr, "%s scheduling failed\n", __pgname);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
sigaction(SIGINT, &sa, NULL);
|
||||
sigaction(SIGQUIT, &sa, NULL);
|
||||
sigaction(SIGTERM, &sa, NULL);
|
||||
|
||||
while (true) sleep(1);
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user