Mercurial > dovecot > original-hg > dovecot-1.2
annotate src/lib-dict/dict-client.c @ 9658:8ba4253adc9b HEAD tip
*-login: SSL connections didn't get closed when the client got destroyed.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Thu, 08 May 2014 16:41:29 +0300 |
parents | 002b58bab1f5 |
children |
rev | line source |
---|---|
9532
00cd9aacd03c
Updated copyright notices to include year 2010.
Timo Sirainen <tss@iki.fi>
parents:
9361
diff
changeset
|
1 /* Copyright (c) 2005-2010 Dovecot authors, see the included COPYING file */ |
3793 | 2 |
3 #include "lib.h" | |
9361
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
4 #include "llist.h" |
3793 | 5 #include "str.h" |
6 #include "network.h" | |
7 #include "istream.h" | |
8 #include "ostream.h" | |
9 #include "dict-private.h" | |
10 #include "dict-client.h" | |
11 | |
9361
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
12 #include <stdlib.h> |
3793 | 13 #include <unistd.h> |
14 #include <fcntl.h> | |
15 | |
9562
0dca2668004f
dict proxy: Disconnect from dict server after 1 second of idling.
Timo Sirainen <tss@iki.fi>
parents:
9532
diff
changeset
|
16 /* Disconnect from dict server after this many milliseconds of idling after |
0dca2668004f
dict proxy: Disconnect from dict server after 1 second of idling.
Timo Sirainen <tss@iki.fi>
parents:
9532
diff
changeset
|
17 sending a command. This timeout is short, because dict server does blocking |
0dca2668004f
dict proxy: Disconnect from dict server after 1 second of idling.
Timo Sirainen <tss@iki.fi>
parents:
9532
diff
changeset
|
18 dict accesses, so it can handle only one client at a time. increasing the |
0dca2668004f
dict proxy: Disconnect from dict server after 1 second of idling.
Timo Sirainen <tss@iki.fi>
parents:
9532
diff
changeset
|
19 timeout increases number of idling dict processes. */ |
0dca2668004f
dict proxy: Disconnect from dict server after 1 second of idling.
Timo Sirainen <tss@iki.fi>
parents:
9532
diff
changeset
|
20 #define DICT_CLIENT_TIMEOUT_MSECS 1000 |
0dca2668004f
dict proxy: Disconnect from dict server after 1 second of idling.
Timo Sirainen <tss@iki.fi>
parents:
9532
diff
changeset
|
21 |
9563
002b58bab1f5
dict proxy client: Timeout lookups after 30 s, log warning if lookup takes >5 s.
Timo Sirainen <tss@iki.fi>
parents:
9562
diff
changeset
|
22 /* Abort dict lookup after this many seconds. */ |
002b58bab1f5
dict proxy client: Timeout lookups after 30 s, log warning if lookup takes >5 s.
Timo Sirainen <tss@iki.fi>
parents:
9562
diff
changeset
|
23 #define DICT_CLIENT_READ_TIMEOUT_SECS 30 |
002b58bab1f5
dict proxy client: Timeout lookups after 30 s, log warning if lookup takes >5 s.
Timo Sirainen <tss@iki.fi>
parents:
9562
diff
changeset
|
24 /* Log a warning if dict lookup takes longer than this many seconds. */ |
002b58bab1f5
dict proxy client: Timeout lookups after 30 s, log warning if lookup takes >5 s.
Timo Sirainen <tss@iki.fi>
parents:
9562
diff
changeset
|
25 #define DICT_CLIENT_READ_WARN_TIMEOUT_SECS 5 |
002b58bab1f5
dict proxy client: Timeout lookups after 30 s, log warning if lookup takes >5 s.
Timo Sirainen <tss@iki.fi>
parents:
9562
diff
changeset
|
26 |
3793 | 27 struct client_dict { |
28 struct dict dict; | |
29 | |
30 pool_t pool; | |
31 int fd; | |
32 const char *uri; | |
33 const char *username; | |
34 const char *path; | |
4516
aa2f73a4df26
Dictionary changes: Added support for defining value's type. Key is still always a string. Added support for sorting the iteration replies. Added dict_unset(). Added Berkeley DB support. Most of the code written by Tianyan Liu.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
4512
diff
changeset
|
35 enum dict_data_type value_type; |
3793 | 36 |
7008
6950bb5e7921
Don't try to reconnect more often than once/sec.
Timo Sirainen <tss@iki.fi>
parents:
7007
diff
changeset
|
37 time_t last_connect_try; |
3793 | 38 struct istream *input; |
39 struct ostream *output; | |
9361
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
40 struct io *io; |
9562
0dca2668004f
dict proxy: Disconnect from dict server after 1 second of idling.
Timo Sirainen <tss@iki.fi>
parents:
9532
diff
changeset
|
41 struct timeout *to_idle; |
9361
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
42 |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
43 struct client_dict_transaction_context *transactions; |
3793 | 44 |
45 unsigned int connect_counter; | |
46 unsigned int transaction_id_counter; | |
9361
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
47 unsigned int async_commits; |
3793 | 48 |
49 unsigned int in_iteration:1; | |
50 unsigned int handshaked:1; | |
51 }; | |
52 | |
53 struct client_dict_iterate_context { | |
54 struct dict_iterate_context ctx; | |
55 | |
56 pool_t pool; | |
3863
55df57c028d4
Added "bool" type and changed all ints that were used as booleans to bool.
Timo Sirainen <tss@iki.fi>
parents:
3858
diff
changeset
|
57 bool failed; |
3793 | 58 }; |
59 | |
60 struct client_dict_transaction_context { | |
61 struct dict_transaction_context ctx; | |
9361
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
62 struct client_dict_transaction_context *prev, *next; |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
63 |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
64 /* for async commits */ |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
65 dict_transaction_commit_callback_t *callback; |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
66 void *context; |
3793 | 67 |
68 unsigned int id; | |
69 unsigned int connect_counter; | |
70 | |
4512
b5d4c1e9a492
Delay sending the transaction begin command to server until the first
Timo Sirainen <tss@iki.fi>
parents:
4385
diff
changeset
|
71 unsigned int failed:1; |
b5d4c1e9a492
Delay sending the transaction begin command to server until the first
Timo Sirainen <tss@iki.fi>
parents:
4385
diff
changeset
|
72 unsigned int sent_begin:1; |
3793 | 73 }; |
74 | |
75 static int client_dict_connect(struct client_dict *dict); | |
76 static void client_dict_disconnect(struct client_dict *dict); | |
77 | |
78 const char *dict_client_escape(const char *src) | |
79 { | |
80 const char *p; | |
81 string_t *dest; | |
82 | |
83 /* first do a quick lookup to see if there's anything to escape. | |
84 probably not. */ | |
85 for (p = src; *p != '\0'; p++) { | |
86 if (*p == '\t' || *p == '\n' || *p == '\001') | |
87 break; | |
88 } | |
89 | |
90 if (*p == '\0') | |
91 return src; | |
92 | |
93 dest = t_str_new(256); | |
94 str_append_n(dest, src, p - src); | |
95 | |
3858 | 96 for (; *p != '\0'; p++) { |
3793 | 97 switch (*p) { |
98 case '\t': | |
99 str_append_c(dest, '\001'); | |
100 str_append_c(dest, 't'); | |
101 break; | |
102 case '\n': | |
103 str_append_c(dest, '\001'); | |
104 str_append_c(dest, 'n'); | |
105 break; | |
106 case '\001': | |
107 str_append_c(dest, '\001'); | |
108 str_append_c(dest, '1'); | |
109 break; | |
110 default: | |
111 str_append_c(dest, *p); | |
112 break; | |
113 } | |
114 } | |
115 return str_c(dest); | |
116 } | |
117 | |
118 const char *dict_client_unescape(const char *src) | |
119 { | |
120 const char *p; | |
121 string_t *dest; | |
122 | |
123 /* first do a quick lookup to see if there's anything to unescape. | |
124 probably not. */ | |
125 for (p = src; *p != '\0'; p++) { | |
126 if (*p == '\001') | |
127 break; | |
128 } | |
129 | |
130 if (*p == '\0') | |
131 return src; | |
132 | |
133 dest = t_str_new(256); | |
134 str_append_n(dest, src, p - src); | |
135 for (; *p != '\0'; p++) { | |
136 if (*p != '\001') | |
137 str_append_c(dest, *p); | |
138 else if (p[1] != '\0') { | |
139 p++; | |
140 switch (*p) { | |
141 case '1': | |
142 str_append_c(dest, '\001'); | |
143 break; | |
144 case 't': | |
145 str_append_c(dest, '\t'); | |
146 break; | |
147 case 'n': | |
148 str_append_c(dest, '\n'); | |
149 break; | |
150 } | |
151 } | |
152 } | |
153 return str_c(dest); | |
154 } | |
155 | |
156 static int client_dict_send_query(struct client_dict *dict, const char *query) | |
157 { | |
4368 | 158 if (dict->output == NULL) { |
159 /* not connected currently */ | |
160 if (client_dict_connect(dict) < 0) | |
161 return -1; | |
162 } | |
163 | |
3793 | 164 if (o_stream_send_str(dict->output, query) < 0 || |
165 o_stream_flush(dict->output) < 0) { | |
166 /* Send failed */ | |
167 if (!dict->handshaked) { | |
168 /* we're trying to send hello, don't try to reconnect */ | |
169 return -1; | |
170 } | |
171 | |
172 /* Reconnect and try again. */ | |
173 client_dict_disconnect(dict); | |
174 if (client_dict_connect(dict) < 0) | |
175 return -1; | |
176 | |
177 if (o_stream_send_str(dict->output, query) < 0 || | |
178 o_stream_flush(dict->output) < 0) { | |
179 i_error("write(%s) failed: %m", dict->path); | |
180 return -1; | |
181 } | |
182 } | |
183 return 0; | |
184 } | |
185 | |
4368 | 186 static int |
4512
b5d4c1e9a492
Delay sending the transaction begin command to server until the first
Timo Sirainen <tss@iki.fi>
parents:
4385
diff
changeset
|
187 client_dict_transaction_send_begin(struct client_dict_transaction_context *ctx) |
b5d4c1e9a492
Delay sending the transaction begin command to server until the first
Timo Sirainen <tss@iki.fi>
parents:
4385
diff
changeset
|
188 { |
b5d4c1e9a492
Delay sending the transaction begin command to server until the first
Timo Sirainen <tss@iki.fi>
parents:
4385
diff
changeset
|
189 struct client_dict *dict = (struct client_dict *)ctx->ctx.dict; |
b5d4c1e9a492
Delay sending the transaction begin command to server until the first
Timo Sirainen <tss@iki.fi>
parents:
4385
diff
changeset
|
190 |
b5d4c1e9a492
Delay sending the transaction begin command to server until the first
Timo Sirainen <tss@iki.fi>
parents:
4385
diff
changeset
|
191 if (ctx->failed) |
b5d4c1e9a492
Delay sending the transaction begin command to server until the first
Timo Sirainen <tss@iki.fi>
parents:
4385
diff
changeset
|
192 return -1; |
b5d4c1e9a492
Delay sending the transaction begin command to server until the first
Timo Sirainen <tss@iki.fi>
parents:
4385
diff
changeset
|
193 |
7226
e6693a0ec8e1
Renamed T_FRAME_BEGIN/END to T_BEGIN/END. Removed T_FRAME() macro and
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
194 T_BEGIN { |
6940
414c9d631a81
Replaced t_push/t_pop calls with T_FRAME*() macros.
Timo Sirainen <tss@iki.fi>
parents:
6525
diff
changeset
|
195 const char *query; |
414c9d631a81
Replaced t_push/t_pop calls with T_FRAME*() macros.
Timo Sirainen <tss@iki.fi>
parents:
6525
diff
changeset
|
196 |
414c9d631a81
Replaced t_push/t_pop calls with T_FRAME*() macros.
Timo Sirainen <tss@iki.fi>
parents:
6525
diff
changeset
|
197 query = t_strdup_printf("%c%u\n", DICT_PROTOCOL_CMD_BEGIN, |
414c9d631a81
Replaced t_push/t_pop calls with T_FRAME*() macros.
Timo Sirainen <tss@iki.fi>
parents:
6525
diff
changeset
|
198 ctx->id); |
414c9d631a81
Replaced t_push/t_pop calls with T_FRAME*() macros.
Timo Sirainen <tss@iki.fi>
parents:
6525
diff
changeset
|
199 if (client_dict_send_query(dict, query) < 0) |
414c9d631a81
Replaced t_push/t_pop calls with T_FRAME*() macros.
Timo Sirainen <tss@iki.fi>
parents:
6525
diff
changeset
|
200 ctx->failed = TRUE; |
414c9d631a81
Replaced t_push/t_pop calls with T_FRAME*() macros.
Timo Sirainen <tss@iki.fi>
parents:
6525
diff
changeset
|
201 else |
414c9d631a81
Replaced t_push/t_pop calls with T_FRAME*() macros.
Timo Sirainen <tss@iki.fi>
parents:
6525
diff
changeset
|
202 ctx->connect_counter = dict->connect_counter; |
7226
e6693a0ec8e1
Renamed T_FRAME_BEGIN/END to T_BEGIN/END. Removed T_FRAME() macro and
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
203 } T_END; |
4512
b5d4c1e9a492
Delay sending the transaction begin command to server until the first
Timo Sirainen <tss@iki.fi>
parents:
4385
diff
changeset
|
204 |
b5d4c1e9a492
Delay sending the transaction begin command to server until the first
Timo Sirainen <tss@iki.fi>
parents:
4385
diff
changeset
|
205 return ctx->failed ? -1 : 0; |
b5d4c1e9a492
Delay sending the transaction begin command to server until the first
Timo Sirainen <tss@iki.fi>
parents:
4385
diff
changeset
|
206 } |
b5d4c1e9a492
Delay sending the transaction begin command to server until the first
Timo Sirainen <tss@iki.fi>
parents:
4385
diff
changeset
|
207 |
b5d4c1e9a492
Delay sending the transaction begin command to server until the first
Timo Sirainen <tss@iki.fi>
parents:
4385
diff
changeset
|
208 static int |
4368 | 209 client_dict_send_transaction_query(struct client_dict_transaction_context *ctx, |
210 const char *query) | |
211 { | |
212 struct client_dict *dict = (struct client_dict *)ctx->ctx.dict; | |
213 | |
4512
b5d4c1e9a492
Delay sending the transaction begin command to server until the first
Timo Sirainen <tss@iki.fi>
parents:
4385
diff
changeset
|
214 if (!ctx->sent_begin) { |
b5d4c1e9a492
Delay sending the transaction begin command to server until the first
Timo Sirainen <tss@iki.fi>
parents:
4385
diff
changeset
|
215 if (client_dict_transaction_send_begin(ctx) < 0) |
b5d4c1e9a492
Delay sending the transaction begin command to server until the first
Timo Sirainen <tss@iki.fi>
parents:
4385
diff
changeset
|
216 return -1; |
b5d4c1e9a492
Delay sending the transaction begin command to server until the first
Timo Sirainen <tss@iki.fi>
parents:
4385
diff
changeset
|
217 ctx->sent_begin = TRUE; |
b5d4c1e9a492
Delay sending the transaction begin command to server until the first
Timo Sirainen <tss@iki.fi>
parents:
4385
diff
changeset
|
218 } |
b5d4c1e9a492
Delay sending the transaction begin command to server until the first
Timo Sirainen <tss@iki.fi>
parents:
4385
diff
changeset
|
219 |
4385 | 220 if (ctx->connect_counter != dict->connect_counter || ctx->failed) |
221 return -1; | |
222 | |
223 if (dict->output == NULL) { | |
4512
b5d4c1e9a492
Delay sending the transaction begin command to server until the first
Timo Sirainen <tss@iki.fi>
parents:
4385
diff
changeset
|
224 /* not connected, this'll fail */ |
b5d4c1e9a492
Delay sending the transaction begin command to server until the first
Timo Sirainen <tss@iki.fi>
parents:
4385
diff
changeset
|
225 return -1; |
4385 | 226 } |
227 | |
4368 | 228 if (o_stream_send_str(dict->output, query) < 0 || |
229 o_stream_flush(dict->output) < 0) { | |
230 /* Send failed. Our transactions have died, so don't even try | |
231 to re-send the command */ | |
232 ctx->failed = TRUE; | |
233 client_dict_disconnect(dict); | |
234 return -1; | |
235 } | |
236 return 0; | |
237 } | |
238 | |
9361
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
239 static struct client_dict_transaction_context * |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
240 client_dict_transaction_find(struct client_dict *dict, unsigned int id) |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
241 { |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
242 struct client_dict_transaction_context *ctx; |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
243 |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
244 for (ctx = dict->transactions; ctx != NULL; ctx = ctx->next) { |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
245 if (ctx->id == id) |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
246 return ctx; |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
247 } |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
248 return NULL; |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
249 } |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
250 |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
251 static void |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
252 client_dict_finish_transaction(struct client_dict *dict, |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
253 unsigned int id, int ret) |
3793 | 254 { |
9361
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
255 struct client_dict_transaction_context *ctx; |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
256 |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
257 ctx = client_dict_transaction_find(dict, id); |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
258 if (ctx == NULL) { |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
259 i_error("dict-client: Unknown transaction id %u", id); |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
260 return; |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
261 } |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
262 if (ctx->callback != NULL) |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
263 ctx->callback(ret, ctx->context); |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
264 |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
265 DLLIST_REMOVE(&dict->transactions, ctx); |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
266 i_free(ctx); |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
267 |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
268 i_assert(dict->async_commits > 0); |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
269 if (--dict->async_commits == 0) |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
270 io_remove(&dict->io); |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
271 } |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
272 |
9563
002b58bab1f5
dict proxy client: Timeout lookups after 30 s, log warning if lookup takes >5 s.
Timo Sirainen <tss@iki.fi>
parents:
9562
diff
changeset
|
273 static ssize_t client_dict_read_timeout(struct client_dict *dict) |
002b58bab1f5
dict proxy client: Timeout lookups after 30 s, log warning if lookup takes >5 s.
Timo Sirainen <tss@iki.fi>
parents:
9562
diff
changeset
|
274 { |
002b58bab1f5
dict proxy client: Timeout lookups after 30 s, log warning if lookup takes >5 s.
Timo Sirainen <tss@iki.fi>
parents:
9562
diff
changeset
|
275 time_t now, timeout; |
002b58bab1f5
dict proxy client: Timeout lookups after 30 s, log warning if lookup takes >5 s.
Timo Sirainen <tss@iki.fi>
parents:
9562
diff
changeset
|
276 unsigned int diff; |
002b58bab1f5
dict proxy client: Timeout lookups after 30 s, log warning if lookup takes >5 s.
Timo Sirainen <tss@iki.fi>
parents:
9562
diff
changeset
|
277 ssize_t ret; |
002b58bab1f5
dict proxy client: Timeout lookups after 30 s, log warning if lookup takes >5 s.
Timo Sirainen <tss@iki.fi>
parents:
9562
diff
changeset
|
278 |
002b58bab1f5
dict proxy client: Timeout lookups after 30 s, log warning if lookup takes >5 s.
Timo Sirainen <tss@iki.fi>
parents:
9562
diff
changeset
|
279 now = time(NULL); |
002b58bab1f5
dict proxy client: Timeout lookups after 30 s, log warning if lookup takes >5 s.
Timo Sirainen <tss@iki.fi>
parents:
9562
diff
changeset
|
280 timeout = now + DICT_CLIENT_READ_TIMEOUT_SECS; |
002b58bab1f5
dict proxy client: Timeout lookups after 30 s, log warning if lookup takes >5 s.
Timo Sirainen <tss@iki.fi>
parents:
9562
diff
changeset
|
281 |
002b58bab1f5
dict proxy client: Timeout lookups after 30 s, log warning if lookup takes >5 s.
Timo Sirainen <tss@iki.fi>
parents:
9562
diff
changeset
|
282 do { |
002b58bab1f5
dict proxy client: Timeout lookups after 30 s, log warning if lookup takes >5 s.
Timo Sirainen <tss@iki.fi>
parents:
9562
diff
changeset
|
283 alarm(timeout - now); |
002b58bab1f5
dict proxy client: Timeout lookups after 30 s, log warning if lookup takes >5 s.
Timo Sirainen <tss@iki.fi>
parents:
9562
diff
changeset
|
284 ret = i_stream_read(dict->input); |
002b58bab1f5
dict proxy client: Timeout lookups after 30 s, log warning if lookup takes >5 s.
Timo Sirainen <tss@iki.fi>
parents:
9562
diff
changeset
|
285 alarm(0); |
002b58bab1f5
dict proxy client: Timeout lookups after 30 s, log warning if lookup takes >5 s.
Timo Sirainen <tss@iki.fi>
parents:
9562
diff
changeset
|
286 if (ret != 0) |
002b58bab1f5
dict proxy client: Timeout lookups after 30 s, log warning if lookup takes >5 s.
Timo Sirainen <tss@iki.fi>
parents:
9562
diff
changeset
|
287 break; |
002b58bab1f5
dict proxy client: Timeout lookups after 30 s, log warning if lookup takes >5 s.
Timo Sirainen <tss@iki.fi>
parents:
9562
diff
changeset
|
288 |
002b58bab1f5
dict proxy client: Timeout lookups after 30 s, log warning if lookup takes >5 s.
Timo Sirainen <tss@iki.fi>
parents:
9562
diff
changeset
|
289 /* interrupted most likely because of timeout, |
002b58bab1f5
dict proxy client: Timeout lookups after 30 s, log warning if lookup takes >5 s.
Timo Sirainen <tss@iki.fi>
parents:
9562
diff
changeset
|
290 but check anyway. */ |
002b58bab1f5
dict proxy client: Timeout lookups after 30 s, log warning if lookup takes >5 s.
Timo Sirainen <tss@iki.fi>
parents:
9562
diff
changeset
|
291 now = time(NULL); |
002b58bab1f5
dict proxy client: Timeout lookups after 30 s, log warning if lookup takes >5 s.
Timo Sirainen <tss@iki.fi>
parents:
9562
diff
changeset
|
292 } while (now < timeout); |
002b58bab1f5
dict proxy client: Timeout lookups after 30 s, log warning if lookup takes >5 s.
Timo Sirainen <tss@iki.fi>
parents:
9562
diff
changeset
|
293 |
002b58bab1f5
dict proxy client: Timeout lookups after 30 s, log warning if lookup takes >5 s.
Timo Sirainen <tss@iki.fi>
parents:
9562
diff
changeset
|
294 if (ret > 0) { |
002b58bab1f5
dict proxy client: Timeout lookups after 30 s, log warning if lookup takes >5 s.
Timo Sirainen <tss@iki.fi>
parents:
9562
diff
changeset
|
295 diff = time(NULL) - now; |
002b58bab1f5
dict proxy client: Timeout lookups after 30 s, log warning if lookup takes >5 s.
Timo Sirainen <tss@iki.fi>
parents:
9562
diff
changeset
|
296 if (diff >= DICT_CLIENT_READ_WARN_TIMEOUT_SECS) { |
002b58bab1f5
dict proxy client: Timeout lookups after 30 s, log warning if lookup takes >5 s.
Timo Sirainen <tss@iki.fi>
parents:
9562
diff
changeset
|
297 i_warning("read(%s): dict lookup took %u seconds", |
002b58bab1f5
dict proxy client: Timeout lookups after 30 s, log warning if lookup takes >5 s.
Timo Sirainen <tss@iki.fi>
parents:
9562
diff
changeset
|
298 dict->path, diff); |
002b58bab1f5
dict proxy client: Timeout lookups after 30 s, log warning if lookup takes >5 s.
Timo Sirainen <tss@iki.fi>
parents:
9562
diff
changeset
|
299 } |
002b58bab1f5
dict proxy client: Timeout lookups after 30 s, log warning if lookup takes >5 s.
Timo Sirainen <tss@iki.fi>
parents:
9562
diff
changeset
|
300 } |
002b58bab1f5
dict proxy client: Timeout lookups after 30 s, log warning if lookup takes >5 s.
Timo Sirainen <tss@iki.fi>
parents:
9562
diff
changeset
|
301 return ret; |
002b58bab1f5
dict proxy client: Timeout lookups after 30 s, log warning if lookup takes >5 s.
Timo Sirainen <tss@iki.fi>
parents:
9562
diff
changeset
|
302 } |
002b58bab1f5
dict proxy client: Timeout lookups after 30 s, log warning if lookup takes >5 s.
Timo Sirainen <tss@iki.fi>
parents:
9562
diff
changeset
|
303 |
9361
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
304 static int client_dict_read_one_line(struct client_dict *dict, char **line_r) |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
305 { |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
306 unsigned int id; |
3793 | 307 char *line; |
9563
002b58bab1f5
dict proxy client: Timeout lookups after 30 s, log warning if lookup takes >5 s.
Timo Sirainen <tss@iki.fi>
parents:
9562
diff
changeset
|
308 ssize_t ret; |
3793 | 309 |
9361
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
310 *line_r = NULL; |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
311 while ((line = i_stream_next_line(dict->input)) == NULL) { |
9563
002b58bab1f5
dict proxy client: Timeout lookups after 30 s, log warning if lookup takes >5 s.
Timo Sirainen <tss@iki.fi>
parents:
9562
diff
changeset
|
312 ret = client_dict_read_timeout(dict); |
9361
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
313 switch (ret) { |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
314 case -1: |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
315 if (dict->input->stream_errno != 0) |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
316 i_error("read(%s) failed: %m", dict->path); |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
317 else { |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
318 i_error("read(%s) failed: Remote disconnected", |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
319 dict->path); |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
320 } |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
321 return -1; |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
322 case -2: |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
323 i_error("read(%s) returned too much data", dict->path); |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
324 return -1; |
9563
002b58bab1f5
dict proxy client: Timeout lookups after 30 s, log warning if lookup takes >5 s.
Timo Sirainen <tss@iki.fi>
parents:
9562
diff
changeset
|
325 case 0: |
002b58bab1f5
dict proxy client: Timeout lookups after 30 s, log warning if lookup takes >5 s.
Timo Sirainen <tss@iki.fi>
parents:
9562
diff
changeset
|
326 i_error("read(%s) failed: Timeout after %u seconds", |
002b58bab1f5
dict proxy client: Timeout lookups after 30 s, log warning if lookup takes >5 s.
Timo Sirainen <tss@iki.fi>
parents:
9562
diff
changeset
|
327 dict->path, DICT_CLIENT_READ_TIMEOUT_SECS); |
002b58bab1f5
dict proxy client: Timeout lookups after 30 s, log warning if lookup takes >5 s.
Timo Sirainen <tss@iki.fi>
parents:
9562
diff
changeset
|
328 return -1; |
9361
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
329 default: |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
330 i_assert(ret > 0); |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
331 break; |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
332 } |
3793 | 333 } |
9361
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
334 if (*line == DICT_PROTOCOL_REPLY_ASYNC_COMMIT) { |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
335 switch (line[1]) { |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
336 case DICT_PROTOCOL_REPLY_OK: |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
337 ret = 1; |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
338 break; |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
339 case DICT_PROTOCOL_REPLY_NOTFOUND: |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
340 ret = 0; |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
341 break; |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
342 case DICT_PROTOCOL_REPLY_FAIL: |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
343 ret = -1; |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
344 break; |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
345 default: |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
346 i_error("dict-client: Invalid async commit line: %s", |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
347 line); |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
348 return 0; |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
349 } |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
350 id = strtoul(line+2, NULL, 10); |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
351 client_dict_finish_transaction(dict, id, ret); |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
352 return 0; |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
353 } |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
354 *line_r = line; |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
355 return 1; |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
356 } |
3793 | 357 |
9562
0dca2668004f
dict proxy: Disconnect from dict server after 1 second of idling.
Timo Sirainen <tss@iki.fi>
parents:
9532
diff
changeset
|
358 static bool client_dict_is_finished(struct client_dict *dict) |
0dca2668004f
dict proxy: Disconnect from dict server after 1 second of idling.
Timo Sirainen <tss@iki.fi>
parents:
9532
diff
changeset
|
359 { |
0dca2668004f
dict proxy: Disconnect from dict server after 1 second of idling.
Timo Sirainen <tss@iki.fi>
parents:
9532
diff
changeset
|
360 return dict->transactions == NULL && !dict->in_iteration && |
0dca2668004f
dict proxy: Disconnect from dict server after 1 second of idling.
Timo Sirainen <tss@iki.fi>
parents:
9532
diff
changeset
|
361 dict->async_commits == 0; |
0dca2668004f
dict proxy: Disconnect from dict server after 1 second of idling.
Timo Sirainen <tss@iki.fi>
parents:
9532
diff
changeset
|
362 } |
0dca2668004f
dict proxy: Disconnect from dict server after 1 second of idling.
Timo Sirainen <tss@iki.fi>
parents:
9532
diff
changeset
|
363 |
0dca2668004f
dict proxy: Disconnect from dict server after 1 second of idling.
Timo Sirainen <tss@iki.fi>
parents:
9532
diff
changeset
|
364 static void client_dict_timeout(struct client_dict *dict) |
0dca2668004f
dict proxy: Disconnect from dict server after 1 second of idling.
Timo Sirainen <tss@iki.fi>
parents:
9532
diff
changeset
|
365 { |
0dca2668004f
dict proxy: Disconnect from dict server after 1 second of idling.
Timo Sirainen <tss@iki.fi>
parents:
9532
diff
changeset
|
366 if (client_dict_is_finished(dict)) |
0dca2668004f
dict proxy: Disconnect from dict server after 1 second of idling.
Timo Sirainen <tss@iki.fi>
parents:
9532
diff
changeset
|
367 client_dict_disconnect(dict); |
0dca2668004f
dict proxy: Disconnect from dict server after 1 second of idling.
Timo Sirainen <tss@iki.fi>
parents:
9532
diff
changeset
|
368 } |
0dca2668004f
dict proxy: Disconnect from dict server after 1 second of idling.
Timo Sirainen <tss@iki.fi>
parents:
9532
diff
changeset
|
369 |
0dca2668004f
dict proxy: Disconnect from dict server after 1 second of idling.
Timo Sirainen <tss@iki.fi>
parents:
9532
diff
changeset
|
370 static void client_dict_add_timeout(struct client_dict *dict) |
0dca2668004f
dict proxy: Disconnect from dict server after 1 second of idling.
Timo Sirainen <tss@iki.fi>
parents:
9532
diff
changeset
|
371 { |
0dca2668004f
dict proxy: Disconnect from dict server after 1 second of idling.
Timo Sirainen <tss@iki.fi>
parents:
9532
diff
changeset
|
372 if (dict->to_idle != NULL) |
0dca2668004f
dict proxy: Disconnect from dict server after 1 second of idling.
Timo Sirainen <tss@iki.fi>
parents:
9532
diff
changeset
|
373 timeout_reset(dict->to_idle); |
0dca2668004f
dict proxy: Disconnect from dict server after 1 second of idling.
Timo Sirainen <tss@iki.fi>
parents:
9532
diff
changeset
|
374 else if (client_dict_is_finished(dict)) { |
0dca2668004f
dict proxy: Disconnect from dict server after 1 second of idling.
Timo Sirainen <tss@iki.fi>
parents:
9532
diff
changeset
|
375 dict->to_idle = timeout_add(DICT_CLIENT_TIMEOUT_MSECS, |
0dca2668004f
dict proxy: Disconnect from dict server after 1 second of idling.
Timo Sirainen <tss@iki.fi>
parents:
9532
diff
changeset
|
376 client_dict_timeout, dict); |
0dca2668004f
dict proxy: Disconnect from dict server after 1 second of idling.
Timo Sirainen <tss@iki.fi>
parents:
9532
diff
changeset
|
377 } |
0dca2668004f
dict proxy: Disconnect from dict server after 1 second of idling.
Timo Sirainen <tss@iki.fi>
parents:
9532
diff
changeset
|
378 } |
0dca2668004f
dict proxy: Disconnect from dict server after 1 second of idling.
Timo Sirainen <tss@iki.fi>
parents:
9532
diff
changeset
|
379 |
9361
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
380 static char *client_dict_read_line(struct client_dict *dict) |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
381 { |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
382 char *line; |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
383 |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
384 while (client_dict_read_one_line(dict, &line) == 0) |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
385 ; |
9562
0dca2668004f
dict proxy: Disconnect from dict server after 1 second of idling.
Timo Sirainen <tss@iki.fi>
parents:
9532
diff
changeset
|
386 |
0dca2668004f
dict proxy: Disconnect from dict server after 1 second of idling.
Timo Sirainen <tss@iki.fi>
parents:
9532
diff
changeset
|
387 client_dict_add_timeout(dict); |
9361
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
388 return line; |
3793 | 389 } |
390 | |
391 static int client_dict_connect(struct client_dict *dict) | |
392 { | |
393 const char *query; | |
394 | |
395 i_assert(dict->fd == -1); | |
396 | |
7008
6950bb5e7921
Don't try to reconnect more often than once/sec.
Timo Sirainen <tss@iki.fi>
parents:
7007
diff
changeset
|
397 if (dict->last_connect_try == ioloop_time) { |
6950bb5e7921
Don't try to reconnect more often than once/sec.
Timo Sirainen <tss@iki.fi>
parents:
7007
diff
changeset
|
398 /* Try again later */ |
6950bb5e7921
Don't try to reconnect more often than once/sec.
Timo Sirainen <tss@iki.fi>
parents:
7007
diff
changeset
|
399 return -1; |
6950bb5e7921
Don't try to reconnect more often than once/sec.
Timo Sirainen <tss@iki.fi>
parents:
7007
diff
changeset
|
400 } |
6950bb5e7921
Don't try to reconnect more often than once/sec.
Timo Sirainen <tss@iki.fi>
parents:
7007
diff
changeset
|
401 dict->last_connect_try = ioloop_time; |
6950bb5e7921
Don't try to reconnect more often than once/sec.
Timo Sirainen <tss@iki.fi>
parents:
7007
diff
changeset
|
402 |
3793 | 403 dict->fd = net_connect_unix(dict->path); |
404 if (dict->fd == -1) { | |
405 i_error("net_connect_unix(%s) failed: %m", dict->path); | |
406 return -1; | |
407 } | |
408 | |
409 /* Dictionary lookups are blocking */ | |
410 net_set_nonblock(dict->fd, FALSE); | |
411 | |
6162
896cc473c1f0
Renamed i_stream_create_file() to i_stream_create_fd().
Timo Sirainen <tss@iki.fi>
parents:
6161
diff
changeset
|
412 dict->input = i_stream_create_fd(dict->fd, (size_t)-1, FALSE); |
6161
c62f7ee79446
Split o_stream_create_file() to _create_fd() and _create_fd_file().
Timo Sirainen <tss@iki.fi>
parents:
6142
diff
changeset
|
413 dict->output = o_stream_create_fd(dict->fd, 4096, FALSE); |
3793 | 414 dict->transaction_id_counter = 0; |
9361
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
415 dict->async_commits = 0; |
3793 | 416 |
4516
aa2f73a4df26
Dictionary changes: Added support for defining value's type. Key is still always a string. Added support for sorting the iteration replies. Added dict_unset(). Added Berkeley DB support. Most of the code written by Tianyan Liu.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
4512
diff
changeset
|
417 query = t_strdup_printf("%c%u\t%u\t%d\t%s\t%s\n", |
aa2f73a4df26
Dictionary changes: Added support for defining value's type. Key is still always a string. Added support for sorting the iteration replies. Added dict_unset(). Added Berkeley DB support. Most of the code written by Tianyan Liu.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
4512
diff
changeset
|
418 DICT_PROTOCOL_CMD_HELLO, |
3793 | 419 DICT_CLIENT_PROTOCOL_MAJOR_VERSION, |
420 DICT_CLIENT_PROTOCOL_MINOR_VERSION, | |
4516
aa2f73a4df26
Dictionary changes: Added support for defining value's type. Key is still always a string. Added support for sorting the iteration replies. Added dict_unset(). Added Berkeley DB support. Most of the code written by Tianyan Liu.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
4512
diff
changeset
|
421 dict->value_type, dict->username, dict->uri); |
3793 | 422 if (client_dict_send_query(dict, query) < 0) { |
423 client_dict_disconnect(dict); | |
424 return -1; | |
425 } | |
426 | |
427 dict->handshaked = TRUE; | |
428 return 0; | |
429 } | |
430 | |
431 static void client_dict_disconnect(struct client_dict *dict) | |
432 { | |
433 dict->connect_counter++; | |
434 dict->handshaked = FALSE; | |
435 | |
9562
0dca2668004f
dict proxy: Disconnect from dict server after 1 second of idling.
Timo Sirainen <tss@iki.fi>
parents:
9532
diff
changeset
|
436 if (dict->to_idle != NULL) |
0dca2668004f
dict proxy: Disconnect from dict server after 1 second of idling.
Timo Sirainen <tss@iki.fi>
parents:
9532
diff
changeset
|
437 timeout_remove(&dict->to_idle); |
9361
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
438 if (dict->io != NULL) |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
439 io_remove(&dict->io); |
3879
928229f8b3e6
deinit, unref, destroy, close, free, etc. functions now take a pointer to
Timo Sirainen <tss@iki.fi>
parents:
3863
diff
changeset
|
440 if (dict->input != NULL) |
4070
71b8faa84ec6
Added i_stream_destroy() and o_stream_destroy() and used them instead of
Timo Sirainen <tss@iki.fi>
parents:
3990
diff
changeset
|
441 i_stream_destroy(&dict->input); |
3879
928229f8b3e6
deinit, unref, destroy, close, free, etc. functions now take a pointer to
Timo Sirainen <tss@iki.fi>
parents:
3863
diff
changeset
|
442 if (dict->output != NULL) |
4070
71b8faa84ec6
Added i_stream_destroy() and o_stream_destroy() and used them instead of
Timo Sirainen <tss@iki.fi>
parents:
3990
diff
changeset
|
443 o_stream_destroy(&dict->output); |
3793 | 444 |
445 if (dict->fd != -1) { | |
446 if (close(dict->fd) < 0) | |
447 i_error("close(%s) failed: %m", dict->path); | |
448 dict->fd = -1; | |
449 } | |
450 } | |
451 | |
4516
aa2f73a4df26
Dictionary changes: Added support for defining value's type. Key is still always a string. Added support for sorting the iteration replies. Added dict_unset(). Added Berkeley DB support. Most of the code written by Tianyan Liu.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
4512
diff
changeset
|
452 static struct dict * |
4517
e661182eab75
Berkeley DB dict support is now enabled only when using --with-db configure option.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
4516
diff
changeset
|
453 client_dict_init(struct dict *driver, const char *uri, |
9174
eed86bcc33aa
dict proxy: Use base_dir as the default dict-server location.
Timo Sirainen <tss@iki.fi>
parents:
8683
diff
changeset
|
454 enum dict_data_type value_type, const char *username, |
eed86bcc33aa
dict proxy: Use base_dir as the default dict-server location.
Timo Sirainen <tss@iki.fi>
parents:
8683
diff
changeset
|
455 const char *base_dir) |
3793 | 456 { |
457 struct client_dict *dict; | |
3967
6fabe878c46d
Dictionary takes now a username parameter, which is used for private
Timo Sirainen <tss@iki.fi>
parents:
3879
diff
changeset
|
458 const char *dest_uri; |
3793 | 459 pool_t pool; |
460 | |
3967
6fabe878c46d
Dictionary takes now a username parameter, which is used for private
Timo Sirainen <tss@iki.fi>
parents:
3879
diff
changeset
|
461 /* uri = [<path>] ":" <uri> */ |
3793 | 462 dest_uri = strchr(uri, ':'); |
463 if (dest_uri == NULL) { | |
464 i_error("dict-client: Invalid URI: %s", uri); | |
465 return NULL; | |
466 } | |
467 | |
468 pool = pool_alloconly_create("client dict", 1024); | |
469 dict = p_new(pool, struct client_dict, 1); | |
470 dict->pool = pool; | |
4517
e661182eab75
Berkeley DB dict support is now enabled only when using --with-db configure option.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
4516
diff
changeset
|
471 dict->dict = *driver; |
4516
aa2f73a4df26
Dictionary changes: Added support for defining value's type. Key is still always a string. Added support for sorting the iteration replies. Added dict_unset(). Added Berkeley DB support. Most of the code written by Tianyan Liu.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
4512
diff
changeset
|
472 dict->value_type = value_type; |
3967
6fabe878c46d
Dictionary takes now a username parameter, which is used for private
Timo Sirainen <tss@iki.fi>
parents:
3879
diff
changeset
|
473 dict->username = p_strdup(pool, username); |
3793 | 474 |
475 dict->fd = -1; | |
476 | |
3967
6fabe878c46d
Dictionary takes now a username parameter, which is used for private
Timo Sirainen <tss@iki.fi>
parents:
3879
diff
changeset
|
477 if (*uri != ':') { |
3793 | 478 /* path given */ |
3967
6fabe878c46d
Dictionary takes now a username parameter, which is used for private
Timo Sirainen <tss@iki.fi>
parents:
3879
diff
changeset
|
479 dict->path = p_strdup_until(pool, uri, dest_uri); |
3793 | 480 } else { |
9174
eed86bcc33aa
dict proxy: Use base_dir as the default dict-server location.
Timo Sirainen <tss@iki.fi>
parents:
8683
diff
changeset
|
481 dict->path = p_strconcat(pool, base_dir, |
eed86bcc33aa
dict proxy: Use base_dir as the default dict-server location.
Timo Sirainen <tss@iki.fi>
parents:
8683
diff
changeset
|
482 "/"DEFAULT_DICT_SERVER_SOCKET_FNAME, NULL); |
3793 | 483 } |
484 dict->uri = p_strdup(pool, dest_uri + 1); | |
485 return &dict->dict; | |
486 } | |
487 | |
488 static void client_dict_deinit(struct dict *_dict) | |
489 { | |
490 struct client_dict *dict = (struct client_dict *)_dict; | |
491 | |
492 client_dict_disconnect(dict); | |
6428
7cad076906eb
pool_unref() now takes ** pointer.
Timo Sirainen <tss@iki.fi>
parents:
6162
diff
changeset
|
493 pool_unref(&dict->pool); |
3793 | 494 } |
495 | |
9361
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
496 static int client_dict_wait(struct dict *_dict) |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
497 { |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
498 struct client_dict *dict = (struct client_dict *)_dict; |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
499 char *line; |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
500 int ret = 0; |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
501 |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
502 while (dict->async_commits > 0) { |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
503 if (client_dict_read_one_line(dict, &line) < 0) { |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
504 ret = -1; |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
505 break; |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
506 } |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
507 } |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
508 return ret; |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
509 } |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
510 |
3793 | 511 static int client_dict_lookup(struct dict *_dict, pool_t pool, |
512 const char *key, const char **value_r) | |
513 { | |
514 struct client_dict *dict = (struct client_dict *)_dict; | |
515 const char *line; | |
6940
414c9d631a81
Replaced t_push/t_pop calls with T_FRAME*() macros.
Timo Sirainen <tss@iki.fi>
parents:
6525
diff
changeset
|
516 int ret; |
3793 | 517 |
7226
e6693a0ec8e1
Renamed T_FRAME_BEGIN/END to T_BEGIN/END. Removed T_FRAME() macro and
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
518 T_BEGIN { |
6940
414c9d631a81
Replaced t_push/t_pop calls with T_FRAME*() macros.
Timo Sirainen <tss@iki.fi>
parents:
6525
diff
changeset
|
519 const char *query; |
414c9d631a81
Replaced t_push/t_pop calls with T_FRAME*() macros.
Timo Sirainen <tss@iki.fi>
parents:
6525
diff
changeset
|
520 |
414c9d631a81
Replaced t_push/t_pop calls with T_FRAME*() macros.
Timo Sirainen <tss@iki.fi>
parents:
6525
diff
changeset
|
521 query = t_strdup_printf("%c%s\n", DICT_PROTOCOL_CMD_LOOKUP, |
414c9d631a81
Replaced t_push/t_pop calls with T_FRAME*() macros.
Timo Sirainen <tss@iki.fi>
parents:
6525
diff
changeset
|
522 dict_client_escape(key)); |
414c9d631a81
Replaced t_push/t_pop calls with T_FRAME*() macros.
Timo Sirainen <tss@iki.fi>
parents:
6525
diff
changeset
|
523 ret = client_dict_send_query(dict, query); |
7226
e6693a0ec8e1
Renamed T_FRAME_BEGIN/END to T_BEGIN/END. Removed T_FRAME() macro and
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
524 } T_END; |
6940
414c9d631a81
Replaced t_push/t_pop calls with T_FRAME*() macros.
Timo Sirainen <tss@iki.fi>
parents:
6525
diff
changeset
|
525 if (ret < 0) |
3793 | 526 return -1; |
527 | |
528 /* read reply */ | |
529 line = client_dict_read_line(dict); | |
530 if (line == NULL) | |
531 return -1; | |
532 | |
533 if (*line == DICT_PROTOCOL_REPLY_OK) { | |
534 *value_r = p_strdup(pool, dict_client_unescape(line + 1)); | |
535 return 1; | |
536 } else { | |
537 *value_r = NULL; | |
538 return *line == DICT_PROTOCOL_REPLY_NOTFOUND ? 0 : -1; | |
539 } | |
540 } | |
541 | |
542 static struct dict_iterate_context * | |
4516
aa2f73a4df26
Dictionary changes: Added support for defining value's type. Key is still always a string. Added support for sorting the iteration replies. Added dict_unset(). Added Berkeley DB support. Most of the code written by Tianyan Liu.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
4512
diff
changeset
|
543 client_dict_iterate_init(struct dict *_dict, const char *path, |
aa2f73a4df26
Dictionary changes: Added support for defining value's type. Key is still always a string. Added support for sorting the iteration replies. Added dict_unset(). Added Berkeley DB support. Most of the code written by Tianyan Liu.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
4512
diff
changeset
|
544 enum dict_iterate_flags flags) |
3793 | 545 { |
546 struct client_dict *dict = (struct client_dict *)_dict; | |
547 struct client_dict_iterate_context *ctx; | |
548 | |
549 if (dict->in_iteration) | |
550 i_panic("dict-client: Only one iteration supported"); | |
551 dict->in_iteration = TRUE; | |
552 | |
553 ctx = i_new(struct client_dict_iterate_context, 1); | |
554 ctx->ctx.dict = _dict; | |
555 ctx->pool = pool_alloconly_create("client dict iteration", 512); | |
556 | |
7226
e6693a0ec8e1
Renamed T_FRAME_BEGIN/END to T_BEGIN/END. Removed T_FRAME() macro and
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
557 T_BEGIN { |
6940
414c9d631a81
Replaced t_push/t_pop calls with T_FRAME*() macros.
Timo Sirainen <tss@iki.fi>
parents:
6525
diff
changeset
|
558 const char *query; |
3793 | 559 |
6940
414c9d631a81
Replaced t_push/t_pop calls with T_FRAME*() macros.
Timo Sirainen <tss@iki.fi>
parents:
6525
diff
changeset
|
560 query = t_strdup_printf("%c%d\t%s\n", DICT_PROTOCOL_CMD_ITERATE, |
414c9d631a81
Replaced t_push/t_pop calls with T_FRAME*() macros.
Timo Sirainen <tss@iki.fi>
parents:
6525
diff
changeset
|
561 flags, dict_client_escape(path)); |
414c9d631a81
Replaced t_push/t_pop calls with T_FRAME*() macros.
Timo Sirainen <tss@iki.fi>
parents:
6525
diff
changeset
|
562 if (client_dict_send_query(dict, query) < 0) |
414c9d631a81
Replaced t_push/t_pop calls with T_FRAME*() macros.
Timo Sirainen <tss@iki.fi>
parents:
6525
diff
changeset
|
563 ctx->failed = TRUE; |
7226
e6693a0ec8e1
Renamed T_FRAME_BEGIN/END to T_BEGIN/END. Removed T_FRAME() macro and
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
564 } T_END; |
3793 | 565 return &ctx->ctx; |
566 } | |
567 | |
568 static int client_dict_iterate(struct dict_iterate_context *_ctx, | |
569 const char **key_r, const char **value_r) | |
570 { | |
571 struct client_dict_iterate_context *ctx = | |
572 (struct client_dict_iterate_context *)_ctx; | |
573 struct client_dict *dict = (struct client_dict *)_ctx->dict; | |
574 char *line, *value; | |
575 | |
576 if (ctx->failed) | |
577 return -1; | |
578 | |
579 /* read next reply */ | |
580 line = client_dict_read_line(dict); | |
581 if (line == NULL) | |
582 return -1; | |
583 | |
584 if (*line == '\0') { | |
585 /* end of iteration */ | |
586 return 0; | |
587 } | |
588 | |
589 /* line contains key \t value */ | |
590 p_clear(ctx->pool); | |
591 | |
9361
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
592 if (*line != DICT_PROTOCOL_REPLY_OK) |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
593 value = NULL; |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
594 else |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
595 value = strchr(++line, '\t'); |
3793 | 596 if (value == NULL) { |
597 /* broken protocol */ | |
598 i_error("dict client (%s) sent broken reply", dict->path); | |
599 return -1; | |
600 } | |
601 *value++ = '\0'; | |
602 | |
603 *key_r = p_strdup(ctx->pool, dict_client_unescape(line)); | |
604 *value_r = p_strdup(ctx->pool, dict_client_unescape(value)); | |
605 return 1; | |
606 } | |
607 | |
608 static void client_dict_iterate_deinit(struct dict_iterate_context *_ctx) | |
609 { | |
610 struct client_dict *dict = (struct client_dict *)_ctx->dict; | |
611 struct client_dict_iterate_context *ctx = | |
612 (struct client_dict_iterate_context *)_ctx; | |
613 | |
6428
7cad076906eb
pool_unref() now takes ** pointer.
Timo Sirainen <tss@iki.fi>
parents:
6162
diff
changeset
|
614 pool_unref(&ctx->pool); |
3793 | 615 i_free(ctx); |
8105
ad9ad222729c
Calling dict_iterate_init() multiple times for a dict assert-crashed.
Timo Sirainen <tss@iki.fi>
parents:
7988
diff
changeset
|
616 dict->in_iteration = FALSE; |
9562
0dca2668004f
dict proxy: Disconnect from dict server after 1 second of idling.
Timo Sirainen <tss@iki.fi>
parents:
9532
diff
changeset
|
617 |
0dca2668004f
dict proxy: Disconnect from dict server after 1 second of idling.
Timo Sirainen <tss@iki.fi>
parents:
9532
diff
changeset
|
618 client_dict_add_timeout(dict); |
3793 | 619 } |
620 | |
621 static struct dict_transaction_context * | |
622 client_dict_transaction_init(struct dict *_dict) | |
623 { | |
624 struct client_dict *dict = (struct client_dict *)_dict; | |
625 struct client_dict_transaction_context *ctx; | |
626 | |
627 ctx = i_new(struct client_dict_transaction_context, 1); | |
628 ctx->ctx.dict = _dict; | |
629 ctx->id = ++dict->transaction_id_counter; | |
4368 | 630 |
9361
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
631 DLLIST_PREPEND(&dict->transactions, ctx); |
3793 | 632 return &ctx->ctx; |
633 } | |
634 | |
9361
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
635 static void dict_async_input(struct client_dict *dict) |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
636 { |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
637 char *line; |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
638 size_t size; |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
639 int ret; |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
640 |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
641 i_assert(!dict->in_iteration); |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
642 |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
643 do { |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
644 ret = client_dict_read_one_line(dict, &line); |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
645 (void)i_stream_get_data(dict->input, &size); |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
646 } while (ret == 0 && size > 0); |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
647 |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
648 if (ret < 0) |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
649 io_remove(&dict->io); |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
650 } |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
651 |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
652 static int |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
653 client_dict_transaction_commit(struct dict_transaction_context *_ctx, |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
654 bool async, |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
655 dict_transaction_commit_callback_t *callback, |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
656 void *context) |
3793 | 657 { |
658 struct client_dict_transaction_context *ctx = | |
659 (struct client_dict_transaction_context *)_ctx; | |
660 struct client_dict *dict = (struct client_dict *)_ctx->dict; | |
9361
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
661 int ret = ctx->failed ? -1 : 1; |
3793 | 662 |
9361
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
663 if (ctx->sent_begin && !ctx->failed) T_BEGIN { |
6940
414c9d631a81
Replaced t_push/t_pop calls with T_FRAME*() macros.
Timo Sirainen <tss@iki.fi>
parents:
6525
diff
changeset
|
664 const char *query, *line; |
414c9d631a81
Replaced t_push/t_pop calls with T_FRAME*() macros.
Timo Sirainen <tss@iki.fi>
parents:
6525
diff
changeset
|
665 |
9361
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
666 query = t_strdup_printf("%c%u\n", !async ? |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
667 DICT_PROTOCOL_CMD_COMMIT : |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
668 DICT_PROTOCOL_CMD_COMMIT_ASYNC, |
8664
446775a31754
dict proxy: Handle async commits better.
Timo Sirainen <tss@iki.fi>
parents:
8660
diff
changeset
|
669 ctx->id); |
4512
b5d4c1e9a492
Delay sending the transaction begin command to server until the first
Timo Sirainen <tss@iki.fi>
parents:
4385
diff
changeset
|
670 if (client_dict_send_transaction_query(ctx, query) < 0) |
3793 | 671 ret = -1; |
9361
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
672 else if (async) { |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
673 ctx->callback = callback; |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
674 ctx->context = context; |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
675 if (dict->async_commits++ == 0) { |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
676 dict->io = io_add(dict->fd, IO_READ, |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
677 dict_async_input, dict); |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
678 } |
8660
d8a56ea9f408
Added dict_transaction_commit_async().
Timo Sirainen <tss@iki.fi>
parents:
8590
diff
changeset
|
679 } else { |
8683
a68ed51b681d
dict proxy client: Don't hang when doing an async commit.
Timo Sirainen <tss@iki.fi>
parents:
8664
diff
changeset
|
680 /* sync commit, read reply */ |
4512
b5d4c1e9a492
Delay sending the transaction begin command to server until the first
Timo Sirainen <tss@iki.fi>
parents:
4385
diff
changeset
|
681 line = client_dict_read_line(dict); |
9361
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
682 if (line == NULL) |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
683 ret = -1; |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
684 else if (*line == DICT_PROTOCOL_REPLY_OK) |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
685 ret = 1; |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
686 else if (*line == DICT_PROTOCOL_REPLY_NOTFOUND) |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
687 ret = 0; |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
688 else |
4512
b5d4c1e9a492
Delay sending the transaction begin command to server until the first
Timo Sirainen <tss@iki.fi>
parents:
4385
diff
changeset
|
689 ret = -1; |
b5d4c1e9a492
Delay sending the transaction begin command to server until the first
Timo Sirainen <tss@iki.fi>
parents:
4385
diff
changeset
|
690 } |
7226
e6693a0ec8e1
Renamed T_FRAME_BEGIN/END to T_BEGIN/END. Removed T_FRAME() macro and
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
691 } T_END; |
3793 | 692 |
9361
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
693 if (ret < 0 || !async) { |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
694 DLLIST_REMOVE(&dict->transactions, ctx); |
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
695 i_free(ctx); |
9562
0dca2668004f
dict proxy: Disconnect from dict server after 1 second of idling.
Timo Sirainen <tss@iki.fi>
parents:
9532
diff
changeset
|
696 |
0dca2668004f
dict proxy: Disconnect from dict server after 1 second of idling.
Timo Sirainen <tss@iki.fi>
parents:
9532
diff
changeset
|
697 client_dict_add_timeout(dict); |
9361
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
698 } |
3793 | 699 return ret; |
700 } | |
701 | |
702 static void | |
703 client_dict_transaction_rollback(struct dict_transaction_context *_ctx) | |
704 { | |
705 struct client_dict_transaction_context *ctx = | |
706 (struct client_dict_transaction_context *)_ctx; | |
9361
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
707 struct client_dict *dict = (struct client_dict *)_ctx->dict; |
3793 | 708 |
7226
e6693a0ec8e1
Renamed T_FRAME_BEGIN/END to T_BEGIN/END. Removed T_FRAME() macro and
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
709 if (ctx->sent_begin) T_BEGIN { |
6940
414c9d631a81
Replaced t_push/t_pop calls with T_FRAME*() macros.
Timo Sirainen <tss@iki.fi>
parents:
6525
diff
changeset
|
710 const char *query; |
414c9d631a81
Replaced t_push/t_pop calls with T_FRAME*() macros.
Timo Sirainen <tss@iki.fi>
parents:
6525
diff
changeset
|
711 |
4512
b5d4c1e9a492
Delay sending the transaction begin command to server until the first
Timo Sirainen <tss@iki.fi>
parents:
4385
diff
changeset
|
712 query = t_strdup_printf("%c%u\n", DICT_PROTOCOL_CMD_ROLLBACK, |
b5d4c1e9a492
Delay sending the transaction begin command to server until the first
Timo Sirainen <tss@iki.fi>
parents:
4385
diff
changeset
|
713 ctx->id); |
b5d4c1e9a492
Delay sending the transaction begin command to server until the first
Timo Sirainen <tss@iki.fi>
parents:
4385
diff
changeset
|
714 (void)client_dict_send_transaction_query(ctx, query); |
7226
e6693a0ec8e1
Renamed T_FRAME_BEGIN/END to T_BEGIN/END. Removed T_FRAME() macro and
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
715 } T_END; |
4385 | 716 |
9361
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
717 DLLIST_REMOVE(&dict->transactions, ctx); |
3793 | 718 i_free(ctx); |
9562
0dca2668004f
dict proxy: Disconnect from dict server after 1 second of idling.
Timo Sirainen <tss@iki.fi>
parents:
9532
diff
changeset
|
719 |
0dca2668004f
dict proxy: Disconnect from dict server after 1 second of idling.
Timo Sirainen <tss@iki.fi>
parents:
9532
diff
changeset
|
720 client_dict_add_timeout(dict); |
3793 | 721 } |
722 | |
723 static void client_dict_set(struct dict_transaction_context *_ctx, | |
724 const char *key, const char *value) | |
725 { | |
726 struct client_dict_transaction_context *ctx = | |
727 (struct client_dict_transaction_context *)_ctx; | |
6940
414c9d631a81
Replaced t_push/t_pop calls with T_FRAME*() macros.
Timo Sirainen <tss@iki.fi>
parents:
6525
diff
changeset
|
728 |
7226
e6693a0ec8e1
Renamed T_FRAME_BEGIN/END to T_BEGIN/END. Removed T_FRAME() macro and
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
729 T_BEGIN { |
6940
414c9d631a81
Replaced t_push/t_pop calls with T_FRAME*() macros.
Timo Sirainen <tss@iki.fi>
parents:
6525
diff
changeset
|
730 const char *query; |
3793 | 731 |
6940
414c9d631a81
Replaced t_push/t_pop calls with T_FRAME*() macros.
Timo Sirainen <tss@iki.fi>
parents:
6525
diff
changeset
|
732 query = t_strdup_printf("%c%u\t%s\t%s\n", |
414c9d631a81
Replaced t_push/t_pop calls with T_FRAME*() macros.
Timo Sirainen <tss@iki.fi>
parents:
6525
diff
changeset
|
733 DICT_PROTOCOL_CMD_SET, ctx->id, |
414c9d631a81
Replaced t_push/t_pop calls with T_FRAME*() macros.
Timo Sirainen <tss@iki.fi>
parents:
6525
diff
changeset
|
734 dict_client_escape(key), |
414c9d631a81
Replaced t_push/t_pop calls with T_FRAME*() macros.
Timo Sirainen <tss@iki.fi>
parents:
6525
diff
changeset
|
735 dict_client_escape(value)); |
414c9d631a81
Replaced t_push/t_pop calls with T_FRAME*() macros.
Timo Sirainen <tss@iki.fi>
parents:
6525
diff
changeset
|
736 (void)client_dict_send_transaction_query(ctx, query); |
7226
e6693a0ec8e1
Renamed T_FRAME_BEGIN/END to T_BEGIN/END. Removed T_FRAME() macro and
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
737 } T_END; |
3793 | 738 } |
739 | |
4516
aa2f73a4df26
Dictionary changes: Added support for defining value's type. Key is still always a string. Added support for sorting the iteration replies. Added dict_unset(). Added Berkeley DB support. Most of the code written by Tianyan Liu.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
4512
diff
changeset
|
740 static void client_dict_unset(struct dict_transaction_context *_ctx, |
aa2f73a4df26
Dictionary changes: Added support for defining value's type. Key is still always a string. Added support for sorting the iteration replies. Added dict_unset(). Added Berkeley DB support. Most of the code written by Tianyan Liu.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
4512
diff
changeset
|
741 const char *key) |
aa2f73a4df26
Dictionary changes: Added support for defining value's type. Key is still always a string. Added support for sorting the iteration replies. Added dict_unset(). Added Berkeley DB support. Most of the code written by Tianyan Liu.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
4512
diff
changeset
|
742 { |
aa2f73a4df26
Dictionary changes: Added support for defining value's type. Key is still always a string. Added support for sorting the iteration replies. Added dict_unset(). Added Berkeley DB support. Most of the code written by Tianyan Liu.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
4512
diff
changeset
|
743 struct client_dict_transaction_context *ctx = |
aa2f73a4df26
Dictionary changes: Added support for defining value's type. Key is still always a string. Added support for sorting the iteration replies. Added dict_unset(). Added Berkeley DB support. Most of the code written by Tianyan Liu.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
4512
diff
changeset
|
744 (struct client_dict_transaction_context *)_ctx; |
6940
414c9d631a81
Replaced t_push/t_pop calls with T_FRAME*() macros.
Timo Sirainen <tss@iki.fi>
parents:
6525
diff
changeset
|
745 |
7226
e6693a0ec8e1
Renamed T_FRAME_BEGIN/END to T_BEGIN/END. Removed T_FRAME() macro and
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
746 T_BEGIN { |
6940
414c9d631a81
Replaced t_push/t_pop calls with T_FRAME*() macros.
Timo Sirainen <tss@iki.fi>
parents:
6525
diff
changeset
|
747 const char *query; |
4516
aa2f73a4df26
Dictionary changes: Added support for defining value's type. Key is still always a string. Added support for sorting the iteration replies. Added dict_unset(). Added Berkeley DB support. Most of the code written by Tianyan Liu.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
4512
diff
changeset
|
748 |
6940
414c9d631a81
Replaced t_push/t_pop calls with T_FRAME*() macros.
Timo Sirainen <tss@iki.fi>
parents:
6525
diff
changeset
|
749 query = t_strdup_printf("%c%u\t%s\n", |
414c9d631a81
Replaced t_push/t_pop calls with T_FRAME*() macros.
Timo Sirainen <tss@iki.fi>
parents:
6525
diff
changeset
|
750 DICT_PROTOCOL_CMD_UNSET, ctx->id, |
414c9d631a81
Replaced t_push/t_pop calls with T_FRAME*() macros.
Timo Sirainen <tss@iki.fi>
parents:
6525
diff
changeset
|
751 dict_client_escape(key)); |
414c9d631a81
Replaced t_push/t_pop calls with T_FRAME*() macros.
Timo Sirainen <tss@iki.fi>
parents:
6525
diff
changeset
|
752 (void)client_dict_send_transaction_query(ctx, query); |
7226
e6693a0ec8e1
Renamed T_FRAME_BEGIN/END to T_BEGIN/END. Removed T_FRAME() macro and
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
753 } T_END; |
4516
aa2f73a4df26
Dictionary changes: Added support for defining value's type. Key is still always a string. Added support for sorting the iteration replies. Added dict_unset(). Added Berkeley DB support. Most of the code written by Tianyan Liu.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
4512
diff
changeset
|
754 } |
aa2f73a4df26
Dictionary changes: Added support for defining value's type. Key is still always a string. Added support for sorting the iteration replies. Added dict_unset(). Added Berkeley DB support. Most of the code written by Tianyan Liu.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
4512
diff
changeset
|
755 |
3793 | 756 static void client_dict_atomic_inc(struct dict_transaction_context *_ctx, |
3990
e2e6919c6c4d
LF wasn't sent at the end of all commands.
Timo Sirainen <tss@iki.fi>
parents:
3967
diff
changeset
|
757 const char *key, long long diff) |
3793 | 758 { |
759 struct client_dict_transaction_context *ctx = | |
760 (struct client_dict_transaction_context *)_ctx; | |
761 | |
7226
e6693a0ec8e1
Renamed T_FRAME_BEGIN/END to T_BEGIN/END. Removed T_FRAME() macro and
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
762 T_BEGIN { |
6940
414c9d631a81
Replaced t_push/t_pop calls with T_FRAME*() macros.
Timo Sirainen <tss@iki.fi>
parents:
6525
diff
changeset
|
763 const char *query; |
414c9d631a81
Replaced t_push/t_pop calls with T_FRAME*() macros.
Timo Sirainen <tss@iki.fi>
parents:
6525
diff
changeset
|
764 query = t_strdup_printf("%c%u\t%s\t%lld\n", |
414c9d631a81
Replaced t_push/t_pop calls with T_FRAME*() macros.
Timo Sirainen <tss@iki.fi>
parents:
6525
diff
changeset
|
765 DICT_PROTOCOL_CMD_ATOMIC_INC, |
414c9d631a81
Replaced t_push/t_pop calls with T_FRAME*() macros.
Timo Sirainen <tss@iki.fi>
parents:
6525
diff
changeset
|
766 ctx->id, dict_client_escape(key), diff); |
414c9d631a81
Replaced t_push/t_pop calls with T_FRAME*() macros.
Timo Sirainen <tss@iki.fi>
parents:
6525
diff
changeset
|
767 (void)client_dict_send_transaction_query(ctx, query); |
7226
e6693a0ec8e1
Renamed T_FRAME_BEGIN/END to T_BEGIN/END. Removed T_FRAME() macro and
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
768 } T_END; |
3793 | 769 } |
770 | |
4517
e661182eab75
Berkeley DB dict support is now enabled only when using --with-db configure option.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
4516
diff
changeset
|
771 struct dict dict_driver_client = { |
3793 | 772 MEMBER(name) "proxy", |
773 | |
774 { | |
775 client_dict_init, | |
776 client_dict_deinit, | |
9361
a1b92a251bb9
dict: Added support for async commits. Changed dict_atomic_inc() behavior.
Timo Sirainen <tss@iki.fi>
parents:
9174
diff
changeset
|
777 client_dict_wait, |
3793 | 778 client_dict_lookup, |
779 client_dict_iterate_init, | |
780 client_dict_iterate, | |
781 client_dict_iterate_deinit, | |
782 client_dict_transaction_init, | |
783 client_dict_transaction_commit, | |
784 client_dict_transaction_rollback, | |
785 client_dict_set, | |
4516
aa2f73a4df26
Dictionary changes: Added support for defining value's type. Key is still always a string. Added support for sorting the iteration replies. Added dict_unset(). Added Berkeley DB support. Most of the code written by Tianyan Liu.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
4512
diff
changeset
|
786 client_dict_unset, |
3793 | 787 client_dict_atomic_inc |
788 } | |
789 }; |