🦄 refactor(stellar api): split exdata and mq
This commit is contained in:
3
infra/mq/CMakeLists.txt
Normal file
3
infra/mq/CMakeLists.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
add_library(mq mq.c)
|
||||
|
||||
#add_subdirectory(test)
|
||||
212
infra/mq/mq.c
Normal file
212
infra/mq/mq.c
Normal file
@@ -0,0 +1,212 @@
|
||||
#include "mq_interna.h"
|
||||
|
||||
#include "stellar/utils.h"
|
||||
|
||||
#include "uthash/utlist.h"
|
||||
|
||||
/*******************************
|
||||
* STELLAR MQ *
|
||||
*******************************/
|
||||
static void stellar_mq_topic_schema_copy(void *_dst, const void *_src)
|
||||
{
|
||||
struct stellar_mq_topic_schema *dst = (struct stellar_mq_topic_schema *)_dst,
|
||||
*src = (struct stellar_mq_topic_schema *)_src;
|
||||
memcpy(_dst, _src, sizeof(struct stellar_mq_topic_schema));
|
||||
dst->topic_name = src->topic_name ? strdup(src->topic_name) : NULL;
|
||||
}
|
||||
|
||||
static void stellar_mq_topic_schema_dtor(void *_elt)
|
||||
{
|
||||
struct stellar_mq_topic_schema *elt = (struct stellar_mq_topic_schema *)_elt;
|
||||
if (elt->topic_name)
|
||||
FREE(elt->topic_name);
|
||||
// FREE(elt); // free the item
|
||||
}
|
||||
|
||||
UT_icd stellar_mq_topic_schema_icd = {sizeof(struct stellar_mq_topic_schema), NULL, stellar_mq_topic_schema_copy, stellar_mq_topic_schema_dtor};
|
||||
|
||||
int mq_schema_get_topic_id(struct mq_schema *s, const char *topic_name)
|
||||
{
|
||||
if(topic_name == NULL || s == NULL || s->topic_array == NULL )return -1;
|
||||
unsigned int len = utarray_len(s->topic_array);
|
||||
struct stellar_mq_topic_schema *t_schema;
|
||||
for(unsigned int i = 0; i < len; i++)
|
||||
{
|
||||
t_schema = (struct stellar_mq_topic_schema *)utarray_eltptr(s->topic_array, i);
|
||||
if(strcmp(t_schema->topic_name, topic_name) == 0)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int mq_schema_update_topic(struct mq_schema *s, int topic_id, on_msg_dispatch_cb_func *on_dispatch_cb, void *on_dispatch_arg, mq_msg_free_cb_func *msg_free_cb, void *msg_free_arg)
|
||||
{
|
||||
if(s == NULL || s->topic_array == NULL)return -1;
|
||||
unsigned int len = utarray_len(s->topic_array);
|
||||
if(len < (unsigned int)topic_id)return -1;
|
||||
struct stellar_mq_topic_schema *t_schema = (struct stellar_mq_topic_schema *)utarray_eltptr(s->topic_array, (unsigned int)topic_id);
|
||||
if(t_schema == NULL)return -1;
|
||||
t_schema->dispatch_cb=on_dispatch_cb;
|
||||
t_schema->dispatch_cb_arg=on_dispatch_arg;
|
||||
t_schema->free_cb=msg_free_cb;
|
||||
t_schema->free_cb_arg=msg_free_arg;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mq_schema_create_topic(struct mq_schema *s, const char *topic_name, on_msg_dispatch_cb_func *on_dispatch_cb, void *on_dispatch_arg, mq_msg_free_cb_func *msg_free_cb, void *msg_free_arg)
|
||||
{
|
||||
if(s==NULL)return -1;
|
||||
if(s->topic_array == NULL)
|
||||
{
|
||||
utarray_new(s->topic_array, &stellar_mq_topic_schema_icd);
|
||||
}
|
||||
unsigned int len = utarray_len(s->topic_array);
|
||||
if(mq_schema_get_topic_id(s, topic_name) >= 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
struct stellar_mq_topic_schema t_schema;
|
||||
memset(&t_schema, 0, sizeof(struct stellar_mq_topic_schema));
|
||||
t_schema.dispatch_cb=on_dispatch_cb;
|
||||
t_schema.free_cb=msg_free_cb;
|
||||
t_schema.topic_name=(char *)topic_name;
|
||||
t_schema.topic_id=len;//topid_id equals arrary index
|
||||
t_schema.dispatch_cb_arg=on_dispatch_arg;
|
||||
t_schema.free_cb_arg=msg_free_arg;
|
||||
t_schema.subscribers=NULL;
|
||||
t_schema.subscriber_cnt=0;
|
||||
utarray_push_back(s->topic_array, &t_schema);
|
||||
s->stellar_mq_topic_num+=1;
|
||||
return t_schema.topic_id;
|
||||
}
|
||||
|
||||
int mq_schema_destroy_topic(struct mq_schema *s, int topic_id)
|
||||
{
|
||||
if(s==NULL)return -1;
|
||||
if(s->topic_array==NULL)return -1;
|
||||
unsigned int len = utarray_len(s->topic_array);
|
||||
if (len <= (unsigned int)topic_id)
|
||||
return -1;
|
||||
struct stellar_mq_topic_schema *topic =
|
||||
(struct stellar_mq_topic_schema *)utarray_eltptr(s->topic_array, (unsigned int)topic_id);
|
||||
struct stellar_mq_subscriber *sub_elt, *sub_tmp;
|
||||
|
||||
if(topic == NULL)return -1;
|
||||
|
||||
if (topic->is_destroyed == 1)return 0;
|
||||
|
||||
DL_FOREACH_SAFE(topic->subscribers, sub_elt, sub_tmp)
|
||||
{
|
||||
DL_DELETE(topic->subscribers, sub_elt);
|
||||
FREE(sub_elt);
|
||||
}
|
||||
topic->is_destroyed = 1;
|
||||
s->stellar_mq_topic_num-=1;
|
||||
return 1; // success
|
||||
}
|
||||
|
||||
|
||||
static void stellar_mq_dispatch_one_message(struct mq_schema *s, struct stellar_message *mq_elt)
|
||||
{
|
||||
struct stellar_mq_subscriber *sub_elt, *sub_tmp;
|
||||
struct stellar_mq_topic_schema *topic = (struct stellar_mq_topic_schema *)utarray_eltptr(s->topic_array,
|
||||
(unsigned int)(mq_elt->header.topic_id));
|
||||
if (topic)
|
||||
{
|
||||
DL_FOREACH_SAFE(topic->subscribers, sub_elt, sub_tmp)
|
||||
{
|
||||
if (sub_elt->plugin_msg_cb)
|
||||
{
|
||||
if(topic->dispatch_cb)topic->dispatch_cb(mq_elt->header.topic_id,mq_elt->body, sub_elt->plugin_msg_cb, topic->dispatch_cb_arg, sub_elt->plugin_msg_cb_arg);
|
||||
else sub_elt->plugin_msg_cb(mq_elt->header.topic_id, mq_elt->body, sub_elt->plugin_msg_cb_arg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void mq_runtime_clean_dlq(struct mq_runtime *rt)
|
||||
{
|
||||
struct stellar_message *mq_elt, *tmp;
|
||||
struct stellar_mq_topic_schema *topic;
|
||||
DL_FOREACH_SAFE(rt->dealth_letter_queue, mq_elt, tmp)
|
||||
{
|
||||
topic = (struct stellar_mq_topic_schema *)utarray_eltptr(rt->schema->topic_array,
|
||||
(unsigned int)(mq_elt->header.topic_id));
|
||||
if (topic && topic->free_cb)
|
||||
{
|
||||
topic->free_cb(mq_elt->body, topic->free_cb_arg);
|
||||
}
|
||||
DL_DELETE(rt->dealth_letter_queue, mq_elt);
|
||||
FREE(mq_elt);
|
||||
}
|
||||
}
|
||||
|
||||
void stellar_mq_dispatch(struct mq_runtime *rt)
|
||||
{
|
||||
struct stellar_message *mq_elt=NULL, *mq_tmp=NULL;
|
||||
int cur_priority = STELLAR_MQ_PRIORITY_HIGH;
|
||||
while(cur_priority >= STELLAR_MQ_PRIORITY_LOW)
|
||||
{
|
||||
if(rt->priority_mq[cur_priority]==NULL)
|
||||
{
|
||||
cur_priority--;
|
||||
continue;
|
||||
}
|
||||
DL_FOREACH_SAFE(rt->priority_mq[cur_priority], mq_elt, mq_tmp)
|
||||
{
|
||||
stellar_mq_dispatch_one_message(rt->schema, mq_elt);
|
||||
DL_DELETE(rt->priority_mq[mq_elt->header.priority], mq_elt);
|
||||
DL_APPEND(rt->dealth_letter_queue, mq_elt); // move to dlq list
|
||||
|
||||
cur_priority=STELLAR_MQ_PRIORITY_HIGH;
|
||||
break;
|
||||
}
|
||||
}
|
||||
mq_runtime_clean_dlq(rt);
|
||||
return;
|
||||
}
|
||||
|
||||
//return 0 if success, otherwise return -1.
|
||||
int stellar_mq_subscribe(struct mq_schema *s, int topic_id, on_msg_cb_func *on_msg_cb, void *on_msg_cb_arg)
|
||||
{
|
||||
|
||||
if(s == NULL || s->topic_array == NULL)return -1;
|
||||
|
||||
unsigned int len = utarray_len(s->topic_array);
|
||||
if (len <= (unsigned int)topic_id)return -1;
|
||||
|
||||
struct stellar_mq_topic_schema *topic = (struct stellar_mq_topic_schema *)utarray_eltptr(s->topic_array, (unsigned int)topic_id);
|
||||
if(topic==NULL)return -1;
|
||||
|
||||
struct stellar_mq_subscriber *new_subscriber = CALLOC(struct stellar_mq_subscriber,1);
|
||||
new_subscriber->topic_subscriber_idx = topic->subscriber_cnt;
|
||||
new_subscriber->plugin_msg_cb = on_msg_cb;
|
||||
new_subscriber->plugin_msg_cb_arg = on_msg_cb_arg;
|
||||
DL_APPEND(topic->subscribers, new_subscriber);
|
||||
|
||||
topic->subscriber_cnt+=1;
|
||||
s->mq_topic_subscriber_num+=1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int stellar_mq_publish_message_with_priority(struct mq_runtime *rt, int topic_id, void *data, enum stellar_mq_priority priority)
|
||||
{
|
||||
if(rt==NULL || rt->schema == NULL || rt->schema->topic_array == NULL)return -1;
|
||||
|
||||
unsigned int len = utarray_len(rt->schema->topic_array);
|
||||
if (len <= (unsigned int)topic_id)return -1;
|
||||
struct stellar_message *msg= CALLOC(struct stellar_message,1);
|
||||
msg->rt=rt;
|
||||
msg->header.topic_id = topic_id;
|
||||
msg->header.priority = priority;
|
||||
msg->body = data;
|
||||
DL_APPEND(rt->priority_mq[priority], msg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int stellar_mq_publish_message(struct mq_runtime *rt, int topic_id, void *data)
|
||||
{
|
||||
return stellar_mq_publish_message_with_priority(rt, topic_id, data, STELLAR_MQ_PRIORITY_MEDIUM);
|
||||
}
|
||||
74
infra/mq/mq_interna.h
Normal file
74
infra/mq/mq_interna.h
Normal file
@@ -0,0 +1,74 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include "stellar/mq.h"
|
||||
|
||||
#include "uthash/utarray.h"
|
||||
|
||||
struct mq_schema
|
||||
{
|
||||
UT_array *topic_array;
|
||||
int stellar_mq_topic_num;
|
||||
int mq_topic_subscriber_num;
|
||||
};
|
||||
|
||||
enum stellar_mq_priority
|
||||
{
|
||||
STELLAR_MQ_PRIORITY_LOW = 0,
|
||||
STELLAR_MQ_PRIORITY_MEDIUM,
|
||||
STELLAR_MQ_PRIORITY_HIGH,
|
||||
STELLAR_MQ_PRIORITY_MAX
|
||||
};
|
||||
|
||||
struct stellar_message
|
||||
{
|
||||
struct mq_runtime *rt;
|
||||
struct
|
||||
{
|
||||
int topic_id;
|
||||
enum stellar_mq_priority priority;
|
||||
} header;
|
||||
void *body;
|
||||
struct stellar_message *next, *prev;
|
||||
} __attribute__((aligned(sizeof(void *))));
|
||||
|
||||
typedef struct stellar_mq_subscriber
|
||||
{
|
||||
int topic_subscriber_idx;
|
||||
int plugin_idx;
|
||||
on_msg_cb_func *plugin_msg_cb;
|
||||
void *plugin_msg_cb_arg;
|
||||
struct stellar_mq_subscriber *next, *prev;
|
||||
}stellar_mq_subscriber __attribute__((aligned(sizeof(void*))));
|
||||
|
||||
|
||||
struct stellar_mq_topic_schema
|
||||
{
|
||||
char *topic_name;
|
||||
int topic_id;
|
||||
int subscriber_cnt;
|
||||
int is_destroyed;
|
||||
on_msg_dispatch_cb_func *dispatch_cb;
|
||||
void *dispatch_cb_arg;
|
||||
mq_msg_free_cb_func *free_cb;
|
||||
void *free_cb_arg;
|
||||
struct stellar_mq_subscriber *subscribers;
|
||||
}__attribute__((aligned(sizeof(void*))));
|
||||
|
||||
|
||||
|
||||
struct mq_runtime
|
||||
{
|
||||
struct mq_schema *schema;
|
||||
struct stellar_message *priority_mq[STELLAR_MQ_PRIORITY_MAX];// message list
|
||||
struct stellar_message *dealth_letter_queue;// dlq list
|
||||
};
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user