Mercurial > dovecot > core-2.2
changeset 20530:1d5136f4f27c
lib-dict: Added DICT_COMMIT_RET_WRITE_UNCERTAIN
author | Timo Sirainen <timo.sirainen@dovecot.fi> |
---|---|
date | Sat, 16 Jul 2016 11:30:39 -0500 |
parents | 6450eb09e83c |
children | 048ff0f4651d |
files | src/dict/dict-commands.c src/lib-dict/dict-client.c src/lib-dict/dict-client.h src/lib-dict/dict-sql.c src/lib-dict/dict.h |
diffstat | 5 files changed, 46 insertions(+), 14 deletions(-) [+] |
line wrap: on
line diff
--- a/src/dict/dict-commands.c Sun Jul 17 12:37:06 2016 -0600 +++ b/src/dict/dict-commands.c Sat Jul 16 11:30:39 2016 -0500 @@ -296,6 +296,10 @@ case 0: chr = DICT_PROTOCOL_REPLY_NOTFOUND; break; + case DICT_COMMIT_RET_WRITE_UNCERTAIN: + chr = DICT_PROTOCOL_REPLY_WRITE_UNCERTAIN; + break; + case DICT_COMMIT_RET_FAILED: default: chr = DICT_PROTOCOL_REPLY_FAIL; break;
--- a/src/lib-dict/dict-client.c Sun Jul 17 12:37:06 2016 -0600 +++ b/src/lib-dict/dict-client.c Sat Jul 16 11:30:39 2016 -0500 @@ -40,7 +40,8 @@ bool background; void (*callback)(struct client_dict_cmd *cmd, - const char *line, const char *error); + const char *line, const char *error, + bool disconnected); struct client_dict_iterate_context *iter; struct { @@ -168,16 +169,17 @@ dict_cmd_callback_line(struct client_dict_cmd *cmd, const char *line) { cmd->unfinished = FALSE; - cmd->callback(cmd, line, NULL); + cmd->callback(cmd, line, NULL, FALSE); return !cmd->unfinished; } static void -dict_cmd_callback_error(struct client_dict_cmd *cmd, const char *error) +dict_cmd_callback_error(struct client_dict_cmd *cmd, const char *error, + bool disconnected) { cmd->unfinished = FALSE; if (cmd->callback != NULL) - cmd->callback(cmd, NULL, error); + cmd->callback(cmd, NULL, error, disconnected); i_assert(!cmd->unfinished); } @@ -252,7 +254,8 @@ return TRUE; } else if (ret < 0) { i_assert(error != NULL); - dict_cmd_callback_error(cmd, error); + /* we didn't successfully send this command to dict */ + dict_cmd_callback_error(cmd, error, FALSE); client_dict_cmd_unref(cmd); if (error_r != NULL) *error_r = error; @@ -443,7 +446,7 @@ array_clear(&dict->cmds); array_foreach(&cmds_copy, cmdp) { - dict_cmd_callback_error(*cmdp, reason); + dict_cmd_callback_error(*cmdp, reason, TRUE); client_dict_cmd_unref(*cmdp); } } @@ -609,7 +612,7 @@ static void client_dict_lookup_async_callback(struct client_dict_cmd *cmd, const char *line, - const char *error) + const char *error, bool disconnected ATTR_UNUSED) { struct client_dict *dict = cmd->dict; struct dict_lookup_result result; @@ -726,7 +729,7 @@ static void client_dict_iter_async_callback(struct client_dict_cmd *cmd, const char *line, - const char *error) + const char *error, bool disconnected ATTR_UNUSED) { struct client_dict_iterate_context *ctx = cmd->iter; struct client_dict *dict = cmd->dict; @@ -888,7 +891,8 @@ static void client_dict_transaction_commit_callback(struct client_dict_cmd *cmd, - const char *line, const char *error) + const char *line, const char *error, + bool disconnected) { struct client_dict *dict = cmd->dict; int ret = -1; @@ -896,6 +900,8 @@ if (error != NULL) { /* failed */ i_error("dict-client: Commit failed: %s", error); + if (disconnected) + ret = DICT_COMMIT_RET_WRITE_UNCERTAIN; } else switch (*line) { case DICT_PROTOCOL_REPLY_OK: ret = 1; @@ -903,6 +909,9 @@ case DICT_PROTOCOL_REPLY_NOTFOUND: ret = 0; break; + case DICT_PROTOCOL_REPLY_WRITE_UNCERTAIN: + ret = DICT_COMMIT_RET_WRITE_UNCERTAIN; + /* fallthrough */ case DICT_PROTOCOL_REPLY_FAIL: { const char *error = strchr(line+1, '\t');
--- a/src/lib-dict/dict-client.h Sun Jul 17 12:37:06 2016 -0600 +++ b/src/lib-dict/dict-client.h Sat Jul 16 11:30:39 2016 -0500 @@ -32,6 +32,7 @@ DICT_PROTOCOL_REPLY_OK = 'O', /* <value> */ DICT_PROTOCOL_REPLY_NOTFOUND = 'N', DICT_PROTOCOL_REPLY_FAIL = 'F', + DICT_PROTOCOL_REPLY_WRITE_UNCERTAIN = 'W', DICT_PROTOCOL_REPLY_ASYNC_COMMIT = 'A' };
--- a/src/lib-dict/dict-sql.c Sun Jul 17 12:37:06 2016 -0600 +++ b/src/lib-dict/dict-sql.c Sat Jul 16 11:30:39 2016 -0500 @@ -807,16 +807,24 @@ } static void -sql_dict_transaction_commit_callback(const char *error, +sql_dict_transaction_commit_callback(const struct sql_commit_result *sql_result, struct sql_dict_transaction_context *ctx) { int ret; - if (error == NULL) + if (sql_result->error == NULL) ret = sql_dict_transaction_has_nonexistent(ctx) ? 0 : 1; else { - i_error("sql dict: commit failed: %s", error); - ret = -1; + i_error("sql dict: commit failed: %s", sql_result->error); + switch (sql_result->error_type) { + case SQL_RESULT_ERROR_TYPE_UNKNOWN: + default: + ret = DICT_COMMIT_RET_FAILED; + break; + case SQL_RESULT_ERROR_TYPE_WRITE_UNCERTAIN: + ret = DICT_COMMIT_RET_WRITE_UNCERTAIN; + break; + } } if (ctx->async_callback != NULL) @@ -846,7 +854,7 @@ } else if (async) { ctx->async_callback = callback; ctx->async_context = context; - sql_transaction_commit(&ctx->sql_ctx, + sql_transaction_commit2(&ctx->sql_ctx, sql_dict_transaction_commit_callback, ctx); return 1; } else {
--- a/src/lib-dict/dict.h Sun Jul 17 12:37:06 2016 -0600 +++ b/src/lib-dict/dict.h Sat Jul 16 11:30:39 2016 -0500 @@ -44,9 +44,19 @@ const char *error; }; +enum dict_commit_ret { + DICT_COMMIT_RET_OK = 1, + DICT_COMMIT_RET_NOTFOUND = 0, + DICT_COMMIT_RET_FAILED = -1, + /* write may or may not have succeeded (e.g. write timeout or + disconnected from server) */ + DICT_COMMIT_RET_WRITE_UNCERTAIN = -2, +}; + typedef void dict_lookup_callback_t(const struct dict_lookup_result *result, void *context); typedef void dict_iterate_callback_t(void *context); +/* ret = enum dict_commit_ret */ typedef void dict_transaction_commit_callback_t(int ret, void *context); void dict_driver_register(struct dict *driver);