1 #ifndef REPLICATOR_QUEUE_H
2 #define REPLICATOR_QUEUE_H
3 
4 #include "priorityq.h"
5 #include "replication-common.h"
6 
7 struct replicator_user {
8 	struct priorityq_item item;
9 
10 	char *username;
11 	/* dsync state for incremental syncing */
12 	char *state;
13 	/* last time this user's state was updated */
14 	time_t last_update;
15 	/* last_fast_sync is always >= last_full_sync. */
16 	time_t last_fast_sync, last_full_sync, last_successful_sync;
17 
18 	int refcount;
19 	enum replication_priority priority;
20 	/* User isn't currently in replication queue */
21 	bool popped:1;
22 	/* Last replication sync failed */
23 	bool last_sync_failed:1;
24 	/* Force a full sync on the next replication */
25 	bool force_full_sync:1;
26 };
27 
28 typedef void replicator_sync_callback_t(bool success, void *context);
29 
30 struct replicator_queue *
31 replicator_queue_init(unsigned int full_sync_interval,
32 		      unsigned int failure_resync_interval);
33 void replicator_queue_deinit(struct replicator_queue **queue);
34 
35 /* Call the specified callback when data is added/removed/moved in queue
36    via _add(), _add_sync() or _remove() functions (not push/pop). */
37 void replicator_queue_set_change_callback(struct replicator_queue *queue,
38 					  void (*callback)(void *context),
39 					  void *context);
40 
41 /* Reference the user */
42 void replicator_user_ref(struct replicator_user *user);
43 /* Unreference the user. Returns TRUE if refcount is still >0. */
44 bool replicator_user_unref(struct replicator_user **user);
45 
46 /* Lookup an existing user */
47 struct replicator_user *
48 replicator_queue_lookup(struct replicator_queue *queue, const char *username);
49 /* Add a user to queue and return it. If the user already exists, it's updated
50    only if the new priority is higher. */
51 struct replicator_user *
52 replicator_queue_add(struct replicator_queue *queue, const char *username,
53 		     enum replication_priority priority);
54 void replicator_queue_add_sync(struct replicator_queue *queue,
55 			       const char *username,
56 			       replicator_sync_callback_t *callback,
57 			       void *context);
58 /* Remove user from replication queue and free it. */
59 void replicator_queue_remove(struct replicator_queue *queue,
60 			     struct replicator_user **user);
61 
62 /* Return the next user from replication queue, and remove it from the queue.
63    If there's nothing to be replicated currently, returns NULL and sets
64    next_secs_r to when there should be more work to do. */
65 struct replicator_user *
66 replicator_queue_pop(struct replicator_queue *queue,
67 		     unsigned int *next_secs_r);
68 /* Add user back to queue. */
69 void replicator_queue_push(struct replicator_queue *queue,
70 			   struct replicator_user *user);
71 
72 int replicator_queue_import(struct replicator_queue *queue, const char *path);
73 int replicator_queue_export(struct replicator_queue *queue, const char *path);
74 
75 /* Returns TRUE if user replication can be started now, FALSE if not. When
76    returning FALSE, next_secs_r is set to user's next replication time. */
77 bool replicator_queue_want_sync_now(struct replicator_queue *queue,
78 				    struct replicator_user *user,
79 				    unsigned int *next_secs_r);
80 /* Iterate through all users in the queue. */
81 struct replicator_queue_iter *
82 replicator_queue_iter_init(struct replicator_queue *queue);
83 struct replicator_user *
84 replicator_queue_iter_next(struct replicator_queue_iter *iter);
85 void replicator_queue_iter_deinit(struct replicator_queue_iter **iter);
86 
87 void replicator_queue_add_auth_users(struct replicator_queue *queue,
88 				     const char *auth_socket_path,
89 				     const char *usermask, time_t last_update);
90 
91 #endif
92