mirror of
https://github.com/haiwen/seafile.git
synced 2025-01-09 04:17:30 +08:00
Merge pull request #2234 from haiwen/refactor-sync-error
Refactor sync error
This commit is contained in:
commit
afe5c026af
@ -335,8 +335,7 @@ seafile_get_clone_tasks (GError **error)
|
||||
task = ptr->data;
|
||||
t = g_object_new (SEAFILE_TYPE_CLONE_TASK,
|
||||
"state", clone_task_state_to_str(task->state),
|
||||
"error_str", clone_task_error_to_str(task->error),
|
||||
"err_detail", task->err_detail,
|
||||
"error_str", task->error,
|
||||
"repo_id", task->repo_id,
|
||||
"repo_name", task->repo_name,
|
||||
"worktree", task->worktree,
|
||||
@ -368,7 +367,6 @@ convert_http_task (HttpTxTask *task)
|
||||
"repo_id", task->repo_id,
|
||||
"state", http_task_state_to_str(task->state),
|
||||
"rt_state", http_task_rt_state_to_str(task->runtime_state),
|
||||
"error_str", http_task_error_str(task->error),
|
||||
NULL);
|
||||
|
||||
if (task->type == HTTP_TASK_TYPE_DOWNLOAD) {
|
||||
@ -427,31 +425,6 @@ seafile_get_download_rate(GError **error)
|
||||
return seaf->sync_mgr->last_recv_bytes;
|
||||
}
|
||||
|
||||
|
||||
GObject *
|
||||
seafile_get_repo_sync_info (const char *repo_id, GError **error)
|
||||
{
|
||||
SyncInfo *info;
|
||||
|
||||
info = seaf_sync_manager_get_sync_info (seaf->sync_mgr, repo_id);
|
||||
if (!info)
|
||||
return NULL;
|
||||
|
||||
SeafileSyncInfo *sinfo;
|
||||
sinfo = g_object_new (SEAFILE_TYPE_SYNC_INFO,
|
||||
"repo_id", info->repo_id,
|
||||
"head_commit", info->head_commit,
|
||||
"deleted_on_relay", info->deleted_on_relay,
|
||||
"need_fetch", info->need_fetch,
|
||||
"need_upload", info->need_upload,
|
||||
"need_merge", info->need_merge,
|
||||
/* "last_sync_time", info->last_sync_time, */
|
||||
NULL);
|
||||
|
||||
return (GObject *)sinfo;
|
||||
}
|
||||
|
||||
|
||||
GObject *
|
||||
seafile_get_repo_sync_task (const char *repo_id, GError **error)
|
||||
{
|
||||
@ -482,44 +455,13 @@ seafile_get_repo_sync_task (const char *repo_id, GError **error)
|
||||
s_task = g_object_new (SEAFILE_TYPE_SYNC_TASK,
|
||||
"force_upload", task->is_manual_sync,
|
||||
"state", sync_state,
|
||||
"error", sync_error_to_str(task->error),
|
||||
"err_detail", task->err_detail,
|
||||
"error", task->error,
|
||||
"repo_id", info->repo_id,
|
||||
NULL);
|
||||
|
||||
return (GObject *)s_task;
|
||||
}
|
||||
|
||||
GList *
|
||||
seafile_get_sync_task_list (GError **error)
|
||||
{
|
||||
GHashTable *sync_info_tbl = seaf->sync_mgr->sync_infos;
|
||||
GHashTableIter iter;
|
||||
SeafileSyncTask *s_task;
|
||||
GList *task_list = NULL;
|
||||
gpointer key, value;
|
||||
|
||||
g_hash_table_iter_init (&iter, sync_info_tbl);
|
||||
while (g_hash_table_iter_next (&iter, &key, &value)) {
|
||||
SyncInfo *info = value;
|
||||
if (!info->in_sync)
|
||||
continue;
|
||||
SyncTask *task = info->current_task;
|
||||
if (!task)
|
||||
continue;
|
||||
s_task = g_object_new (SEAFILE_TYPE_SYNC_TASK,
|
||||
"force_upload", task->is_manual_sync,
|
||||
"state", sync_state_to_str(task->state),
|
||||
"error", sync_error_to_str(task->error),
|
||||
"repo_id", info->repo_id,
|
||||
NULL);
|
||||
task_list = g_list_prepend (task_list, s_task);
|
||||
}
|
||||
|
||||
return task_list;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
seafile_set_repo_property (const char *repo_id,
|
||||
const char *key,
|
||||
|
@ -31,7 +31,8 @@ noinst_HEADERS = \
|
||||
sync-status-tree.h \
|
||||
filelock-mgr.h \
|
||||
set-perm.h \
|
||||
change-set.h
|
||||
change-set.h \
|
||||
seafile-error-impl.h
|
||||
|
||||
if LINUX
|
||||
wt_monitor_src = wt-monitor.c wt-monitor-linux.c wt-monitor-structs.c
|
||||
@ -53,6 +54,7 @@ common_src = \
|
||||
../common/seafile-crypt.c ../common/diff-simple.c $(wt_monitor_src) \
|
||||
clone-mgr.c \
|
||||
seafile-config.c \
|
||||
seafile-error.c \
|
||||
../common/branch-mgr.c ../common/fs-mgr.c \
|
||||
repo-mgr.c ../common/commit-mgr.c \
|
||||
../common/log.c \
|
||||
|
@ -5,7 +5,7 @@
|
||||
#define DEBUG_FLAG SEAFILE_DEBUG_SYNC
|
||||
#include "log.h"
|
||||
|
||||
#include "seafile-error.h"
|
||||
#include "seafile-error-impl.h"
|
||||
#include "seafile-session.h"
|
||||
#include "vc-utils.h"
|
||||
#include "utils.h"
|
||||
@ -47,17 +47,6 @@ static const char *state_str[] = {
|
||||
"merge",
|
||||
};
|
||||
|
||||
static const char *error_str[] = {
|
||||
"ok",
|
||||
"check server",
|
||||
"index",
|
||||
"fetch",
|
||||
"password",
|
||||
"checkout",
|
||||
"merge",
|
||||
"internal",
|
||||
};
|
||||
|
||||
static void
|
||||
mark_clone_done_v2 (SeafRepo *repo, CloneTask *task)
|
||||
{
|
||||
@ -71,7 +60,7 @@ mark_clone_done_v2 (SeafRepo *repo, CloneTask *task)
|
||||
if (!local) {
|
||||
seaf_warning ("Cannot get branch local for repo %s(%.10s).\n",
|
||||
repo->name, repo->id);
|
||||
transition_to_error (task, CLONE_ERROR_INTERNAL);
|
||||
transition_to_error (task, SYNC_ERROR_ID_LOCAL_DATA_CORRUPT);
|
||||
return;
|
||||
}
|
||||
/* Set repo head to mark checkout done. */
|
||||
@ -83,7 +72,7 @@ mark_clone_done_v2 (SeafRepo *repo, CloneTask *task)
|
||||
repo,
|
||||
task->passwd) < 0) {
|
||||
seaf_warning ("[Clone mgr] failed to set passwd for %s.\n", repo->id);
|
||||
transition_to_error (task, CLONE_ERROR_INTERNAL);
|
||||
transition_to_error (task, SYNC_ERROR_ID_GENERAL_ERROR);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -106,7 +95,7 @@ mark_clone_done_v2 (SeafRepo *repo, CloneTask *task)
|
||||
if (seaf_wt_monitor_watch_repo (seaf->wt_monitor,
|
||||
repo->id, repo->worktree) < 0) {
|
||||
seaf_warning ("failed to watch repo %s(%.10s).\n", repo->name, repo->id);
|
||||
transition_to_error (task, CLONE_ERROR_INTERNAL);
|
||||
transition_to_error (task, SYNC_ERROR_ID_GENERAL_ERROR);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -135,7 +124,7 @@ start_clone_v2 (CloneTask *task)
|
||||
g_mkdir_with_parents (task->worktree, 0777) < 0) {
|
||||
seaf_warning ("[clone mgr] Failed to create worktree %s.\n",
|
||||
task->worktree);
|
||||
transition_to_error (task, CLONE_ERROR_FETCH);
|
||||
transition_to_error (task, SYNC_ERROR_ID_WRITE_LOCAL_DATA);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -159,7 +148,7 @@ start_clone_v2 (CloneTask *task)
|
||||
if (add_transfer_task (task, &error) == 0)
|
||||
transition_state (task, CLONE_STATE_FETCH);
|
||||
else
|
||||
transition_to_error (task, CLONE_ERROR_FETCH);
|
||||
transition_to_error (task, SYNC_ERROR_ID_NOT_ENOUGH_MEMORY);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -176,9 +165,7 @@ check_head_commit_done (HttpHeadCommit *result, void *user_data)
|
||||
memcpy (task->server_head_id, result->head_commit, 40);
|
||||
start_clone_v2 (task);
|
||||
} else {
|
||||
transition_to_error (task, CLONE_ERROR_CHECK_SERVER);
|
||||
if (result->error_code != 0)
|
||||
task->err_detail = g_strdup(http_task_error_str(result->error_code));
|
||||
transition_to_error (task, result->error_code);
|
||||
}
|
||||
}
|
||||
|
||||
@ -194,7 +181,7 @@ http_check_head_commit (CloneTask *task)
|
||||
check_head_commit_done,
|
||||
task);
|
||||
if (ret < 0)
|
||||
transition_to_error (task, CLONE_ERROR_CHECK_SERVER);
|
||||
transition_to_error (task, SYNC_ERROR_ID_NOT_ENOUGH_MEMORY);
|
||||
}
|
||||
|
||||
static char *
|
||||
@ -241,9 +228,7 @@ check_http_fileserver_protocol_done (HttpProtocolVersion *result, void *user_dat
|
||||
http_check_head_commit (task);
|
||||
} else {
|
||||
/* Wait for periodic retry. */
|
||||
transition_to_error (task, CLONE_ERROR_CHECK_SERVER);
|
||||
if (result->error_code != 0)
|
||||
task->err_detail = g_strdup(http_task_error_str(result->error_code));
|
||||
transition_to_error (task, result->error_code);
|
||||
}
|
||||
}
|
||||
|
||||
@ -268,13 +253,11 @@ check_http_protocol_done (HttpProtocolVersion *result, void *user_data)
|
||||
TRUE,
|
||||
check_http_fileserver_protocol_done,
|
||||
task) < 0)
|
||||
transition_to_error (task, CLONE_ERROR_CHECK_SERVER);
|
||||
transition_to_error (task, SYNC_ERROR_ID_NOT_ENOUGH_MEMORY);
|
||||
g_free (host_fileserver);
|
||||
} else {
|
||||
/* Wait for periodic retry. */
|
||||
transition_to_error (task, CLONE_ERROR_CHECK_SERVER);
|
||||
if (result->error_code != 0)
|
||||
task->err_detail = g_strdup(http_task_error_str(result->error_code));
|
||||
transition_to_error (task, result->error_code);
|
||||
}
|
||||
}
|
||||
|
||||
@ -286,7 +269,7 @@ check_http_protocol (CloneTask *task)
|
||||
FALSE,
|
||||
check_http_protocol_done,
|
||||
task) < 0) {
|
||||
transition_to_error (task, CLONE_ERROR_CHECK_SERVER);
|
||||
transition_to_error (task, SYNC_ERROR_ID_NOT_ENOUGH_MEMORY);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -317,6 +300,7 @@ clone_task_new (const char *repo_id,
|
||||
task->repo_name = g_strdup(repo_name);
|
||||
if (passwd)
|
||||
task->passwd = g_strdup (passwd);
|
||||
task->error = SYNC_ERROR_ID_NO_ERROR;
|
||||
|
||||
return task;
|
||||
}
|
||||
@ -335,7 +319,6 @@ clone_task_free (CloneTask *task)
|
||||
g_free (task->random_key);
|
||||
g_free (task->server_url);
|
||||
g_free (task->effective_url);
|
||||
g_free (task->err_detail);
|
||||
|
||||
g_free (task);
|
||||
}
|
||||
@ -348,14 +331,6 @@ clone_task_state_to_str (int state)
|
||||
return state_str[state];
|
||||
}
|
||||
|
||||
const char *
|
||||
clone_task_error_to_str (int error)
|
||||
{
|
||||
if (error < 0 || error >= N_CLONE_ERRORS)
|
||||
return NULL;
|
||||
return error_str[error];
|
||||
}
|
||||
|
||||
SeafCloneManager *
|
||||
seaf_clone_manager_new (SeafileSession *session)
|
||||
{
|
||||
@ -521,7 +496,7 @@ restart_task (sqlite3_stmt *stmt, void *data)
|
||||
if (task->server_url) {
|
||||
check_http_protocol (task);
|
||||
} else {
|
||||
transition_to_error (task, CLONE_ERROR_CHECK_SERVER);
|
||||
transition_to_error (task, SYNC_ERROR_ID_GENERAL_ERROR);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
@ -579,10 +554,8 @@ static int check_connect_pulse (void *vmanager)
|
||||
task = value;
|
||||
if (task->state == CLONE_STATE_ERROR &&
|
||||
task->repo_version > 0 &&
|
||||
is_http_task_net_error (task->err_detail)) {
|
||||
g_free (task->err_detail);
|
||||
task->err_detail = NULL;
|
||||
task->error = 0;
|
||||
sync_error_level (task->error) == SYNC_ERROR_LEVEL_NETWORK) {
|
||||
task->error = SYNC_ERROR_ID_NO_ERROR;
|
||||
check_http_protocol (task);
|
||||
}
|
||||
}
|
||||
@ -732,7 +705,7 @@ transition_to_error (CloneTask *task, int error)
|
||||
seaf_message ("Transition clone state for %.8s from [%s] to [error]: %s.\n",
|
||||
task->repo_id,
|
||||
state_str[task->state],
|
||||
error_str[error]);
|
||||
sync_error_id_to_str(error));
|
||||
|
||||
task->state = CLONE_STATE_ERROR;
|
||||
task->error = error;
|
||||
@ -1538,8 +1511,7 @@ on_repo_http_fetched (SeafileSession *seaf,
|
||||
transition_state (task, CLONE_STATE_CANCELED);
|
||||
return;
|
||||
} else if (tx_task->state == HTTP_TASK_STATE_ERROR) {
|
||||
transition_to_error (task, CLONE_ERROR_FETCH);
|
||||
task->err_detail = g_strdup(http_task_error_str(tx_task->error));
|
||||
transition_to_error (task, tx_task->error);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1548,7 +1520,7 @@ on_repo_http_fetched (SeafileSession *seaf,
|
||||
if (repo == NULL) {
|
||||
seaf_warning ("[Clone mgr] cannot find repo %s after fetched.\n",
|
||||
tx_task->repo_id);
|
||||
transition_to_error (task, CLONE_ERROR_INTERNAL);
|
||||
transition_to_error (task, SYNC_ERROR_ID_LOCAL_DATA_CORRUPT);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1578,7 +1550,7 @@ check_folder_perms_done (HttpFolderPerms *result, void *user_data)
|
||||
if (repo == NULL) {
|
||||
seaf_warning ("[Clone mgr] cannot find repo %s after fetched.\n",
|
||||
task->repo_id);
|
||||
transition_to_error (task, CLONE_ERROR_INTERNAL);
|
||||
transition_to_error (task, SYNC_ERROR_ID_LOCAL_DATA_CORRUPT);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1615,7 +1587,7 @@ check_folder_permissions (CloneTask *task)
|
||||
if (repo == NULL) {
|
||||
seaf_warning ("[Clone mgr] cannot find repo %s after fetched.\n",
|
||||
task->repo_id);
|
||||
transition_to_error (task, CLONE_ERROR_INTERNAL);
|
||||
transition_to_error (task, SYNC_ERROR_ID_LOCAL_DATA_CORRUPT);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1638,5 +1610,5 @@ check_folder_permissions (CloneTask *task)
|
||||
requests,
|
||||
check_folder_perms_done,
|
||||
task) < 0)
|
||||
transition_to_error (task, CLONE_ERROR_INTERNAL);
|
||||
transition_to_error (task, SYNC_ERROR_ID_NOT_ENOUGH_MEMORY);
|
||||
}
|
||||
|
@ -28,23 +28,10 @@ enum {
|
||||
N_CLONE_STATES,
|
||||
};
|
||||
|
||||
enum {
|
||||
CLONE_OK,
|
||||
CLONE_ERROR_CHECK_SERVER,
|
||||
CLONE_ERROR_INDEX,
|
||||
CLONE_ERROR_FETCH,
|
||||
CLONE_ERROR_PASSWD,
|
||||
CLONE_ERROR_CHECKOUT,
|
||||
CLONE_ERROR_MERGE,
|
||||
CLONE_ERROR_INTERNAL,
|
||||
N_CLONE_ERRORS,
|
||||
};
|
||||
|
||||
struct _CloneTask {
|
||||
SeafCloneManager *manager;
|
||||
int state;
|
||||
int error;
|
||||
char *err_detail;
|
||||
char repo_id[37];
|
||||
int repo_version;
|
||||
char peer_id[41];
|
||||
@ -77,9 +64,6 @@ struct _CloneTask {
|
||||
const char *
|
||||
clone_task_state_to_str (int state);
|
||||
|
||||
const char *
|
||||
clone_task_error_to_str (int error);
|
||||
|
||||
struct _SeafCloneManager {
|
||||
struct _SeafileSession *seaf;
|
||||
sqlite3 *db;
|
||||
|
@ -27,7 +27,7 @@
|
||||
#include "seafile-session.h"
|
||||
#include "http-tx-mgr.h"
|
||||
|
||||
#include "seafile-error.h"
|
||||
#include "seafile-error-impl.h"
|
||||
#include "utils.h"
|
||||
#include "diff-simple.h"
|
||||
|
||||
@ -130,6 +130,8 @@ http_tx_task_new (HttpTxManager *mgr,
|
||||
if (worktree)
|
||||
task->worktree = g_strdup(worktree);
|
||||
|
||||
task->error = SYNC_ERROR_ID_NO_ERROR;
|
||||
|
||||
return task;
|
||||
}
|
||||
|
||||
@ -141,10 +143,9 @@ http_tx_task_free (HttpTxTask *task)
|
||||
g_free (task->passwd);
|
||||
g_free (task->worktree);
|
||||
g_free (task->email);
|
||||
g_free (task->repo_name);
|
||||
if (task->type == HTTP_TASK_TYPE_DOWNLOAD) {
|
||||
g_hash_table_destroy (task->blk_ref_cnts);
|
||||
cevent_manager_unregister (seaf->ev_mgr, task->cevent_id);
|
||||
g_free (task->repo_name);
|
||||
}
|
||||
g_free (task);
|
||||
}
|
||||
@ -166,32 +167,6 @@ static const char *http_task_rt_state_str[] = {
|
||||
"finished",
|
||||
};
|
||||
|
||||
static const char *http_task_error_strs[] = {
|
||||
"Successful",
|
||||
"Permission denied on server",
|
||||
"Do not have write permission to the library",
|
||||
"Do not have permission to sync the library",
|
||||
"Network error",
|
||||
"Cannot resolve proxy address",
|
||||
"Cannot resolve server address",
|
||||
"Cannot connect to server",
|
||||
"Failed to establish secure connection",
|
||||
"Data transfer was interrupted",
|
||||
"Data transfer timed out",
|
||||
"Unhandled http redirect from server",
|
||||
"Server error",
|
||||
"Bad request",
|
||||
"Internal data corrupt on the client",
|
||||
"Not enough memory",
|
||||
"Failed to write data on the client",
|
||||
"Storage quota full",
|
||||
"Files are locked by other application",
|
||||
"Library deleted on server",
|
||||
"Library damaged on server",
|
||||
"File is locked by another user on server",
|
||||
"Unknown error",
|
||||
};
|
||||
|
||||
/* Http connection and connection pool. */
|
||||
|
||||
static Connection *
|
||||
@ -1100,21 +1075,22 @@ static int
|
||||
http_error_to_http_task_error (int status)
|
||||
{
|
||||
if (status == HTTP_BAD_REQUEST)
|
||||
return HTTP_TASK_ERR_BAD_REQUEST;
|
||||
/* This is usually a bug in the client. Set to general error. */
|
||||
return SYNC_ERROR_ID_GENERAL_ERROR;
|
||||
else if (status == HTTP_FORBIDDEN)
|
||||
return HTTP_TASK_ERR_FORBIDDEN;
|
||||
return SYNC_ERROR_ID_ACCESS_DENIED;
|
||||
else if (status >= HTTP_INTERNAL_SERVER_ERROR)
|
||||
return HTTP_TASK_ERR_SERVER;
|
||||
return SYNC_ERROR_ID_SERVER;
|
||||
else if (status == HTTP_NOT_FOUND)
|
||||
return HTTP_TASK_ERR_SERVER;
|
||||
return SYNC_ERROR_ID_SERVER;
|
||||
else if (status == HTTP_NO_QUOTA)
|
||||
return HTTP_TASK_ERR_NO_QUOTA;
|
||||
return SYNC_ERROR_ID_QUOTA_FULL;
|
||||
else if (status == HTTP_REPO_DELETED)
|
||||
return HTTP_TASK_ERR_REPO_DELETED;
|
||||
return SYNC_ERROR_ID_SERVER_REPO_DELETED;
|
||||
else if (status == HTTP_REPO_CORRUPTED)
|
||||
return HTTP_TASK_ERR_REPO_CORRUPTED;
|
||||
return SYNC_ERROR_ID_SERVER_REPO_CORRUPT;
|
||||
else
|
||||
return HTTP_TASK_ERR_UNKNOWN;
|
||||
return SYNC_ERROR_ID_GENERAL_ERROR;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1128,30 +1104,30 @@ curl_error_to_http_task_error (int curl_error)
|
||||
{
|
||||
if (curl_error == CURLE_SSL_CACERT ||
|
||||
curl_error == CURLE_PEER_FAILED_VERIFICATION)
|
||||
return HTTP_TASK_ERR_SSL;
|
||||
return SYNC_ERROR_ID_SSL;
|
||||
|
||||
switch (curl_error) {
|
||||
case CURLE_COULDNT_RESOLVE_PROXY:
|
||||
return HTTP_TASK_ERR_RESOLVE_PROXY;
|
||||
return SYNC_ERROR_ID_RESOLVE_PROXY;
|
||||
case CURLE_COULDNT_RESOLVE_HOST:
|
||||
return HTTP_TASK_ERR_RESOLVE_HOST;
|
||||
return SYNC_ERROR_ID_RESOLVE_HOST;
|
||||
case CURLE_COULDNT_CONNECT:
|
||||
return HTTP_TASK_ERR_CONNECT;
|
||||
return SYNC_ERROR_ID_CONNECT;
|
||||
case CURLE_OPERATION_TIMEDOUT:
|
||||
return HTTP_TASK_ERR_TX_TIMEOUT;
|
||||
return SYNC_ERROR_ID_TX_TIMEOUT;
|
||||
case CURLE_SSL_CONNECT_ERROR:
|
||||
case CURLE_SSL_CERTPROBLEM:
|
||||
case CURLE_SSL_CACERT_BADFILE:
|
||||
case CURLE_SSL_ISSUER_ERROR:
|
||||
return HTTP_TASK_ERR_SSL;
|
||||
return SYNC_ERROR_ID_SSL;
|
||||
case CURLE_GOT_NOTHING:
|
||||
case CURLE_SEND_ERROR:
|
||||
case CURLE_RECV_ERROR:
|
||||
return HTTP_TASK_ERR_TX;
|
||||
return SYNC_ERROR_ID_TX;
|
||||
case CURLE_SEND_FAIL_REWIND:
|
||||
return HTTP_TASK_ERR_UNHANDLED_REDIRECT;
|
||||
return SYNC_ERROR_ID_UNHANDLED_REDIRECT;
|
||||
default:
|
||||
return HTTP_TASK_ERR_NET;
|
||||
return SYNC_ERROR_ID_NETWORK;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2387,15 +2363,6 @@ clean_tasks_for_repo (HttpTxManager *manager, const char *repo_id)
|
||||
remove_task_help, (gpointer)repo_id);
|
||||
}
|
||||
|
||||
static void
|
||||
notify_sync_perm_error (HttpTxTask *task, const char *unsyncable_path)
|
||||
{
|
||||
|
||||
send_file_sync_error_notification (task->repo_id, task->repo_name,
|
||||
unsyncable_path, SYNC_ERROR_ID_PERM_NOT_SYNCABLE);
|
||||
|
||||
}
|
||||
|
||||
static int
|
||||
check_permission (HttpTxTask *task, Connection *conn)
|
||||
{
|
||||
@ -2462,9 +2429,9 @@ check_permission (HttpTxTask *task, Connection *conn)
|
||||
|
||||
reason_str = json_string_value (reason);
|
||||
if (g_strcmp0 (reason_str, "no write permission") == 0) {
|
||||
task->error = HTTP_TASK_ERR_NO_WRITE_PERMISSION;
|
||||
task->error = SYNC_ERROR_ID_NO_WRITE_PERMISSION;
|
||||
} else if (g_strcmp0 (reason_str, "unsyncable share permission") == 0) {
|
||||
task->error = HTTP_TASK_ERR_NO_PERMISSION_TO_SYNC;
|
||||
task->error = SYNC_ERROR_ID_PERM_NOT_SYNCABLE;
|
||||
|
||||
unsyncable_path = json_object_get (rsp_obj, "unsyncable_path");
|
||||
if (!unsyncable_path) {
|
||||
@ -2475,9 +2442,11 @@ check_permission (HttpTxTask *task, Connection *conn)
|
||||
|
||||
unsyncable_path_str = json_string_value (unsyncable_path);
|
||||
if (unsyncable_path_str)
|
||||
notify_sync_perm_error (task, unsyncable_path_str);
|
||||
seaf_repo_manager_record_sync_error (task->repo_id, task->repo_name,
|
||||
unsyncable_path_str,
|
||||
SYNC_ERROR_ID_PERM_NOT_SYNCABLE);
|
||||
} else {
|
||||
task->error = HTTP_TASK_ERR_FORBIDDEN;
|
||||
task->error = SYNC_ERROR_ID_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
ret = -1;
|
||||
@ -2532,6 +2501,8 @@ http_tx_manager_add_upload (HttpTxManager *manager,
|
||||
|
||||
task->use_fileserver_port = use_fileserver_port;
|
||||
|
||||
task->repo_name = g_strdup(repo->name);
|
||||
|
||||
g_hash_table_insert (manager->priv->upload_tasks,
|
||||
g_strdup(repo_id),
|
||||
task);
|
||||
@ -2739,7 +2710,7 @@ send_commit_object (HttpTxTask *task, Connection *conn)
|
||||
task->repo_id, task->repo_version,
|
||||
task->head, (void**)&data, &len) < 0) {
|
||||
seaf_warning ("Failed to read commit %s.\n", task->head);
|
||||
task->error = HTTP_TASK_ERR_BAD_LOCAL_DATA;
|
||||
task->error = SYNC_ERROR_ID_LOCAL_DATA_CORRUPT;
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -2970,7 +2941,7 @@ upload_check_id_list_segment (HttpTxTask *task, Connection *conn, const char *ur
|
||||
array = json_loadb (rsp_content, rsp_size, 0, &jerror);
|
||||
if (!array) {
|
||||
seaf_warning ("Invalid JSON response from the server: %s.\n", jerror.text);
|
||||
task->error = HTTP_TASK_ERR_SERVER;
|
||||
task->error = SYNC_ERROR_ID_SERVER;
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
@ -3039,7 +3010,7 @@ send_fs_objects (HttpTxTask *task, Connection *conn, GList **send_fs_list)
|
||||
obj_id, (void **)&data, &len) < 0) {
|
||||
seaf_warning ("Failed to read fs object %s in repo %s.\n",
|
||||
obj_id, task->repo_id);
|
||||
task->error = HTTP_TASK_ERR_BAD_LOCAL_DATA;
|
||||
task->error = SYNC_ERROR_ID_LOCAL_DATA_CORRUPT;
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
@ -3287,7 +3258,7 @@ send_block_callback (void *ptr, size_t size, size_t nmemb, void *userp)
|
||||
if (n < 0) {
|
||||
seaf_warning ("Failed to read block %s in repo %.8s.\n",
|
||||
data->block_id, task->repo_id);
|
||||
task->error = HTTP_TASK_ERR_BAD_LOCAL_DATA;
|
||||
task->error = SYNC_ERROR_ID_LOCAL_DATA_CORRUPT;
|
||||
return CURL_READFUNC_ABORT;
|
||||
}
|
||||
|
||||
@ -3331,7 +3302,7 @@ send_block (HttpTxTask *task, Connection *conn, const char *block_id, guint32 *p
|
||||
if (!bmd) {
|
||||
seaf_warning ("Failed to stat block %s in repo %s.\n",
|
||||
block_id, task->repo_id);
|
||||
task->error = HTTP_TASK_ERR_BAD_LOCAL_DATA;
|
||||
task->error = SYNC_ERROR_ID_LOCAL_DATA_CORRUPT;
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -3341,7 +3312,7 @@ send_block (HttpTxTask *task, Connection *conn, const char *block_id, guint32 *p
|
||||
if (!block) {
|
||||
seaf_warning ("Failed to open block %s in repo %s.\n",
|
||||
block_id, task->repo_id);
|
||||
task->error = HTTP_TASK_ERR_BAD_LOCAL_DATA;
|
||||
task->error = SYNC_ERROR_ID_LOCAL_DATA_CORRUPT;
|
||||
g_free (bmd);
|
||||
return -1;
|
||||
}
|
||||
@ -3369,7 +3340,7 @@ send_block (HttpTxTask *task, Connection *conn, const char *block_id, guint32 *p
|
||||
if (task->state == HTTP_TASK_STATE_CANCELED)
|
||||
goto out;
|
||||
|
||||
if (task->error == HTTP_TASK_OK) {
|
||||
if (task->error == SYNC_ERROR_ID_NO_ERROR) {
|
||||
/* Only release connection when it's a network error */
|
||||
conn->release = TRUE;
|
||||
handle_curl_errors (task, curl_error);
|
||||
@ -3428,7 +3399,7 @@ upload_block_thread_func (gpointer data, gpointer user_data)
|
||||
conn = connection_pool_get_connection (tx_data->cpool);
|
||||
if (!conn) {
|
||||
seaf_warning ("Failed to get connection to host %s.\n", http_task->host);
|
||||
http_task->error = HTTP_TASK_ERR_NOT_ENOUGH_MEMORY;
|
||||
http_task->error = SYNC_ERROR_ID_NOT_ENOUGH_MEMORY;
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
@ -3464,7 +3435,7 @@ multi_threaded_send_blocks (HttpTxTask *http_task, GList *block_list)
|
||||
cpool = find_connection_pool (priv, http_task->host);
|
||||
if (!cpool) {
|
||||
seaf_warning ("Failed to create connection pool for host %s.\n", http_task->host);
|
||||
http_task->error = HTTP_TASK_ERR_NOT_ENOUGH_MEMORY;
|
||||
http_task->error = SYNC_ERROR_ID_NOT_ENOUGH_MEMORY;
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -3534,19 +3505,21 @@ notify_permission_error (HttpTxTask *task, const char *error_str)
|
||||
|
||||
if (g_regex_match (priv->locked_error_regex, error_str, 0, &match_info)) {
|
||||
path = g_match_info_fetch (match_info, 1);
|
||||
send_file_sync_error_notification (task->repo_id, task->repo_name, path,
|
||||
seaf_repo_manager_record_sync_error (task->repo_id, task->repo_name, path,
|
||||
SYNC_ERROR_ID_FILE_LOCKED);
|
||||
g_free (path);
|
||||
|
||||
/* Set more accurate error. */
|
||||
task->error = HTTP_TASK_ERR_FILE_LOCKED_ON_SERVER;
|
||||
task->error = SYNC_ERROR_ID_FILE_LOCKED;
|
||||
} else if (g_regex_match (priv->folder_perm_error_regex, error_str, 0, &match_info)) {
|
||||
path = g_match_info_fetch (match_info, 1);
|
||||
/* The path returned by server begins with '/'. */
|
||||
send_file_sync_error_notification (task->repo_id, task->repo_name,
|
||||
seaf_repo_manager_record_sync_error (task->repo_id, task->repo_name,
|
||||
(path[0] == '/') ? (path + 1) : path,
|
||||
SYNC_ERROR_ID_FOLDER_PERM_DENIED);
|
||||
g_free (path);
|
||||
|
||||
task->error = SYNC_ERROR_ID_FOLDER_PERM_DENIED;
|
||||
}
|
||||
|
||||
g_match_info_free (match_info);
|
||||
@ -3666,7 +3639,7 @@ http_upload_thread (void *vdata)
|
||||
task->repo_id, "local");
|
||||
if (!local) {
|
||||
seaf_warning ("Failed to get branch local of repo %.8s.\n", task->repo_id);
|
||||
task->error = HTTP_TASK_ERR_BAD_LOCAL_DATA;
|
||||
task->error = SYNC_ERROR_ID_LOCAL_DATA_CORRUPT;
|
||||
return NULL;
|
||||
}
|
||||
memcpy (task->head, local->commit_id, 40);
|
||||
@ -3675,14 +3648,14 @@ http_upload_thread (void *vdata)
|
||||
pool = find_connection_pool (priv, task->host);
|
||||
if (!pool) {
|
||||
seaf_warning ("Failed to create connection pool for host %s.\n", task->host);
|
||||
task->error = HTTP_TASK_ERR_NOT_ENOUGH_MEMORY;
|
||||
task->error = SYNC_ERROR_ID_NOT_ENOUGH_MEMORY;
|
||||
goto out;
|
||||
}
|
||||
|
||||
conn = connection_pool_get_connection (pool);
|
||||
if (!conn) {
|
||||
seaf_warning ("Failed to get connection to host %s.\n", task->host);
|
||||
task->error = HTTP_TASK_ERR_NOT_ENOUGH_MEMORY;
|
||||
task->error = SYNC_ERROR_ID_NOT_ENOUGH_MEMORY;
|
||||
goto out;
|
||||
}
|
||||
|
||||
@ -3697,7 +3670,7 @@ http_upload_thread (void *vdata)
|
||||
if (calculate_upload_size_delta_and_active_paths (task, &delta, active_paths) < 0) {
|
||||
seaf_warning ("Failed to calculate upload size delta for repo %s.\n",
|
||||
task->repo_id);
|
||||
task->error = HTTP_TASK_ERR_BAD_LOCAL_DATA;
|
||||
task->error = SYNC_ERROR_ID_LOCAL_DATA_CORRUPT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
@ -3734,7 +3707,7 @@ http_upload_thread (void *vdata)
|
||||
if (!send_fs_list) {
|
||||
seaf_warning ("Failed to calculate fs object list for repo %.8s.\n",
|
||||
task->repo_id);
|
||||
task->error = HTTP_TASK_ERR_BAD_LOCAL_DATA;
|
||||
task->error = SYNC_ERROR_ID_LOCAL_DATA_CORRUPT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
@ -3773,7 +3746,7 @@ http_upload_thread (void *vdata)
|
||||
if (calculate_block_list (task, &block_list) < 0) {
|
||||
seaf_warning ("Failed to calculate block list for repo %.8s.\n",
|
||||
task->repo_id);
|
||||
task->error = HTTP_TASK_ERR_BAD_LOCAL_DATA;
|
||||
task->error = SYNC_ERROR_ID_LOCAL_DATA_CORRUPT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
@ -3843,7 +3816,7 @@ http_upload_done (void *vdata)
|
||||
{
|
||||
HttpTxTask *task = vdata;
|
||||
|
||||
if (task->error != HTTP_TASK_OK)
|
||||
if (task->error != SYNC_ERROR_ID_NO_ERROR)
|
||||
transition_state (task, HTTP_TASK_STATE_ERROR, HTTP_TASK_RT_STATE_FINISHED);
|
||||
else if (task->state == HTTP_TASK_STATE_CANCELED)
|
||||
transition_state (task, task->state, HTTP_TASK_RT_STATE_FINISHED);
|
||||
@ -3855,7 +3828,6 @@ http_upload_done (void *vdata)
|
||||
|
||||
static void *http_download_thread (void *vdata);
|
||||
static void http_download_done (void *vdata);
|
||||
static void notify_conflict (CEvent *event, void *data);
|
||||
|
||||
int
|
||||
http_tx_manager_add_download (HttpTxManager *manager,
|
||||
@ -3911,9 +3883,6 @@ http_tx_manager_add_download (HttpTxManager *manager,
|
||||
g_strdup(repo_id),
|
||||
task);
|
||||
|
||||
task->cevent_id = cevent_manager_register (seaf->ev_mgr,
|
||||
(cevent_handler)notify_conflict,
|
||||
NULL);
|
||||
task->repo_name = g_strdup(repo_name);
|
||||
|
||||
if (seaf_job_manager_schedule_job (seaf->job_mgr,
|
||||
@ -3972,7 +3941,7 @@ get_commit_object (HttpTxTask *task, Connection *conn)
|
||||
if (rc < 0) {
|
||||
seaf_warning ("Failed to save commit %s in repo %.8s.\n",
|
||||
task->head, task->repo_id);
|
||||
task->error = HTTP_TASK_ERR_WRITE_LOCAL_DATA;
|
||||
task->error = SYNC_ERROR_ID_WRITE_LOCAL_DATA;
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
@ -4043,7 +4012,7 @@ get_needed_fs_id_list (HttpTxTask *task, Connection *conn, GList **fs_id_list)
|
||||
array = json_loadb (rsp_content, rsp_size, 0, &jerror);
|
||||
if (!array) {
|
||||
seaf_warning ("Invalid JSON response from the server: %s.\n", jerror.text);
|
||||
task->error = HTTP_TASK_ERR_SERVER;
|
||||
task->error = SYNC_ERROR_ID_SERVER;
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
@ -4195,7 +4164,7 @@ get_fs_objects (HttpTxTask *task, Connection *conn, GList **fs_list)
|
||||
if (n + sizeof(ObjectHeader) + size > rsp_size) {
|
||||
seaf_warning ("Incomplete object package received for repo %.8s.\n",
|
||||
task->repo_id);
|
||||
task->error = HTTP_TASK_ERR_SERVER;
|
||||
task->error = SYNC_ERROR_ID_SERVER;
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
@ -4210,7 +4179,7 @@ get_fs_objects (HttpTxTask *task, Connection *conn, GList **fs_list)
|
||||
if (rc < 0) {
|
||||
seaf_warning ("Failed to write fs object %s in repo %.8s.\n",
|
||||
recv_obj_id, task->repo_id);
|
||||
task->error = HTTP_TASK_ERR_WRITE_LOCAL_DATA;
|
||||
task->error = SYNC_ERROR_ID_WRITE_LOCAL_DATA;
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
@ -4271,7 +4240,7 @@ get_block_callback (void *ptr, size_t size, size_t nmemb, void *userp)
|
||||
if (n < realsize) {
|
||||
seaf_warning ("Failed to write block %s in repo %.8s.\n",
|
||||
data->block_id, task->repo_id);
|
||||
task->error = HTTP_TASK_ERR_WRITE_LOCAL_DATA;
|
||||
task->error = SYNC_ERROR_ID_WRITE_LOCAL_DATA;
|
||||
return n;
|
||||
}
|
||||
|
||||
@ -4338,7 +4307,7 @@ get_block (HttpTxTask *task, Connection *conn, const char *block_id)
|
||||
if (task->state == HTTP_TASK_STATE_CANCELED)
|
||||
goto error;
|
||||
|
||||
if (task->error == HTTP_TASK_OK) {
|
||||
if (task->error == SYNC_ERROR_ID_NO_ERROR) {
|
||||
/* Only release the connection when it's a network error. */
|
||||
conn->release = TRUE;
|
||||
handle_curl_errors (task, curl_error);
|
||||
@ -4378,7 +4347,7 @@ get_block (HttpTxTask *task, Connection *conn, const char *block_id)
|
||||
{
|
||||
seaf_warning ("Failed to commit block %s in repo %.8s.\n",
|
||||
block_id, task->repo_id);
|
||||
task->error = HTTP_TASK_ERR_WRITE_LOCAL_DATA;
|
||||
task->error = SYNC_ERROR_ID_WRITE_LOCAL_DATA;
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
@ -4430,7 +4399,7 @@ http_tx_task_download_file_blocks (HttpTxTask *task, const char *file_id)
|
||||
pool = find_connection_pool (priv, task->host);
|
||||
if (!pool) {
|
||||
seaf_warning ("Failed to create connection pool for host %s.\n", task->host);
|
||||
task->error = HTTP_TASK_ERR_NOT_ENOUGH_MEMORY;
|
||||
task->error = SYNC_ERROR_ID_NOT_ENOUGH_MEMORY;
|
||||
seafile_unref (file);
|
||||
return -1;
|
||||
}
|
||||
@ -4438,7 +4407,7 @@ http_tx_task_download_file_blocks (HttpTxTask *task, const char *file_id)
|
||||
conn = connection_pool_get_connection (pool);
|
||||
if (!conn) {
|
||||
seaf_warning ("Failed to get connection to host %s.\n", task->host);
|
||||
task->error = HTTP_TASK_ERR_NOT_ENOUGH_MEMORY;
|
||||
task->error = SYNC_ERROR_ID_NOT_ENOUGH_MEMORY;
|
||||
seafile_unref (file);
|
||||
return -1;
|
||||
}
|
||||
@ -4473,7 +4442,7 @@ update_local_repo (HttpTxTask *task)
|
||||
task->head);
|
||||
if (!new_head) {
|
||||
seaf_warning ("Failed to get commit %s:%s.\n", task->repo_id, task->head);
|
||||
task->error = HTTP_TASK_ERR_BAD_LOCAL_DATA;
|
||||
task->error = SYNC_ERROR_ID_LOCAL_DATA_CORRUPT;
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -4488,7 +4457,7 @@ update_local_repo (HttpTxTask *task)
|
||||
repo = seaf_repo_new (new_head->repo_id, NULL, NULL);
|
||||
if (repo == NULL) {
|
||||
/* create repo failed */
|
||||
task->error = HTTP_TASK_ERR_NOT_ENOUGH_MEMORY;
|
||||
task->error = SYNC_ERROR_ID_NOT_ENOUGH_MEMORY;
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
@ -4507,7 +4476,7 @@ update_local_repo (HttpTxTask *task)
|
||||
seaf_branch_unref (branch);
|
||||
} else {
|
||||
if (!repo) {
|
||||
task->error = HTTP_TASK_ERR_BAD_LOCAL_DATA;
|
||||
task->error = SYNC_ERROR_ID_LOCAL_DATA_CORRUPT;
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
@ -4517,7 +4486,7 @@ update_local_repo (HttpTxTask *task)
|
||||
"master");
|
||||
if (!branch) {
|
||||
seaf_warning ("Branch master not found for repo %.8s.\n", task->repo_id);
|
||||
task->error = HTTP_TASK_ERR_BAD_LOCAL_DATA;
|
||||
task->error = SYNC_ERROR_ID_LOCAL_DATA_CORRUPT;
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
@ -4550,14 +4519,14 @@ http_download_thread (void *vdata)
|
||||
pool = find_connection_pool (priv, task->host);
|
||||
if (!pool) {
|
||||
seaf_warning ("Failed to create connection pool for host %s.\n", task->host);
|
||||
task->error = HTTP_TASK_ERR_NOT_ENOUGH_MEMORY;
|
||||
task->error = SYNC_ERROR_ID_NOT_ENOUGH_MEMORY;
|
||||
goto out;
|
||||
}
|
||||
|
||||
conn = connection_pool_get_connection (pool);
|
||||
if (!conn) {
|
||||
seaf_warning ("Failed to get connection to host %s.\n", task->host);
|
||||
task->error = HTTP_TASK_ERR_NOT_ENOUGH_MEMORY;
|
||||
task->error = SYNC_ERROR_ID_NOT_ENOUGH_MEMORY;
|
||||
goto out;
|
||||
}
|
||||
|
||||
@ -4625,12 +4594,12 @@ http_download_thread (void *vdata)
|
||||
case FETCH_CHECKOUT_CANCELED:
|
||||
goto out;
|
||||
case FETCH_CHECKOUT_FAILED:
|
||||
task->error = HTTP_TASK_ERR_WRITE_LOCAL_DATA;
|
||||
task->error = SYNC_ERROR_ID_WRITE_LOCAL_DATA;
|
||||
goto out;
|
||||
case FETCH_CHECKOUT_TRANSFER_ERROR:
|
||||
goto out;
|
||||
case FETCH_CHECKOUT_LOCKED:
|
||||
task->error = HTTP_TASK_ERR_FILES_LOCKED;
|
||||
task->error = SYNC_ERROR_ID_FILE_LOCKED_BY_APP;
|
||||
goto out;
|
||||
}
|
||||
|
||||
@ -4647,7 +4616,7 @@ http_download_done (void *vdata)
|
||||
{
|
||||
HttpTxTask *task = vdata;
|
||||
|
||||
if (task->error != HTTP_TASK_OK)
|
||||
if (task->error != SYNC_ERROR_ID_NO_ERROR)
|
||||
transition_state (task, HTTP_TASK_STATE_ERROR, HTTP_TASK_RT_STATE_FINISHED);
|
||||
else if (task->state == HTTP_TASK_STATE_CANCELED)
|
||||
transition_state (task, task->state, HTTP_TASK_RT_STATE_FINISHED);
|
||||
@ -4655,49 +4624,6 @@ http_download_done (void *vdata)
|
||||
transition_state (task, HTTP_TASK_STATE_FINISHED, HTTP_TASK_RT_STATE_FINISHED);
|
||||
}
|
||||
|
||||
typedef struct FileConflictData {
|
||||
char *repo_id;
|
||||
char *repo_name;
|
||||
char *path;
|
||||
} FileConflictData;
|
||||
|
||||
static void
|
||||
notify_conflict (CEvent *event, void *handler_data)
|
||||
{
|
||||
FileConflictData *data = event->data;
|
||||
json_t *object;
|
||||
char *str;
|
||||
|
||||
object = json_object ();
|
||||
json_object_set_new (object, "repo_id", json_string(data->repo_id));
|
||||
json_object_set_new (object, "repo_name", json_string(data->repo_name));
|
||||
json_object_set_new (object, "path", json_string(data->path));
|
||||
|
||||
str = json_dumps (object, 0);
|
||||
|
||||
seaf_mq_manager_publish_notification (seaf->mq_mgr,
|
||||
"sync.conflict",
|
||||
str);
|
||||
|
||||
free (str);
|
||||
json_decref (object);
|
||||
g_free (data->repo_id);
|
||||
g_free (data->repo_name);
|
||||
g_free (data->path);
|
||||
g_free (data);
|
||||
}
|
||||
|
||||
void
|
||||
http_tx_manager_notify_conflict (HttpTxTask *task, const char *path)
|
||||
{
|
||||
FileConflictData *data = g_new0 (FileConflictData, 1);
|
||||
data->repo_id = g_strdup(task->repo_id);
|
||||
data->repo_name = g_strdup(task->repo_name);
|
||||
data->path = g_strdup(path);
|
||||
|
||||
cevent_manager_add_event (seaf->ev_mgr, task->cevent_id, data);
|
||||
}
|
||||
|
||||
GList*
|
||||
http_tx_manager_get_upload_tasks (HttpTxManager *manager)
|
||||
{
|
||||
@ -4775,28 +4701,3 @@ http_task_rt_state_to_str (int rt_state)
|
||||
|
||||
return http_task_rt_state_str[rt_state];
|
||||
}
|
||||
|
||||
const char *
|
||||
http_task_error_str (int task_errno)
|
||||
{
|
||||
if (task_errno < 0 || task_errno >= N_HTTP_TASK_ERROR)
|
||||
return "unknown error";
|
||||
|
||||
return http_task_error_strs[task_errno];
|
||||
}
|
||||
|
||||
gboolean
|
||||
is_http_task_net_error (char *err_detail)
|
||||
{
|
||||
if (err_detail &&
|
||||
(strcmp (err_detail, http_task_error_strs[HTTP_TASK_ERR_NET]) == 0 ||
|
||||
strcmp (err_detail, http_task_error_strs[HTTP_TASK_ERR_RESOLVE_PROXY]) == 0 ||
|
||||
strcmp (err_detail, http_task_error_strs[HTTP_TASK_ERR_RESOLVE_HOST]) == 0 ||
|
||||
strcmp (err_detail, http_task_error_strs[HTTP_TASK_ERR_CONNECT]) == 0 ||
|
||||
strcmp (err_detail, http_task_error_strs[HTTP_TASK_ERR_SSL]) == 0 ||
|
||||
strcmp (err_detail, http_task_error_strs[HTTP_TASK_ERR_TX]) == 0 ||
|
||||
strcmp (err_detail, http_task_error_strs[HTTP_TASK_ERR_TX_TIMEOUT]) == 0))
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -34,33 +34,6 @@ enum HttpTaskRuntimeState {
|
||||
N_HTTP_TASK_RT_STATE,
|
||||
};
|
||||
|
||||
enum HttpTaskError {
|
||||
HTTP_TASK_OK = 0,
|
||||
HTTP_TASK_ERR_FORBIDDEN,
|
||||
HTTP_TASK_ERR_NO_WRITE_PERMISSION,
|
||||
HTTP_TASK_ERR_NO_PERMISSION_TO_SYNC,
|
||||
HTTP_TASK_ERR_NET,
|
||||
HTTP_TASK_ERR_RESOLVE_PROXY,
|
||||
HTTP_TASK_ERR_RESOLVE_HOST,
|
||||
HTTP_TASK_ERR_CONNECT,
|
||||
HTTP_TASK_ERR_SSL,
|
||||
HTTP_TASK_ERR_TX,
|
||||
HTTP_TASK_ERR_TX_TIMEOUT,
|
||||
HTTP_TASK_ERR_UNHANDLED_REDIRECT,
|
||||
HTTP_TASK_ERR_SERVER,
|
||||
HTTP_TASK_ERR_BAD_REQUEST,
|
||||
HTTP_TASK_ERR_BAD_LOCAL_DATA,
|
||||
HTTP_TASK_ERR_NOT_ENOUGH_MEMORY,
|
||||
HTTP_TASK_ERR_WRITE_LOCAL_DATA,
|
||||
HTTP_TASK_ERR_NO_QUOTA,
|
||||
HTTP_TASK_ERR_FILES_LOCKED,
|
||||
HTTP_TASK_ERR_REPO_DELETED,
|
||||
HTTP_TASK_ERR_REPO_CORRUPTED,
|
||||
HTTP_TASK_ERR_FILE_LOCKED_ON_SERVER,
|
||||
HTTP_TASK_ERR_UNKNOWN,
|
||||
N_HTTP_TASK_ERROR,
|
||||
};
|
||||
|
||||
struct _SeafileSession;
|
||||
struct _HttpTxPriv;
|
||||
|
||||
@ -77,6 +50,7 @@ struct _HttpTxTask {
|
||||
|
||||
char repo_id[37];
|
||||
int repo_version;
|
||||
char *repo_name;
|
||||
char *token;
|
||||
int protocol_version;
|
||||
int type;
|
||||
@ -117,9 +91,6 @@ struct _HttpTxTask {
|
||||
|
||||
gint tx_bytes; /* bytes transferred in this second. */
|
||||
gint last_tx_bytes; /* bytes transferred in the last second. */
|
||||
|
||||
uint32_t cevent_id; /* Used by download task to send notification. */
|
||||
char *repo_name; /* Used by download task in conflict notification. */
|
||||
};
|
||||
typedef struct _HttpTxTask HttpTxTask;
|
||||
|
||||
@ -312,10 +283,6 @@ http_tx_manager_cancel_task (HttpTxManager *manager,
|
||||
const char *repo_id,
|
||||
int task_type);
|
||||
|
||||
/* Only useful for download task. */
|
||||
void
|
||||
http_tx_manager_notify_conflict (HttpTxTask *task, const char *path);
|
||||
|
||||
int
|
||||
http_tx_task_get_rate (HttpTxTask *task);
|
||||
|
||||
@ -325,9 +292,4 @@ http_task_state_to_str (int state);
|
||||
const char *
|
||||
http_task_rt_state_to_str (int rt_state);
|
||||
|
||||
const char *
|
||||
http_task_error_str (int task_errno);
|
||||
|
||||
#endif
|
||||
gboolean
|
||||
is_http_task_net_error (char *err_detail);
|
||||
|
@ -55,8 +55,6 @@ struct _SeafRepoManagerPriv {
|
||||
GHashTable *group_perms; /* repo_id -> folder group perms */
|
||||
pthread_mutex_t perm_lock;
|
||||
|
||||
uint32_t cevent_id; /* Used to notify sync error */
|
||||
|
||||
GAsyncQueue *lock_office_job_queue;
|
||||
};
|
||||
|
||||
@ -276,6 +274,7 @@ locked_file_set_remove (LockedFileSet *fset, const char *path, gboolean db_only)
|
||||
sqlite3_finalize (stmt);
|
||||
pthread_mutex_unlock (&mgr->priv->db_lock);
|
||||
|
||||
if (!db_only)
|
||||
g_hash_table_remove (fset->locked_files, path);
|
||||
|
||||
return 0;
|
||||
@ -665,61 +664,49 @@ is_repo_id_valid (const char *id)
|
||||
return is_uuid_valid (id);
|
||||
}
|
||||
|
||||
typedef struct FileErrorAux {
|
||||
char *repo_id;
|
||||
char *path;
|
||||
int err_id;
|
||||
} FileErrorAux;
|
||||
/*
|
||||
* Sync error related. These functions should belong to the sync-mgr module.
|
||||
* But since we have to store the errors in repo database, we have to put the code here.
|
||||
*/
|
||||
|
||||
static gboolean
|
||||
get_last_file_sync_error (sqlite3_stmt *stmt, void *data)
|
||||
{
|
||||
FileErrorAux *aux = data;
|
||||
|
||||
aux->repo_id = g_strdup((const char *)sqlite3_column_text (stmt, 0));
|
||||
aux->path = g_strdup((const char *)sqlite3_column_text (stmt, 1));
|
||||
aux->err_id = sqlite3_column_int (stmt, 2);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
save_file_sync_error (const char *repo_id, const char *repo_name, const char *path,
|
||||
int err_id, gboolean *duplicated)
|
||||
int
|
||||
seaf_repo_manager_record_sync_error (const char *repo_id,
|
||||
const char *repo_name,
|
||||
const char *path,
|
||||
int error_id)
|
||||
{
|
||||
char *sql;
|
||||
FileErrorAux aux;
|
||||
int n;
|
||||
|
||||
memset (&aux, 0, sizeof(aux));
|
||||
int ret;
|
||||
|
||||
pthread_mutex_lock (&seaf->repo_mgr->priv->db_lock);
|
||||
|
||||
sql = "SELECT repo_id, path, err_id FROM FileSyncError "
|
||||
"ORDER BY id DESC LIMIT 1 OFFSET 0";
|
||||
n = sqlite_foreach_selected_row (seaf->repo_mgr->priv->db,
|
||||
sql, get_last_file_sync_error, &aux);
|
||||
|
||||
if (n > 0 &&
|
||||
g_strcmp0(repo_id, aux.repo_id) == 0 &&
|
||||
g_strcmp0(path, aux.path) == 0 &&
|
||||
err_id == aux.err_id) {
|
||||
*duplicated = TRUE;
|
||||
sql = sqlite3_mprintf ("DELETE FROM FileSyncError WHERE repo_id='%q' AND path='%q'",
|
||||
repo_id, path);
|
||||
ret = sqlite_query_exec (seaf->repo_mgr->priv->db, sql);
|
||||
sqlite3_free (sql);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* REPLACE INTO will update the primary key id automatically.
|
||||
* So new errors are always on top.
|
||||
*/
|
||||
if (path != NULL)
|
||||
sql = sqlite3_mprintf ("INSERT INTO FileSyncError "
|
||||
"(repo_id, repo_name, path, err_id, timestamp) "
|
||||
"VALUES ('%q', '%q', '%q', %d, %"G_GINT64_FORMAT")",
|
||||
repo_id, repo_name, path, err_id, (gint64)time(NULL));
|
||||
sqlite_query_exec (seaf->repo_mgr->priv->db, sql);
|
||||
repo_id, repo_name, path, error_id, (gint64)time(NULL));
|
||||
else
|
||||
sql = sqlite3_mprintf ("INSERT INTO FileSyncError "
|
||||
"(repo_id, repo_name, err_id, timestamp) "
|
||||
"VALUES ('%q', '%q', %d, %"G_GINT64_FORMAT")",
|
||||
repo_id, repo_name, error_id, (gint64)time(NULL));
|
||||
|
||||
ret = sqlite_query_exec (seaf->repo_mgr->priv->db, sql);
|
||||
sqlite3_free (sql);
|
||||
|
||||
out:
|
||||
pthread_mutex_unlock (&seaf->repo_mgr->priv->db_lock);
|
||||
g_free (aux.repo_id);
|
||||
g_free (aux.path);
|
||||
return;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -771,42 +758,8 @@ seaf_repo_manager_get_file_sync_errors (SeafRepoManager *mgr, int offset, int li
|
||||
return ret;
|
||||
}
|
||||
|
||||
typedef struct SyncErrorData {
|
||||
char *repo_id;
|
||||
char *repo_name;
|
||||
char *path;
|
||||
int err_id;
|
||||
} SyncErrorData;
|
||||
|
||||
static void
|
||||
notify_sync_error (CEvent *event, void *handler_data)
|
||||
{
|
||||
SyncErrorData *data = event->data;
|
||||
json_t *object;
|
||||
char *str;
|
||||
|
||||
object = json_object ();
|
||||
json_object_set_new (object, "repo_id", json_string(data->repo_id));
|
||||
json_object_set_new (object, "repo_name", json_string(data->repo_name));
|
||||
json_object_set_new (object, "path", json_string(data->path));
|
||||
json_object_set_new (object, "err_id", json_integer(data->err_id));
|
||||
|
||||
str = json_dumps (object, 0);
|
||||
|
||||
seaf_mq_manager_publish_notification (seaf->mq_mgr,
|
||||
"sync.error",
|
||||
str);
|
||||
|
||||
free (str);
|
||||
json_decref (object);
|
||||
g_free (data->repo_id);
|
||||
g_free (data->repo_name);
|
||||
g_free (data->path);
|
||||
g_free (data);
|
||||
}
|
||||
|
||||
/*
|
||||
* FIXME: This function should be placed in sync manager.
|
||||
* Record file-level sync errors and send system notification.
|
||||
*/
|
||||
void
|
||||
send_file_sync_error_notification (const char *repo_id,
|
||||
@ -821,23 +774,27 @@ send_file_sync_error_notification (const char *repo_id,
|
||||
repo_name = repo->name;
|
||||
}
|
||||
|
||||
SyncErrorData *data = g_new0 (SyncErrorData, 1);
|
||||
data->repo_id = g_strdup(repo_id);
|
||||
data->repo_name = g_strdup(repo_name);
|
||||
data->path = g_strdup(path);
|
||||
data->err_id = err_id;
|
||||
seaf_repo_manager_record_sync_error (repo_id, repo_name, path, err_id);
|
||||
|
||||
gboolean duplicated = FALSE;
|
||||
save_file_sync_error (repo_id, repo_name, path, err_id, &duplicated);
|
||||
seaf_sync_manager_set_task_error_code (seaf->sync_mgr, repo_id, err_id);
|
||||
|
||||
if (!duplicated)
|
||||
cevent_manager_add_event (seaf->ev_mgr, seaf->repo_mgr->priv->cevent_id, data);
|
||||
else {
|
||||
g_free (data->repo_id);
|
||||
g_free (data->repo_name);
|
||||
g_free (data->path);
|
||||
g_free (data);
|
||||
}
|
||||
json_t *object;
|
||||
char *str;
|
||||
|
||||
object = json_object ();
|
||||
json_object_set_new (object, "repo_id", json_string(repo_id));
|
||||
json_object_set_new (object, "repo_name", json_string(repo_name));
|
||||
json_object_set_new (object, "path", json_string(path));
|
||||
json_object_set_new (object, "err_id", json_integer(err_id));
|
||||
|
||||
str = json_dumps (object, 0);
|
||||
|
||||
seaf_mq_manager_publish_notification (seaf->mq_mgr,
|
||||
"sync.error",
|
||||
str);
|
||||
|
||||
free (str);
|
||||
json_decref (object);
|
||||
}
|
||||
|
||||
SeafRepo*
|
||||
@ -4601,11 +4558,11 @@ checkout_file_http (FileTxData *data,
|
||||
cleanup_file_blocks_http (http_task, file_id);
|
||||
|
||||
if (conflicted) {
|
||||
http_tx_manager_notify_conflict (http_task, de->name);
|
||||
send_file_sync_error_notification (repo_id, NULL, de->name, SYNC_ERROR_ID_CONFLICT);
|
||||
} else if (!http_task->is_clone) {
|
||||
char *orig_path = NULL;
|
||||
if (check_path_conflict (de->name, &orig_path))
|
||||
http_tx_manager_notify_conflict (http_task, orig_path);
|
||||
send_file_sync_error_notification (repo_id, NULL, orig_path, SYNC_ERROR_ID_CONFLICT);
|
||||
g_free (orig_path);
|
||||
}
|
||||
|
||||
@ -5687,10 +5644,6 @@ seaf_repo_manager_init (SeafRepoManager *mgr)
|
||||
return -1;
|
||||
}
|
||||
|
||||
mgr->priv->cevent_id = cevent_manager_register (seaf->ev_mgr,
|
||||
(cevent_handler)notify_sync_error,
|
||||
NULL);
|
||||
|
||||
/* Load all the repos into memory on the client side. */
|
||||
load_repos (mgr, mgr->seaf->seaf_dir);
|
||||
|
||||
@ -6577,6 +6530,9 @@ open_db (SeafRepoManager *manager, const char *seaf_dir)
|
||||
"path TEXT, err_id INTEGER, timestamp INTEGER);";
|
||||
sqlite_query_exec (db, sql);
|
||||
|
||||
sql = "CREATE INDEX IF NOT EXISTS FileSyncErrorIndex ON FileSyncError (repo_id, path)";
|
||||
sqlite_query_exec (db, sql);
|
||||
|
||||
return db;
|
||||
}
|
||||
|
||||
|
@ -400,25 +400,18 @@ seaf_repo_manager_is_path_writable (SeafRepoManager *mgr,
|
||||
const char *repo_id,
|
||||
const char *path);
|
||||
|
||||
/*
|
||||
* File Sync Errors.
|
||||
* FIXME: better to be placed in sync manager.
|
||||
*/
|
||||
/* Sync error related. */
|
||||
|
||||
#define SYNC_ERROR_ID_FILE_LOCKED_BY_APP 0
|
||||
#define SYNC_ERROR_ID_FOLDER_LOCKED_BY_APP 1
|
||||
#define SYNC_ERROR_ID_FILE_LOCKED 2
|
||||
#define SYNC_ERROR_ID_INVALID_PATH 3
|
||||
#define SYNC_ERROR_ID_INDEX_ERROR 4
|
||||
#define SYNC_ERROR_ID_PATH_END_SPACE_PERIOD 5
|
||||
#define SYNC_ERROR_ID_PATH_INVALID_CHARACTER 6
|
||||
#define SYNC_ERROR_ID_FOLDER_PERM_DENIED 7
|
||||
#define SYNC_ERROR_ID_PERM_NOT_SYNCABLE 8
|
||||
#define SYNC_ERROR_ID_UPDATE_TO_READ_ONLY_REPO 9
|
||||
int
|
||||
seaf_repo_manager_record_sync_error (const char *repo_id,
|
||||
const char *repo_name,
|
||||
const char *path,
|
||||
int error_id);
|
||||
|
||||
GList *
|
||||
seaf_repo_manager_get_file_sync_errors (SeafRepoManager *mgr, int offset, int limit);
|
||||
|
||||
/* Record sync error and send notification. */
|
||||
void
|
||||
send_file_sync_error_notification (const char *repo_id,
|
||||
const char *repo_name,
|
||||
|
@ -222,11 +222,6 @@ register_rpc_service ()
|
||||
"seafile_get_repo_sync_task",
|
||||
searpc_signature_object__string());
|
||||
|
||||
searpc_server_register_function ("seafile-rpcserver",
|
||||
seafile_get_repo_sync_info,
|
||||
"seafile_get_repo_sync_info",
|
||||
searpc_signature_object__string());
|
||||
|
||||
searpc_server_register_function ("seafile-rpcserver",
|
||||
seafile_find_transfer_task,
|
||||
"seafile_find_transfer_task",
|
||||
|
18
daemon/seafile-error-impl.h
Normal file
18
daemon/seafile-error-impl.h
Normal file
@ -0,0 +1,18 @@
|
||||
#ifndef SEAFILE_ERROR_IMPL_H
|
||||
#define SEAFILE_ERROR_IMPL_H
|
||||
|
||||
#include "seafile-error.h"
|
||||
|
||||
enum {
|
||||
SYNC_ERROR_LEVEL_REPO,
|
||||
SYNC_ERROR_LEVEL_FILE,
|
||||
SYNC_ERROR_LEVEL_NETWORK,
|
||||
};
|
||||
|
||||
const char *
|
||||
sync_error_id_to_str (int error);
|
||||
|
||||
int
|
||||
sync_error_level (int error);
|
||||
|
||||
#endif
|
178
daemon/seafile-error.c
Normal file
178
daemon/seafile-error.c
Normal file
@ -0,0 +1,178 @@
|
||||
#include "common.h"
|
||||
|
||||
#include "seafile-error-impl.h"
|
||||
|
||||
typedef struct SyncErrorInfo {
|
||||
int error_id;
|
||||
int error_level;
|
||||
const char *err_str;
|
||||
} SyncErrorInfo;
|
||||
|
||||
static SyncErrorInfo sync_error_info_tbl[] = {
|
||||
{
|
||||
SYNC_ERROR_ID_FILE_LOCKED_BY_APP,
|
||||
SYNC_ERROR_LEVEL_FILE,
|
||||
"File is locked by another application"
|
||||
},
|
||||
{
|
||||
SYNC_ERROR_ID_FOLDER_LOCKED_BY_APP,
|
||||
SYNC_ERROR_LEVEL_FILE,
|
||||
"Folder is locked by another application"
|
||||
},
|
||||
{
|
||||
SYNC_ERROR_ID_FILE_LOCKED,
|
||||
SYNC_ERROR_LEVEL_FILE,
|
||||
"File is locked by another user"
|
||||
},
|
||||
{
|
||||
SYNC_ERROR_ID_INVALID_PATH,
|
||||
SYNC_ERROR_LEVEL_FILE,
|
||||
"Path is invalid"
|
||||
},
|
||||
{
|
||||
SYNC_ERROR_ID_INDEX_ERROR,
|
||||
SYNC_ERROR_LEVEL_FILE,
|
||||
"Error when indexing"
|
||||
},
|
||||
{
|
||||
SYNC_ERROR_ID_PATH_END_SPACE_PERIOD,
|
||||
SYNC_ERROR_LEVEL_FILE,
|
||||
"Path ends with space or period character"
|
||||
},
|
||||
{
|
||||
SYNC_ERROR_ID_PATH_INVALID_CHARACTER,
|
||||
SYNC_ERROR_LEVEL_FILE,
|
||||
"Path contains invalid characters like '|' or ':'"
|
||||
},
|
||||
{
|
||||
SYNC_ERROR_ID_FOLDER_PERM_DENIED,
|
||||
SYNC_ERROR_LEVEL_FILE,
|
||||
"Update to file denied by folder permission setting"
|
||||
},
|
||||
{
|
||||
SYNC_ERROR_ID_PERM_NOT_SYNCABLE,
|
||||
SYNC_ERROR_LEVEL_FILE,
|
||||
"No permission to sync this folder"
|
||||
},
|
||||
{
|
||||
SYNC_ERROR_ID_UPDATE_TO_READ_ONLY_REPO,
|
||||
SYNC_ERROR_LEVEL_FILE,
|
||||
"Created or updated a file in a non-writable library or folder"
|
||||
},
|
||||
{
|
||||
SYNC_ERROR_ID_ACCESS_DENIED,
|
||||
SYNC_ERROR_LEVEL_REPO,
|
||||
"Permission denied on server"
|
||||
},
|
||||
{
|
||||
SYNC_ERROR_ID_NO_WRITE_PERMISSION,
|
||||
SYNC_ERROR_LEVEL_REPO,
|
||||
"Do not have write permission to the library"
|
||||
},
|
||||
{
|
||||
SYNC_ERROR_ID_QUOTA_FULL,
|
||||
SYNC_ERROR_LEVEL_REPO,
|
||||
"Storage quota full"
|
||||
},
|
||||
{
|
||||
SYNC_ERROR_ID_NETWORK,
|
||||
SYNC_ERROR_LEVEL_NETWORK,
|
||||
"Network error",
|
||||
},
|
||||
{
|
||||
SYNC_ERROR_ID_RESOLVE_PROXY,
|
||||
SYNC_ERROR_LEVEL_NETWORK,
|
||||
"Cannot resolve proxy address"
|
||||
},
|
||||
{
|
||||
SYNC_ERROR_ID_RESOLVE_HOST,
|
||||
SYNC_ERROR_LEVEL_NETWORK,
|
||||
"Cannot resolve server address"
|
||||
},
|
||||
{
|
||||
SYNC_ERROR_ID_CONNECT,
|
||||
SYNC_ERROR_LEVEL_NETWORK,
|
||||
"Cannot connect to server"
|
||||
},
|
||||
{
|
||||
SYNC_ERROR_ID_SSL,
|
||||
SYNC_ERROR_LEVEL_NETWORK,
|
||||
"Failed to establish secure connection. Please check server SSL certificate"
|
||||
},
|
||||
{
|
||||
SYNC_ERROR_ID_TX,
|
||||
SYNC_ERROR_LEVEL_NETWORK,
|
||||
"Data transfer was interrupted. Please check network or firewall"
|
||||
},
|
||||
{
|
||||
SYNC_ERROR_ID_TX_TIMEOUT,
|
||||
SYNC_ERROR_LEVEL_NETWORK,
|
||||
"Data transfer timed out. Please check network or firewall"
|
||||
},
|
||||
{
|
||||
SYNC_ERROR_ID_UNHANDLED_REDIRECT,
|
||||
SYNC_ERROR_LEVEL_NETWORK,
|
||||
"Unhandled http redirect from server. Please check server cofiguration"
|
||||
},
|
||||
{
|
||||
SYNC_ERROR_ID_SERVER,
|
||||
SYNC_ERROR_LEVEL_REPO,
|
||||
"Server error"
|
||||
},
|
||||
{
|
||||
SYNC_ERROR_ID_LOCAL_DATA_CORRUPT,
|
||||
SYNC_ERROR_LEVEL_REPO,
|
||||
"Internal data corrupt on the client. Please try to resync the library"
|
||||
},
|
||||
{
|
||||
SYNC_ERROR_ID_WRITE_LOCAL_DATA,
|
||||
SYNC_ERROR_LEVEL_REPO,
|
||||
"Failed to write data on the client. Please check disk space or folder permissions"
|
||||
},
|
||||
{
|
||||
SYNC_ERROR_ID_SERVER_REPO_DELETED,
|
||||
SYNC_ERROR_LEVEL_REPO,
|
||||
"Library deleted on server"
|
||||
},
|
||||
{
|
||||
SYNC_ERROR_ID_SERVER_REPO_CORRUPT,
|
||||
SYNC_ERROR_LEVEL_REPO,
|
||||
"Library damaged on server"
|
||||
},
|
||||
{
|
||||
SYNC_ERROR_ID_NOT_ENOUGH_MEMORY,
|
||||
SYNC_ERROR_LEVEL_REPO,
|
||||
"Not enough memory"
|
||||
},
|
||||
{
|
||||
SYNC_ERROR_ID_CONFLICT,
|
||||
SYNC_ERROR_LEVEL_FILE,
|
||||
"Concurrent updates to file. File is saved as conflict file"
|
||||
},
|
||||
{
|
||||
SYNC_ERROR_ID_GENERAL_ERROR,
|
||||
SYNC_ERROR_LEVEL_REPO,
|
||||
"Unknown error"
|
||||
},
|
||||
{
|
||||
SYNC_ERROR_ID_NO_ERROR,
|
||||
SYNC_ERROR_LEVEL_REPO,
|
||||
"No error"
|
||||
},
|
||||
};
|
||||
|
||||
const char *
|
||||
sync_error_id_to_str (int error)
|
||||
{
|
||||
g_return_val_if_fail ((error >= 0 && error < N_SYNC_ERROR_ID), "Unknown error");
|
||||
|
||||
return sync_error_info_tbl[error].err_str;
|
||||
}
|
||||
|
||||
int
|
||||
sync_error_level (int error)
|
||||
{
|
||||
g_return_val_if_fail ((error >= 0 && error < N_SYNC_ERROR_ID), -1);
|
||||
|
||||
return sync_error_info_tbl[error].error_level;
|
||||
}
|
@ -9,7 +9,7 @@
|
||||
#include "seafile-session.h"
|
||||
#include "seafile-config.h"
|
||||
#include "sync-mgr.h"
|
||||
#include "seafile-error.h"
|
||||
#include "seafile-error-impl.h"
|
||||
#include "mq-mgr.h"
|
||||
#include "utils.h"
|
||||
#include "vc-utils.h"
|
||||
@ -506,6 +506,15 @@ notify_sync (SeafRepo *repo, gboolean is_multipart_upload)
|
||||
|
||||
#define IN_ERROR_THRESHOLD 3
|
||||
|
||||
static gboolean
|
||||
is_perm_error (int error)
|
||||
{
|
||||
return (error == SYNC_ERROR_ID_ACCESS_DENIED ||
|
||||
error == SYNC_ERROR_ID_NO_WRITE_PERMISSION ||
|
||||
error == SYNC_ERROR_ID_PERM_NOT_SYNCABLE ||
|
||||
error == SYNC_ERROR_ID_FOLDER_PERM_DENIED);
|
||||
}
|
||||
|
||||
static void
|
||||
update_sync_info_error_state (SyncTask *task, int new_state)
|
||||
{
|
||||
@ -515,7 +524,7 @@ update_sync_info_error_state (SyncTask *task, int new_state)
|
||||
info->err_cnt++;
|
||||
if (info->err_cnt == IN_ERROR_THRESHOLD)
|
||||
info->in_error = TRUE;
|
||||
if (task->error == SYNC_ERROR_ACCESS_DENIED)
|
||||
if (is_perm_error(task->error))
|
||||
info->sync_perm_err_cnt++;
|
||||
} else if (info->err_cnt > 0) {
|
||||
info->err_cnt = 0;
|
||||
@ -526,7 +535,7 @@ update_sync_info_error_state (SyncTask *task, int new_state)
|
||||
|
||||
static void commit_repo (SyncTask *task);
|
||||
|
||||
static inline void
|
||||
static void
|
||||
transition_sync_state (SyncTask *task, int new_state)
|
||||
{
|
||||
g_return_if_fail (new_state >= 0 && new_state < SYNC_STATE_NUM);
|
||||
@ -551,6 +560,17 @@ transition_sync_state (SyncTask *task, int new_state)
|
||||
return;
|
||||
}
|
||||
|
||||
/* If file error levels occured during sync, the whole sync process can still finish
|
||||
* with DONE state. But we need to notify the user about this error in the interface.
|
||||
* Such file level errors are set with seaf_sync_manager_set_task_error_code().
|
||||
*/
|
||||
if (new_state != SYNC_STATE_ERROR && task->error != SYNC_ERROR_ID_NO_ERROR) {
|
||||
new_state = SYNC_STATE_ERROR;
|
||||
seaf_message ("Repo '%s' sync is finished but with error: %s\n",
|
||||
task->repo->name,
|
||||
sync_error_id_to_str(task->error));
|
||||
}
|
||||
|
||||
if (!(task->state == SYNC_STATE_DONE && new_state == SYNC_STATE_INIT) &&
|
||||
!(task->state == SYNC_STATE_INIT && new_state == SYNC_STATE_DONE)) {
|
||||
seaf_message ("Repo '%s' sync state transition from '%s' to '%s'.\n",
|
||||
@ -582,49 +602,32 @@ transition_sync_state (SyncTask *task, int new_state)
|
||||
}
|
||||
}
|
||||
|
||||
static const char *sync_error_str[] = {
|
||||
"Success",
|
||||
"relay not connected",
|
||||
"failed to upgrade old repo",
|
||||
"Server has been removed",
|
||||
"You have not login to the server",
|
||||
"Remote service is not available",
|
||||
"You do not have permission to access this library",
|
||||
"The storage space of the repo owner has been used up",
|
||||
"Access denied to service. Please check your registration on relay.",
|
||||
"Internal data corrupted.",
|
||||
"Failed to start upload.",
|
||||
"Error occurred in upload.",
|
||||
"Failed to start download.",
|
||||
"Error occurred in download.",
|
||||
"No such repo on relay.",
|
||||
"Repo is damaged on relay.",
|
||||
"Failed to index files.",
|
||||
"Conflict in merge.",
|
||||
"Files changed in local folder, skip merge.",
|
||||
"Server version is too old.",
|
||||
"Failed to get sync info from server.",
|
||||
"Files are locked by other application",
|
||||
"Unknown error.",
|
||||
};
|
||||
|
||||
void
|
||||
seaf_sync_manager_set_task_error (SyncTask *task, int error)
|
||||
static void
|
||||
set_task_error (SyncTask *task, int error)
|
||||
{
|
||||
g_return_if_fail (error >= 0 && error < SYNC_ERROR_NUM);
|
||||
g_return_if_fail (error >= 0 && error < N_SYNC_ERROR_ID);
|
||||
|
||||
const char *err_str = sync_error_id_to_str(error);
|
||||
int err_level = sync_error_level(error);
|
||||
|
||||
if (task->state != SYNC_STATE_ERROR) {
|
||||
seaf_message ("Repo '%s' sync state transition from %s to '%s': '%s'.\n",
|
||||
task->repo->name,
|
||||
sync_state_str[task->state],
|
||||
sync_state_str[SYNC_STATE_ERROR],
|
||||
sync_error_str[error]);
|
||||
err_str);
|
||||
task->state = SYNC_STATE_ERROR;
|
||||
task->error = error;
|
||||
task->info->in_sync = FALSE;
|
||||
--(task->mgr->n_running_tasks);
|
||||
update_sync_info_error_state (task, SYNC_STATE_ERROR);
|
||||
|
||||
/* For repo-level errors, only need to record in database, but not send notifications.
|
||||
* File-level errors are recorded and notified in the location they happens, not here.
|
||||
*/
|
||||
if (err_level == SYNC_ERROR_LEVEL_REPO)
|
||||
seaf_repo_manager_record_sync_error (task->repo->id, task->repo->name, NULL, error);
|
||||
|
||||
#ifdef WIN32
|
||||
seaf_sync_manager_add_refresh_path (seaf->sync_mgr, task->repo->worktree);
|
||||
#endif
|
||||
@ -632,13 +635,24 @@ seaf_sync_manager_set_task_error (SyncTask *task, int error)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
seaf_sync_manager_set_task_error_code (SeafSyncManager *mgr,
|
||||
const char *repo_id,
|
||||
int error)
|
||||
{
|
||||
SyncInfo *info = g_hash_table_lookup (mgr->sync_infos, repo_id);
|
||||
if (!info)
|
||||
return;
|
||||
|
||||
info->current_task->error = error;
|
||||
}
|
||||
|
||||
static void
|
||||
sync_task_free (SyncTask *task)
|
||||
{
|
||||
g_free (task->tx_id);
|
||||
g_free (task->dest_id);
|
||||
g_free (task->token);
|
||||
g_free (task->err_detail);
|
||||
g_free (task);
|
||||
}
|
||||
|
||||
@ -657,7 +671,7 @@ start_upload_if_necessary (SyncTask *task)
|
||||
repo->use_fileserver_port,
|
||||
&error) < 0) {
|
||||
seaf_warning ("Failed to start http upload: %s\n", error->message);
|
||||
seaf_sync_manager_set_task_error (task, SYNC_ERROR_START_UPLOAD);
|
||||
set_task_error (task, SYNC_ERROR_ID_NOT_ENOUGH_MEMORY);
|
||||
return;
|
||||
}
|
||||
task->tx_id = g_strdup(repo->id);
|
||||
@ -685,7 +699,7 @@ start_fetch_if_necessary (SyncTask *task, const char *remote_head)
|
||||
repo->name,
|
||||
&error) < 0) {
|
||||
seaf_warning ("Failed to start http download: %s.\n", error->message);
|
||||
seaf_sync_manager_set_task_error (task, SYNC_ERROR_START_FETCH);
|
||||
set_task_error (task, SYNC_ERROR_ID_NOT_ENOUGH_MEMORY);
|
||||
return;
|
||||
}
|
||||
task->tx_id = g_strdup(repo->id);
|
||||
@ -809,7 +823,7 @@ remove_blocks_done (void *vtask)
|
||||
static void
|
||||
on_repo_deleted_on_server (SyncTask *task, SeafRepo *repo)
|
||||
{
|
||||
seaf_sync_manager_set_task_error (task, SYNC_ERROR_NOREPO);
|
||||
set_task_error (task, SYNC_ERROR_ID_SERVER_REPO_DELETED);
|
||||
|
||||
seaf_warning ("repo %s(%.8s) not found on server\n",
|
||||
repo->name, repo->id);
|
||||
@ -817,9 +831,9 @@ on_repo_deleted_on_server (SyncTask *task, SeafRepo *repo)
|
||||
if (!seafile_session_config_get_allow_repo_not_found_on_server(seaf)) {
|
||||
seaf_message ("remove repo %s(%.8s) since it's deleted on relay\n",
|
||||
repo->name, repo->id);
|
||||
seaf_mq_manager_publish_notification (seaf->mq_mgr,
|
||||
"repo.deleted_on_relay",
|
||||
repo->name);
|
||||
/* seaf_mq_manager_publish_notification (seaf->mq_mgr, */
|
||||
/* "repo.deleted_on_relay", */
|
||||
/* repo->name); */
|
||||
seaf_repo_manager_del_repo (seaf->repo_mgr, repo);
|
||||
}
|
||||
}
|
||||
@ -836,7 +850,7 @@ update_sync_status_v2 (SyncTask *task)
|
||||
if (!local) {
|
||||
seaf_warning ("[sync-mgr] Branch local not found for repo %s(%.8s).\n",
|
||||
repo->name, repo->id);
|
||||
seaf_sync_manager_set_task_error (task, SYNC_ERROR_DATA_CORRUPT);
|
||||
set_task_error (task, SYNC_ERROR_ID_LOCAL_DATA_CORRUPT);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -845,12 +859,12 @@ update_sync_status_v2 (SyncTask *task)
|
||||
if (!master) {
|
||||
seaf_warning ("[sync-mgr] Branch master not found for repo %s(%.8s).\n",
|
||||
repo->name, repo->id);
|
||||
seaf_sync_manager_set_task_error (task, SYNC_ERROR_DATA_CORRUPT);
|
||||
set_task_error (task, SYNC_ERROR_ID_LOCAL_DATA_CORRUPT);
|
||||
return;
|
||||
}
|
||||
|
||||
if (info->repo_corrupted) {
|
||||
seaf_sync_manager_set_task_error (task, SYNC_ERROR_REPO_CORRUPT);
|
||||
set_task_error (task, SYNC_ERROR_ID_SERVER_REPO_CORRUPT);
|
||||
} else if (info->deleted_on_relay) {
|
||||
on_repo_deleted_on_server (task, repo);
|
||||
} else {
|
||||
@ -883,8 +897,7 @@ check_head_commit_done (HttpHeadCommit *result, void *user_data)
|
||||
SyncInfo *info = task->info;
|
||||
|
||||
if (!result->check_success) {
|
||||
seaf_sync_manager_set_task_error (task, SYNC_ERROR_GET_SYNC_INFO);
|
||||
task->err_detail = g_strdup(http_task_error_str(result->error_code));
|
||||
set_task_error (task, result->error_code);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -910,7 +923,7 @@ check_head_commit_http (SyncTask *task)
|
||||
if (ret == 0)
|
||||
transition_sync_state (task, SYNC_STATE_INIT);
|
||||
else if (ret < 0)
|
||||
seaf_sync_manager_set_task_error (task, SYNC_ERROR_GET_SYNC_INFO);
|
||||
set_task_error (task, SYNC_ERROR_ID_NOT_ENOUGH_MEMORY);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -976,7 +989,7 @@ commit_job_done (void *vres)
|
||||
}
|
||||
|
||||
if (!res->success) {
|
||||
seaf_sync_manager_set_task_error (res->task, SYNC_ERROR_COMMIT);
|
||||
set_task_error (res->task, SYNC_ERROR_ID_INDEX_ERROR);
|
||||
g_free (res);
|
||||
return;
|
||||
}
|
||||
@ -1012,7 +1025,7 @@ commit_repo (SyncTask *task)
|
||||
commit_job,
|
||||
commit_job_done,
|
||||
task) < 0)
|
||||
seaf_sync_manager_set_task_error (task, SYNC_ERROR_COMMIT);
|
||||
set_task_error (task, SYNC_ERROR_ID_NOT_ENOUGH_MEMORY);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -1045,6 +1058,7 @@ create_sync_task_v2 (SeafSyncManager *manager, SeafRepo *repo,
|
||||
task->token = g_strdup(repo->token);
|
||||
task->is_manual_sync = is_manual_sync;
|
||||
task->is_initial_commit = is_initial_commit;
|
||||
task->error = SYNC_ERROR_ID_NO_ERROR;
|
||||
|
||||
repo->last_sync_time = time(NULL);
|
||||
++(manager->n_running_tasks);
|
||||
@ -2025,17 +2039,6 @@ auto_sync_pulse (void *vmanager)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
inline static void
|
||||
send_sync_error_notification (SeafRepo *repo, const char *type)
|
||||
{
|
||||
GString *buf = g_string_new (NULL);
|
||||
g_string_append_printf (buf, "%s\t%s", repo->name, repo->id);
|
||||
seaf_mq_manager_publish_notification (seaf->mq_mgr,
|
||||
type,
|
||||
buf->str);
|
||||
g_string_free (buf, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
on_repo_http_fetched (SeafileSession *seaf,
|
||||
HttpTxTask *tx_task,
|
||||
@ -2060,21 +2063,11 @@ on_repo_http_fetched (SeafileSession *seaf,
|
||||
} else if (tx_task->state == HTTP_TASK_STATE_CANCELED) {
|
||||
transition_sync_state (task, SYNC_STATE_CANCELED);
|
||||
} else if (tx_task->state == HTTP_TASK_STATE_ERROR) {
|
||||
if (tx_task->error == HTTP_TASK_ERR_FORBIDDEN ||
|
||||
tx_task->error == HTTP_TASK_ERR_NO_WRITE_PERMISSION ||
|
||||
tx_task->error == HTTP_TASK_ERR_NO_PERMISSION_TO_SYNC) {
|
||||
seaf_sync_manager_set_task_error (task, SYNC_ERROR_ACCESS_DENIED);
|
||||
if (!task->repo->access_denied_notified) {
|
||||
send_sync_error_notification (task->repo, "sync.access_denied");
|
||||
task->repo->access_denied_notified = 1;
|
||||
}
|
||||
} else if (tx_task->error == HTTP_TASK_ERR_FILES_LOCKED) {
|
||||
seaf_sync_manager_set_task_error (task, SYNC_ERROR_FILES_LOCKED);
|
||||
} else if (tx_task->error == HTTP_TASK_ERR_REPO_DELETED) {
|
||||
if (tx_task->error == SYNC_ERROR_ID_SERVER_REPO_DELETED) {
|
||||
on_repo_deleted_on_server (task, task->repo);
|
||||
} else
|
||||
seaf_sync_manager_set_task_error (task, SYNC_ERROR_FETCH);
|
||||
task->err_detail = g_strdup(http_task_error_str(tx_task->error));
|
||||
} else {
|
||||
set_task_error (task, tx_task->error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2107,38 +2100,12 @@ on_repo_http_uploaded (SeafileSession *seaf,
|
||||
} else if (tx_task->state == HTTP_TASK_STATE_CANCELED) {
|
||||
transition_sync_state (task, SYNC_STATE_CANCELED);
|
||||
} else if (tx_task->state == HTTP_TASK_STATE_ERROR) {
|
||||
if (tx_task->error == HTTP_TASK_ERR_FORBIDDEN ||
|
||||
tx_task->error == HTTP_TASK_ERR_NO_WRITE_PERMISSION ||
|
||||
tx_task->error == HTTP_TASK_ERR_NO_PERMISSION_TO_SYNC) {
|
||||
seaf_sync_manager_set_task_error (task, SYNC_ERROR_ACCESS_DENIED);
|
||||
if (!task->repo->access_denied_notified) {
|
||||
send_sync_error_notification (task->repo, "sync.access_denied");
|
||||
task->repo->access_denied_notified = 1;
|
||||
}
|
||||
} else if (tx_task->error == HTTP_TASK_ERR_NO_QUOTA) {
|
||||
seaf_sync_manager_set_task_error (task, SYNC_ERROR_QUOTA_FULL);
|
||||
/* Only notify "quota full" once. */
|
||||
if (!task->repo->quota_full_notified) {
|
||||
send_sync_error_notification (task->repo, "sync.quota_full");
|
||||
task->repo->quota_full_notified = 1;
|
||||
}
|
||||
} else if (tx_task->error == HTTP_TASK_ERR_REPO_DELETED) {
|
||||
if (tx_task->error == SYNC_ERROR_ID_SERVER_REPO_DELETED) {
|
||||
on_repo_deleted_on_server (task, task->repo);
|
||||
} else
|
||||
seaf_sync_manager_set_task_error (task, SYNC_ERROR_UPLOAD);
|
||||
task->err_detail = g_strdup(http_task_error_str(tx_task->error));
|
||||
} else {
|
||||
set_task_error (task, tx_task->error);
|
||||
}
|
||||
}
|
||||
|
||||
const char *
|
||||
sync_error_to_str (int error)
|
||||
{
|
||||
if (error < 0 || error >= SYNC_ERROR_NUM) {
|
||||
seaf_warning ("illegal sync error: %d\n", error);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return sync_error_str[error];
|
||||
}
|
||||
|
||||
const char *
|
||||
|
@ -50,33 +50,6 @@ enum {
|
||||
SYNC_STATE_NUM,
|
||||
};
|
||||
|
||||
enum {
|
||||
SYNC_ERROR_NONE,
|
||||
SYNC_ERROR_RELAY_OFFLINE,
|
||||
SYNC_ERROR_UPGRADE_REPO,
|
||||
SYNC_ERROR_RELAY_REMOVED,
|
||||
SYNC_ERROR_NOT_LOGIN,
|
||||
SYNC_ERROR_SERVICE_DOWN,
|
||||
SYNC_ERROR_ACCESS_DENIED,
|
||||
SYNC_ERROR_QUOTA_FULL,
|
||||
SYNC_ERROR_PROC_PERM_ERR,
|
||||
SYNC_ERROR_DATA_CORRUPT,
|
||||
SYNC_ERROR_START_UPLOAD,
|
||||
SYNC_ERROR_UPLOAD,
|
||||
SYNC_ERROR_START_FETCH,
|
||||
SYNC_ERROR_FETCH,
|
||||
SYNC_ERROR_NOREPO,
|
||||
SYNC_ERROR_REPO_CORRUPT,
|
||||
SYNC_ERROR_COMMIT,
|
||||
SYNC_ERROR_MERGE,
|
||||
SYNC_ERROR_WORKTREE_DIRTY,
|
||||
SYNC_ERROR_DEPRECATED_SERVER,
|
||||
SYNC_ERROR_GET_SYNC_INFO, /* for http sync */
|
||||
SYNC_ERROR_FILES_LOCKED,
|
||||
SYNC_ERROR_UNKNOWN,
|
||||
SYNC_ERROR_NUM,
|
||||
};
|
||||
|
||||
struct _SyncTask {
|
||||
SeafSyncManager *mgr;
|
||||
SyncInfo *info;
|
||||
@ -85,7 +58,6 @@ struct _SyncTask {
|
||||
gboolean is_initial_commit;
|
||||
int state;
|
||||
int error;
|
||||
char *err_detail;
|
||||
char *tx_id;
|
||||
char *token;
|
||||
struct SeafTimer *commit_timer;
|
||||
@ -166,9 +138,6 @@ seaf_sync_manager_enable_auto_sync (SeafSyncManager *mgr);
|
||||
int
|
||||
seaf_sync_manager_is_auto_sync_enabled (SeafSyncManager *mgr);
|
||||
|
||||
const char *
|
||||
sync_error_to_str (int error);
|
||||
|
||||
const char *
|
||||
sync_state_to_str (int state);
|
||||
|
||||
@ -209,4 +178,9 @@ void
|
||||
seaf_sync_manager_refresh_path (SeafSyncManager *mgr, const char *path);
|
||||
#endif
|
||||
|
||||
void
|
||||
seaf_sync_manager_set_task_error_code (SeafSyncManager *mgr,
|
||||
const char *repo_id,
|
||||
int error);
|
||||
|
||||
#endif
|
||||
|
@ -1,6 +1,8 @@
|
||||
#ifndef SEAFILE_ERROR_H
|
||||
#define SEAFILE_ERROR_H
|
||||
|
||||
/* Error codes used in RPC. */
|
||||
|
||||
#define SEAF_ERR_GENERAL 500
|
||||
#define SEAF_ERR_BAD_REPO 501
|
||||
#define SEAF_ERR_BAD_COMMIT 502
|
||||
@ -19,4 +21,44 @@
|
||||
#define SEAF_ERR_DIR_MISSING 515
|
||||
#define SEAF_ERR_PATH_NO_EXIST 516 /* the dir or file pointed by this path not exists */
|
||||
|
||||
/* Sync errors. */
|
||||
|
||||
#define SYNC_ERROR_ID_FILE_LOCKED_BY_APP 0
|
||||
#define SYNC_ERROR_ID_FOLDER_LOCKED_BY_APP 1
|
||||
/* When file is locked on server. Returned in update-branch. */
|
||||
#define SYNC_ERROR_ID_FILE_LOCKED 2
|
||||
#define SYNC_ERROR_ID_INVALID_PATH 3
|
||||
#define SYNC_ERROR_ID_INDEX_ERROR 4
|
||||
#define SYNC_ERROR_ID_PATH_END_SPACE_PERIOD 5
|
||||
#define SYNC_ERROR_ID_PATH_INVALID_CHARACTER 6
|
||||
/* Returned in update-branch */
|
||||
#define SYNC_ERROR_ID_FOLDER_PERM_DENIED 7
|
||||
/* When there is no sync permission to library */
|
||||
#define SYNC_ERROR_ID_PERM_NOT_SYNCABLE 8
|
||||
/* Local error when updating a file in readonly library. */
|
||||
#define SYNC_ERROR_ID_UPDATE_TO_READ_ONLY_REPO 9
|
||||
/* When there is no read access to library. */
|
||||
#define SYNC_ERROR_ID_ACCESS_DENIED 10
|
||||
/* When there is no write access to library */
|
||||
#define SYNC_ERROR_ID_NO_WRITE_PERMISSION 11
|
||||
#define SYNC_ERROR_ID_QUOTA_FULL 12
|
||||
#define SYNC_ERROR_ID_NETWORK 13
|
||||
#define SYNC_ERROR_ID_RESOLVE_PROXY 14
|
||||
#define SYNC_ERROR_ID_RESOLVE_HOST 15
|
||||
#define SYNC_ERROR_ID_CONNECT 16
|
||||
#define SYNC_ERROR_ID_SSL 17
|
||||
#define SYNC_ERROR_ID_TX 18
|
||||
#define SYNC_ERROR_ID_TX_TIMEOUT 19
|
||||
#define SYNC_ERROR_ID_UNHANDLED_REDIRECT 20
|
||||
#define SYNC_ERROR_ID_SERVER 21
|
||||
#define SYNC_ERROR_ID_LOCAL_DATA_CORRUPT 22
|
||||
#define SYNC_ERROR_ID_WRITE_LOCAL_DATA 23
|
||||
#define SYNC_ERROR_ID_SERVER_REPO_DELETED 24
|
||||
#define SYNC_ERROR_ID_SERVER_REPO_CORRUPT 25
|
||||
#define SYNC_ERROR_ID_NOT_ENOUGH_MEMORY 26
|
||||
#define SYNC_ERROR_ID_CONFLICT 27
|
||||
#define SYNC_ERROR_ID_GENERAL_ERROR 28
|
||||
#define SYNC_ERROR_ID_NO_ERROR 29
|
||||
#define N_SYNC_ERROR_ID 30
|
||||
|
||||
#endif
|
||||
|
@ -30,15 +30,6 @@ GObject* seafile_get_repo (const gchar* id, GError **error);
|
||||
GObject *
|
||||
seafile_get_repo_sync_task (const char *repo_id, GError **error);
|
||||
|
||||
/**
|
||||
* seafile_get_repo_sync_info:
|
||||
*/
|
||||
GObject *
|
||||
seafile_get_repo_sync_info (const char *repo_id, GError **error);
|
||||
|
||||
GList*
|
||||
seafile_get_repo_sinfo (const char *repo_id, GError **error);
|
||||
|
||||
/* [seafile_get_config] returns the value of the config entry whose name is
|
||||
* [key] in config.db
|
||||
*/
|
||||
|
@ -97,28 +97,12 @@ public class Repo : Object {
|
||||
public bool is_shared { get; set; }
|
||||
}
|
||||
|
||||
public class SyncInfo : Object {
|
||||
|
||||
public string repo_id { get; set; }
|
||||
public string head_commit { get; set; }
|
||||
public bool deleted_on_relay { get; set; }
|
||||
public bool bad_local_branch { get; set; }
|
||||
public bool need_fetch { get; set; }
|
||||
public bool need_upload { get; set; }
|
||||
public bool need_merge { get; set; }
|
||||
// public int last_sync_time { get; set; }
|
||||
}
|
||||
|
||||
public class SyncTask : Object {
|
||||
|
||||
public bool is_sync_lan { get; set; }
|
||||
public bool force_upload { get; set; }
|
||||
public string dest_id { get; set; }
|
||||
public string repo_id { get; set; }
|
||||
public string state { get; set; }
|
||||
public string error { get; set; }
|
||||
public string err_detail { get; set; }
|
||||
public string tx_id { get; set; }
|
||||
public int error { get; set; }
|
||||
}
|
||||
|
||||
public class SessionInfo : Object {
|
||||
|
@ -21,8 +21,6 @@ public class Task : Object {
|
||||
|
||||
public string rt_state { get; set; }
|
||||
|
||||
public string error_str { get; set; }
|
||||
|
||||
public int64 block_total { get; set; }
|
||||
public int64 block_done { get; set; } // the number of blocks sent or received
|
||||
|
||||
@ -47,13 +45,10 @@ public class Task : Object {
|
||||
|
||||
public class CloneTask : Object {
|
||||
public string state { get; set; }
|
||||
public string error_str { get; set; }
|
||||
public string err_detail { get; set; }
|
||||
public int error { get; set; }
|
||||
public string repo_id { get; set; }
|
||||
public string peer_id { get; set; }
|
||||
public string repo_name { get; set; }
|
||||
public string worktree { get; set; }
|
||||
public string tx_id { get; set; }
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
@ -139,11 +139,6 @@ class SeafileRpcClient(NamedPipeClient):
|
||||
pass
|
||||
find_transfer_task = seafile_find_transfer_task
|
||||
|
||||
@searpc_func("object", ["string"])
|
||||
def seafile_get_checkout_task(repo_id):
|
||||
pass
|
||||
get_checkout_task = seafile_get_checkout_task
|
||||
|
||||
### sync
|
||||
@searpc_func("int", ["string", "string"])
|
||||
def seafile_sync(repo_id, peer_id):
|
||||
@ -155,16 +150,16 @@ class SeafileRpcClient(NamedPipeClient):
|
||||
pass
|
||||
get_repo_sync_task = seafile_get_repo_sync_task
|
||||
|
||||
@searpc_func("object", ["string"])
|
||||
def seafile_get_repo_sync_info():
|
||||
pass
|
||||
get_repo_sync_info = seafile_get_repo_sync_info
|
||||
|
||||
@searpc_func("int", [])
|
||||
def seafile_is_auto_sync_enabled():
|
||||
pass
|
||||
is_auto_sync_enabled = seafile_is_auto_sync_enabled
|
||||
|
||||
@searpc_func("objlist", ["int", "int"])
|
||||
def seafile_get_file_sync_errors():
|
||||
pass
|
||||
get_file_sync_errors = seafile_get_file_sync_errors
|
||||
|
||||
###### Property Management #########
|
||||
|
||||
@searpc_func("int", ["string", "string"])
|
||||
|
Loading…
Reference in New Issue
Block a user