replicator-queue.c revision a8c5a86d183db25a57bf193c06b41e092ec2e151
/* Copyright (c) 2013-2014 Dovecot authors, see the included COPYING file */
#include "lib.h"
#include "array.h"
#include "ioloop.h"
#include "istream.h"
#include "ostream.h"
#include "str.h"
#include "strescape.h"
#include "hash.h"
#include "replicator-queue.h"
#include <unistd.h>
#include <fcntl.h>
struct replicator_sync_lookup {
struct replicator_user *user;
void *context;
bool wait_for_next_push;
};
struct replicator_queue {
struct priorityq *user_queue;
/* username => struct replicator_user* */
unsigned int full_sync_interval;
unsigned int failure_resync_interval;
void (*change_callback)(void *context);
void *change_context;
};
struct replicator_queue_iter {
struct replicator_queue *queue;
struct hash_iterate_context *iter;
};
{
return -1;
return 1;
/* there is something to replicate */
return -1;
return 1;
/* resync failures first */
if (user1->last_sync_failed)
return -1;
else
return 1;
} else if (user1->last_sync_failed) {
/* both have failed. resync failures with fast-sync timestamp */
return -1;
return 1;
} else {
/* nothing to replicate, but do still periodic full syncs */
return -1;
return 1;
}
return 0;
}
struct replicator_queue *
replicator_queue_init(unsigned int full_sync_interval,
unsigned int failure_resync_interval)
{
struct replicator_queue *queue;
return queue;
}
{
struct priorityq_item *item;
}
}
void *context)
{
}
struct replicator_user *
{
}
static struct replicator_user *
enum replication_priority priority)
{
struct replicator_user *user;
} else {
/* user already has a higher priority than this */
return user;
}
}
return user;
}
struct replicator_user *
enum replication_priority priority)
{
struct replicator_user *user;
return user;
}
const char *username,
void *context)
{
struct replicator_user *user;
struct replicator_sync_lookup *lookup;
}
struct replicator_user **_user)
{
}
struct replicator_user *user,
unsigned int *next_secs_r)
{
return TRUE;
if (user->last_sync_failed) {
} else {
}
if (next_sync <= ioloop_time)
return TRUE;
return FALSE;
}
struct replicator_user *
unsigned int *next_secs_r)
{
struct priorityq_item *item;
struct replicator_user *user;
/* no users defined. we shouldn't normally get here */
*next_secs_r = 3600;
return NULL;
}
/* we don't want to sync the user yet */
return NULL;
}
return user;
}
static void
struct replicator_user *user)
{
struct replicator_sync_lookup *lookups;
unsigned int i, count;
for (i = 0; i < count; ) {
i++;
else if (lookups[i].wait_for_next_push) {
/* another sync request came while user was being
replicated */
i++;
} else {
}
}
}
struct replicator_user *user)
{
T_BEGIN {
} T_END;
}
static int
{
unsigned int priority;
/* <user> <priority> <last update> <last fast sync> <last full sync>
<last failed> <state> */
return -1;
if (username[0] == '\0' ||
return -1;
/* we already have a newer state */
return 0;
}
/* either one of these could be newer. use the one
with higher priority. */
return 0;
}
}
return 0;
}
{
const char *line;
if (fd == -1) {
return 0;
return -1;
}
T_BEGIN {
} T_END;
if (ret < 0) {
i_error("Corrupted replicator record in %s: %s",
break;
}
}
if (input->stream_errno != 0)
ret = -1;
return ret;
}
static void
{
(long long)user->last_update,
(long long)user->last_fast_sync,
(long long)user->last_full_sync,
}
{
struct replicator_queue_iter *iter;
struct replicator_user *user;
if (fd == -1) {
return -1;
}
str_truncate(str, 0);
break;
}
if (o_stream_nfinish(output) < 0) {
ret = -1;
}
return ret;
}
struct replicator_queue_iter *
{
struct replicator_queue_iter *iter;
return iter;
}
struct replicator_user *
{
struct replicator_user *user;
char *username;
return NULL;
return user;
}
{
}