2016-09-23 17:10:15 -07:00
|
|
|
#ifndef REDIS_H
|
|
|
|
#define REDIS_H
|
|
|
|
|
2016-09-13 18:54:26 -07:00
|
|
|
#include "db.h"
|
|
|
|
#include "object_table.h"
|
2016-11-10 18:13:26 -08:00
|
|
|
#include "task_table.h"
|
2016-09-13 18:54:26 -07:00
|
|
|
|
|
|
|
#include "hiredis/hiredis.h"
|
|
|
|
#include "hiredis/async.h"
|
2016-09-20 17:02:56 -07:00
|
|
|
#include "uthash.h"
|
2016-09-29 21:12:06 -07:00
|
|
|
#include "utarray.h"
|
2016-09-20 17:02:56 -07:00
|
|
|
|
2016-12-09 17:21:49 -08:00
|
|
|
/* Allow up to 5 seconds for connecting to Redis. */
|
|
|
|
#define REDIS_DB_CONNECT_RETRIES 50
|
|
|
|
#define REDIS_DB_CONNECT_WAIT_MS 100
|
|
|
|
|
2016-11-19 12:19:49 -08:00
|
|
|
#define LOG_REDIS_ERROR(context, M, ...) \
|
|
|
|
LOG_ERROR("Redis error %d %s; %s", context->err, context->errstr, M)
|
|
|
|
|
|
|
|
#define LOG_REDIS_DEBUG(context, M, ...) \
|
|
|
|
LOG_DEBUG("Redis error %d %s; %s", context->err, context->errstr, M)
|
|
|
|
|
2016-09-20 17:02:56 -07:00
|
|
|
typedef struct {
|
2016-11-18 19:57:51 -08:00
|
|
|
/** Unique ID for this db client. */
|
2017-02-26 00:32:43 -08:00
|
|
|
DBClientID db_client_id;
|
2016-11-18 19:57:51 -08:00
|
|
|
/** IP address and port of this db client. */
|
2016-09-23 22:53:58 -07:00
|
|
|
char *addr;
|
2016-10-29 15:22:33 -07:00
|
|
|
/** Handle for the uthash table. */
|
2016-09-20 17:02:56 -07:00
|
|
|
UT_hash_handle hh;
|
2017-02-26 00:32:43 -08:00
|
|
|
} DBClientCacheEntry;
|
2016-09-13 18:54:26 -07:00
|
|
|
|
2017-02-26 00:32:43 -08:00
|
|
|
struct DBHandle {
|
2016-10-29 15:22:33 -07:00
|
|
|
/** String that identifies this client type. */
|
2016-09-13 18:54:26 -07:00
|
|
|
char *client_type;
|
2016-11-18 19:57:51 -08:00
|
|
|
/** Unique ID for this client. */
|
2017-02-26 00:32:43 -08:00
|
|
|
DBClientID client;
|
2016-12-09 00:51:44 -08:00
|
|
|
/** Redis context for all non-subscribe connections. */
|
2016-09-13 18:54:26 -07:00
|
|
|
redisAsyncContext *context;
|
2016-11-18 19:57:51 -08:00
|
|
|
/** Redis context for "subscribe" communication. Yes, we need a separate one
|
|
|
|
* for that, see https://github.com/redis/hiredis/issues/55. */
|
2016-09-29 21:12:06 -07:00
|
|
|
redisAsyncContext *sub_context;
|
2016-10-29 15:22:33 -07:00
|
|
|
/** The event loop this global state store connection is part of. */
|
2016-09-13 18:54:26 -07:00
|
|
|
event_loop *loop;
|
2016-10-29 15:22:33 -07:00
|
|
|
/** Index of the database connection in the event loop */
|
2016-09-20 22:40:35 -07:00
|
|
|
int64_t db_index;
|
2016-11-18 19:57:51 -08:00
|
|
|
/** Cache for the IP addresses of db clients. This is a hash table mapping
|
|
|
|
* client IDs to addresses. */
|
2017-02-26 00:32:43 -08:00
|
|
|
DBClientCacheEntry *db_client_cache;
|
2016-11-18 19:57:51 -08:00
|
|
|
/** Redis context for synchronous connections. This should only be used very
|
|
|
|
* rarely, it is not asynchronous. */
|
2016-09-20 17:02:56 -07:00
|
|
|
redisContext *sync_context;
|
2016-09-13 18:54:26 -07:00
|
|
|
};
|
|
|
|
|
2016-10-29 15:22:33 -07:00
|
|
|
void redis_object_table_get_entry(redisAsyncContext *c,
|
|
|
|
void *r,
|
|
|
|
void *privdata);
|
2016-09-13 18:54:26 -07:00
|
|
|
|
|
|
|
void object_table_lookup_callback(redisAsyncContext *c,
|
|
|
|
void *r,
|
|
|
|
void *privdata);
|
2016-09-20 22:40:35 -07:00
|
|
|
|
2016-10-29 15:22:33 -07:00
|
|
|
/*
|
|
|
|
* ==== Redis object table functions ====
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Lookup object table entry in redis.
|
|
|
|
*
|
|
|
|
* @param callback_data Data structure containing redis connection and timeout
|
|
|
|
* information.
|
|
|
|
* @return Void.
|
|
|
|
*/
|
2017-02-26 00:32:43 -08:00
|
|
|
void redis_object_table_lookup(TableCallbackData *callback_data);
|
2016-10-29 15:22:33 -07:00
|
|
|
|
|
|
|
/**
|
2016-11-10 18:13:26 -08:00
|
|
|
* Add a location entry to the object table in redis.
|
2016-10-29 15:22:33 -07:00
|
|
|
*
|
|
|
|
* @param callback_data Data structure containing redis connection and timeout
|
|
|
|
* information.
|
|
|
|
* @return Void.
|
|
|
|
*/
|
2017-02-26 00:32:43 -08:00
|
|
|
void redis_object_table_add(TableCallbackData *callback_data);
|
2016-10-29 15:22:33 -07:00
|
|
|
|
2016-12-19 23:18:57 -08:00
|
|
|
/**
|
|
|
|
* Remove a location entry from the object table in redis.
|
|
|
|
*
|
|
|
|
* @param callback_data Data structure containing redis connection and timeout
|
|
|
|
* information.
|
|
|
|
* @return Void.
|
|
|
|
*/
|
2017-02-26 00:32:43 -08:00
|
|
|
void redis_object_table_remove(TableCallbackData *callback_data);
|
2016-12-19 23:18:57 -08:00
|
|
|
|
2016-10-29 15:22:33 -07:00
|
|
|
/**
|
2016-12-18 18:19:02 -08:00
|
|
|
* Create a client-specific channel for receiving notifications from the object
|
|
|
|
* table.
|
2016-10-29 15:22:33 -07:00
|
|
|
*
|
|
|
|
* @param callback_data Data structure containing redis connection and timeout
|
|
|
|
* information.
|
|
|
|
* @return Void.
|
|
|
|
*/
|
2016-12-18 18:19:02 -08:00
|
|
|
void redis_object_table_subscribe_to_notifications(
|
2017-02-26 00:32:43 -08:00
|
|
|
TableCallbackData *callback_data);
|
2016-12-18 18:19:02 -08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Request notifications about when certain objects become available.
|
|
|
|
*
|
|
|
|
* @param callback_data Data structure containing redis connection and timeout
|
|
|
|
* information.
|
|
|
|
* @return Void.
|
|
|
|
*/
|
2017-02-26 00:32:43 -08:00
|
|
|
void redis_object_table_request_notifications(TableCallbackData *callback_data);
|
2016-10-29 15:22:33 -07:00
|
|
|
|
2016-11-10 18:13:26 -08:00
|
|
|
/**
|
|
|
|
* Add a new object to the object table in redis.
|
|
|
|
*
|
|
|
|
* @param callback_data Data structure containing redis connection and timeout
|
|
|
|
* information.
|
|
|
|
* @return Void.
|
|
|
|
*/
|
2017-02-26 00:32:43 -08:00
|
|
|
void redis_result_table_add(TableCallbackData *callback_data);
|
2016-11-10 18:13:26 -08:00
|
|
|
|
|
|
|
/**
|
2017-02-01 19:18:46 -08:00
|
|
|
* Lookup the task that created the object in redis. The result is the task ID.
|
2016-11-10 18:13:26 -08:00
|
|
|
*
|
|
|
|
* @param callback_data Data structure containing redis connection and timeout
|
|
|
|
* information.
|
|
|
|
* @return Void.
|
|
|
|
*/
|
2017-02-26 00:32:43 -08:00
|
|
|
void redis_result_table_lookup(TableCallbackData *callback_data);
|
2016-11-10 18:13:26 -08:00
|
|
|
|
2016-12-18 18:19:02 -08:00
|
|
|
/**
|
|
|
|
* Callback invoked when the reply from the object table lookup command is
|
|
|
|
* received.
|
|
|
|
*
|
|
|
|
* @param c Redis context.
|
|
|
|
* @param r Reply.
|
|
|
|
* @param privdata Data associated to the callback.
|
|
|
|
* @return Void.
|
|
|
|
*/
|
|
|
|
void redis_object_table_lookup_callback(redisAsyncContext *c,
|
|
|
|
void *r,
|
|
|
|
void *privdata);
|
|
|
|
|
2016-10-29 15:22:33 -07:00
|
|
|
/*
|
|
|
|
* ==== Redis task table function =====
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
2016-11-10 18:13:26 -08:00
|
|
|
* Get a task table entry, including the task spec and the task's scheduling
|
|
|
|
* information.
|
2016-10-29 15:22:33 -07:00
|
|
|
*
|
|
|
|
* @param callback_data Data structure containing redis connection and timeout
|
|
|
|
* information.
|
|
|
|
* @return Void.
|
|
|
|
*/
|
2017-02-26 00:32:43 -08:00
|
|
|
void redis_task_table_get_task(TableCallbackData *callback_data);
|
2016-10-29 15:22:33 -07:00
|
|
|
|
|
|
|
/**
|
2016-11-10 18:13:26 -08:00
|
|
|
* Add a task table entry with a new task spec and the task's scheduling
|
|
|
|
* information.
|
|
|
|
*
|
|
|
|
* @param callback_data Data structure containing redis connection and timeout
|
|
|
|
* information.
|
|
|
|
* @return Void.
|
|
|
|
*/
|
2017-02-26 00:32:43 -08:00
|
|
|
void redis_task_table_add_task(TableCallbackData *callback_data);
|
2016-11-10 18:13:26 -08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Update a task table entry with the task's scheduling information.
|
|
|
|
*
|
|
|
|
* @param callback_data Data structure containing redis connection and timeout
|
|
|
|
* information.
|
|
|
|
* @return Void.
|
|
|
|
*/
|
2017-02-26 00:32:43 -08:00
|
|
|
void redis_task_table_update(TableCallbackData *callback_data);
|
2016-11-10 18:13:26 -08:00
|
|
|
|
2017-02-01 19:18:46 -08:00
|
|
|
/**
|
|
|
|
* Update a task table entry with the task's scheduling information, if the
|
|
|
|
* task's current scheduling information matches the test value.
|
|
|
|
*
|
|
|
|
* @param callback_data Data structure containing redis connection and timeout
|
|
|
|
* information.
|
|
|
|
* @return Void.
|
|
|
|
*/
|
2017-02-26 00:32:43 -08:00
|
|
|
void redis_task_table_test_and_update(TableCallbackData *callback_data);
|
2017-02-01 19:18:46 -08:00
|
|
|
|
2016-11-10 18:13:26 -08:00
|
|
|
/**
|
|
|
|
* Callback invoked when the reply from the task push command is received.
|
2016-10-29 15:22:33 -07:00
|
|
|
*
|
|
|
|
* @param c Redis context.
|
|
|
|
* @param r Reply (not used).
|
|
|
|
* @param privdata Data associated to the callback.
|
|
|
|
* @return Void.
|
|
|
|
*/
|
2016-11-10 18:13:26 -08:00
|
|
|
void redis_task_table_publish_push_callback(redisAsyncContext *c,
|
|
|
|
void *r,
|
|
|
|
void *privdata);
|
2016-10-29 15:22:33 -07:00
|
|
|
|
|
|
|
/**
|
2016-11-10 18:13:26 -08:00
|
|
|
* Callback invoked when the reply from the task publish command is received.
|
2016-10-29 15:22:33 -07:00
|
|
|
*
|
|
|
|
* @param c Redis context.
|
|
|
|
* @param r Reply (not used).
|
|
|
|
* @param privdata Data associated to the callback.
|
|
|
|
* @return Void.
|
|
|
|
*/
|
2016-11-10 18:13:26 -08:00
|
|
|
void redis_task_table_publish_publish_callback(redisAsyncContext *c,
|
|
|
|
void *r,
|
|
|
|
void *privdata);
|
2016-10-29 15:22:33 -07:00
|
|
|
|
|
|
|
/**
|
2016-11-10 18:13:26 -08:00
|
|
|
* Subscribe to updates of the task table.
|
2016-10-29 15:22:33 -07:00
|
|
|
*
|
|
|
|
* @param callback_data Data structure containing redis connection and timeout
|
|
|
|
* information.
|
|
|
|
* @return Void.
|
|
|
|
*/
|
2017-02-26 00:32:43 -08:00
|
|
|
void redis_task_table_subscribe(TableCallbackData *callback_data);
|
2016-10-29 15:22:33 -07:00
|
|
|
|
2017-03-02 19:51:20 -08:00
|
|
|
/**
|
|
|
|
* Remove a client from the db clients table.
|
|
|
|
*
|
|
|
|
* @param callback_data Data structure containing redis connection and timeout
|
|
|
|
* information.
|
|
|
|
* @return Void.
|
|
|
|
*/
|
|
|
|
void redis_db_client_table_remove(TableCallbackData *callback_data);
|
|
|
|
|
2016-11-18 19:57:51 -08:00
|
|
|
/**
|
|
|
|
* Subscribe to updates from the db client table.
|
|
|
|
*
|
|
|
|
* @param callback_data Data structure containing redis connection and timeout
|
|
|
|
* information.
|
|
|
|
* @return Void.
|
|
|
|
*/
|
2017-02-26 00:32:43 -08:00
|
|
|
void redis_db_client_table_subscribe(TableCallbackData *callback_data);
|
2016-11-18 19:57:51 -08:00
|
|
|
|
2016-12-24 20:02:25 -08:00
|
|
|
/**
|
|
|
|
* Subscribe to updates from the local scheduler table.
|
|
|
|
*
|
|
|
|
* @param callback_data Data structure containing redis connection and timeout
|
|
|
|
* information.
|
|
|
|
* @return Void.
|
|
|
|
*/
|
2017-02-26 00:32:43 -08:00
|
|
|
void redis_local_scheduler_table_subscribe(TableCallbackData *callback_data);
|
2016-12-24 20:02:25 -08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Publish an update to the local scheduler table.
|
|
|
|
*
|
|
|
|
* @param callback_data Data structure containing redis connection and timeout
|
|
|
|
* information.
|
|
|
|
* @return Void.
|
|
|
|
*/
|
2017-02-26 00:32:43 -08:00
|
|
|
void redis_local_scheduler_table_send_info(TableCallbackData *callback_data);
|
2016-12-24 20:02:25 -08:00
|
|
|
|
2017-02-15 00:10:05 -08:00
|
|
|
/**
|
|
|
|
* Subscribe to updates about newly created actors.
|
|
|
|
*
|
|
|
|
* @param callback_data Data structure containing redis connection and timeout
|
|
|
|
* information.
|
|
|
|
* @return Void.
|
|
|
|
*/
|
2017-02-26 00:32:43 -08:00
|
|
|
void redis_actor_notification_table_subscribe(TableCallbackData *callback_data);
|
2017-02-15 00:10:05 -08:00
|
|
|
|
2017-02-26 00:32:43 -08:00
|
|
|
void redis_object_info_subscribe(TableCallbackData *callback_data);
|
2016-12-09 00:51:44 -08:00
|
|
|
|
2017-03-07 00:32:15 -08:00
|
|
|
void redis_push_error(TableCallbackData *callback_data);
|
|
|
|
|
2016-10-29 15:22:33 -07:00
|
|
|
#endif /* REDIS_H */
|