mirror of
https://github.com/haiwen/seafile-server.git
synced 2025-04-28 03:20:10 +00:00
Return 409 when gc conflict (#731)
* Return 409 when gc conflict * Go return 409 when gc conflict * Return gc conflict when sync repo --------- Co-authored-by: 杨赫然 <heran.yang@seafile.com>
This commit is contained in:
parent
de62852244
commit
ee9ad5ef39
@ -1745,8 +1745,12 @@ func postMultiFiles(rsp http.ResponseWriter, r *http.Request, repoID, parentDir,
|
||||
|
||||
retStr, err := postFilesAndGenCommit(fileNames, repo.ID, user, canonPath, replace, ids, sizes, lastModify, gcID)
|
||||
if err != nil {
|
||||
err := fmt.Errorf("failed to post files and gen commit: %v", err)
|
||||
return &appError{err, "", http.StatusInternalServerError}
|
||||
if errors.Is(err, ErrGCConflict) {
|
||||
return &appError{nil, "GC Conflict.\n", http.StatusConflict}
|
||||
} else {
|
||||
err := fmt.Errorf("failed to post files and gen commit: %v", err)
|
||||
return &appError{err, "", http.StatusInternalServerError}
|
||||
}
|
||||
}
|
||||
|
||||
_, ok := r.Form["ret-json"]
|
||||
@ -1848,7 +1852,7 @@ retry:
|
||||
_, err = genNewCommit(repo, headCommit, rootID, user, buf, handleConncurrentUpdate, lastGCID, true)
|
||||
if err != nil {
|
||||
if err != ErrConflict {
|
||||
err := fmt.Errorf("failed to generate new commit: %v", err)
|
||||
err := fmt.Errorf("failed to generate new commit: %w", err)
|
||||
return "", err
|
||||
}
|
||||
retryCnt++
|
||||
@ -1907,7 +1911,10 @@ func getCanonPath(p string) string {
|
||||
return filepath.Join(formatPath)
|
||||
}
|
||||
|
||||
var ErrConflict = fmt.Errorf("Concurent upload conflict")
|
||||
var (
|
||||
ErrConflict = errors.New("Concurent upload conflict")
|
||||
ErrGCConflict = errors.New("GC Conflict")
|
||||
)
|
||||
|
||||
func genNewCommit(repo *repomgr.Repo, base *commitmgr.Commit, newRoot, user, desc string, handleConncurrentUpdate bool, lastGCID string, checkGC bool) (string, error) {
|
||||
var retryCnt int
|
||||
@ -2094,7 +2101,7 @@ func updateBranch(repoID, originRepoID, newCommitID, oldCommitID, secondParentID
|
||||
if lastGCID != gcID.String {
|
||||
err = fmt.Errorf("Head branch update for repo %s conflicts with GC.", repoID)
|
||||
trans.Rollback()
|
||||
return true, err
|
||||
return true, ErrGCConflict
|
||||
}
|
||||
}
|
||||
|
||||
@ -3247,8 +3254,12 @@ func putFile(rsp http.ResponseWriter, r *http.Request, repoID, parentDir, user,
|
||||
desc := fmt.Sprintf("Modified \"%s\"", fileName)
|
||||
_, err = genNewCommit(repo, headCommit, rootID, user, desc, true, gcID, true)
|
||||
if err != nil {
|
||||
err := fmt.Errorf("failed to generate new commit: %v", err)
|
||||
return &appError{err, "", http.StatusInternalServerError}
|
||||
if errors.Is(err, ErrGCConflict) {
|
||||
return &appError{nil, "GC Conflict.\n", http.StatusConflict}
|
||||
} else {
|
||||
err := fmt.Errorf("failed to generate new commit: %v", err)
|
||||
return &appError{err, "", http.StatusInternalServerError}
|
||||
}
|
||||
}
|
||||
|
||||
if isAjax {
|
||||
@ -3485,8 +3496,12 @@ func commitFileBlocks(repoID, parentDir, fileName, blockIDsJSON, user string, fi
|
||||
desc := fmt.Sprintf("Added \"%s\"", fileName)
|
||||
_, err = genNewCommit(repo, headCommit, rootID, user, desc, true, gcID, true)
|
||||
if err != nil {
|
||||
err := fmt.Errorf("failed to generate new commit: %v", err)
|
||||
return "", &appError{err, "", http.StatusInternalServerError}
|
||||
if errors.Is(err, ErrGCConflict) {
|
||||
return "", &appError{nil, "GC Conflict.\n", http.StatusConflict}
|
||||
} else {
|
||||
err := fmt.Errorf("failed to generate new commit: %v", err)
|
||||
return "", &appError{err, "", http.StatusInternalServerError}
|
||||
}
|
||||
}
|
||||
|
||||
return fileID, nil
|
||||
|
@ -1077,8 +1077,12 @@ func putUpdateBranchCB(rsp http.ResponseWriter, r *http.Request) *appError {
|
||||
token = utils.GetAuthorizationToken(r.Header)
|
||||
}
|
||||
if err := fastForwardOrMerge(user, token, repo, base, newCommit); err != nil {
|
||||
err := fmt.Errorf("Fast forward merge for repo %s is failed: %v", repoID, err)
|
||||
return &appError{err, "", http.StatusInternalServerError}
|
||||
if errors.Is(err, ErrGCConflict) {
|
||||
return &appError{nil, "GC Conflict.\n", http.StatusConflict}
|
||||
} else {
|
||||
err := fmt.Errorf("Fast forward merge for repo %s is failed: %v", repoID, err)
|
||||
return &appError{err, "", http.StatusInternalServerError}
|
||||
}
|
||||
}
|
||||
|
||||
go mergeVirtualRepoPool.AddTask(repoID, "")
|
||||
|
@ -24,5 +24,6 @@
|
||||
#define POST_FILE_ERR_QUOTA_FULL 519
|
||||
#define SEAF_ERR_CONCURRENT_UPLOAD 520
|
||||
#define SEAF_ERR_FILES_WITH_SAME_NAME 521
|
||||
#define SEAF_ERR_GC_CONFLICT 522
|
||||
|
||||
#endif
|
||||
|
@ -969,7 +969,8 @@ static int
|
||||
fast_forward_or_merge (const char *repo_id,
|
||||
SeafCommit *base,
|
||||
SeafCommit *new_commit,
|
||||
const char *token)
|
||||
const char *token,
|
||||
gboolean *is_gc_conflict)
|
||||
{
|
||||
#define MAX_RETRY_COUNT 3
|
||||
|
||||
@ -1086,6 +1087,9 @@ retry:
|
||||
&gc_conflict) < 0)
|
||||
{
|
||||
if (gc_conflict) {
|
||||
if (is_gc_conflict) {
|
||||
*is_gc_conflict = TRUE;
|
||||
}
|
||||
seaf_warning ("Head branch update for repo %s conflicts with GC.\n",
|
||||
repo_id);
|
||||
ret = -1;
|
||||
@ -1347,9 +1351,16 @@ put_update_branch_cb (evhtp_request_t *req, void *arg)
|
||||
}
|
||||
}
|
||||
|
||||
if (fast_forward_or_merge (repo_id, base, new_commit, token) < 0) {
|
||||
seaf_warning ("Fast forward merge for repo %s is failed.\n", repo_id);
|
||||
evhtp_send_reply (req, EVHTP_RES_SERVERR);
|
||||
gboolean gc_conflict = FALSE;
|
||||
if (fast_forward_or_merge (repo_id, base, new_commit, token, &gc_conflict) < 0) {
|
||||
if (gc_conflict) {
|
||||
char *msg = "GC Conflict.\n";
|
||||
evbuffer_add (req->buffer_out, msg, strlen (msg));
|
||||
evhtp_send_reply (req, EVHTP_RES_CONFLICT);
|
||||
} else {
|
||||
seaf_warning ("Fast forward merge for repo %s is failed.\n", repo_id);
|
||||
evhtp_send_reply (req, EVHTP_RES_SERVERR);
|
||||
}
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
@ -579,7 +579,7 @@ retry:
|
||||
if (check_gc && gc_conflict) {
|
||||
seaf_warning ("Head branch update for repo %s conflicts with GC.\n",
|
||||
repo->id);
|
||||
g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_GENERAL, "GC Conflict");
|
||||
g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_GC_CONFLICT, "GC Conflict");
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
|
@ -612,6 +612,9 @@ upload_api_cb(evhtp_request_t *req, void *arg)
|
||||
} else if (error->code == SEAF_ERR_FILES_WITH_SAME_NAME) {
|
||||
error_code = -1;
|
||||
send_error_reply (req, EVHTP_RES_BADREQ, "Too many files with same name.\n");
|
||||
} else if (error->code == SEAF_ERR_GC_CONFLICT) {
|
||||
error_code = -1;
|
||||
send_error_reply (req, EVHTP_RES_CONFLICT, "GC Conflict.\n");
|
||||
}
|
||||
g_clear_error (&error);
|
||||
}
|
||||
@ -811,6 +814,9 @@ upload_blks_api_cb(evhtp_request_t *req, void *arg)
|
||||
error_code = ERROR_BLOCK_MISSING;
|
||||
} else if (error->code == POST_FILE_ERR_QUOTA_FULL) {
|
||||
error_code = ERROR_QUOTA;
|
||||
} else if (error->code == SEAF_ERR_GC_CONFLICT) {
|
||||
error_code = -1;
|
||||
send_error_reply (req, EVHTP_RES_CONFLICT, "GC Conflict.\n");
|
||||
}
|
||||
g_clear_error (&error);
|
||||
}
|
||||
@ -1243,6 +1249,9 @@ upload_ajax_cb(evhtp_request_t *req, void *arg)
|
||||
} else if (error->code == SEAF_ERR_FILES_WITH_SAME_NAME) {
|
||||
error_code = -1;
|
||||
send_error_reply (req, EVHTP_RES_BADREQ, "Too many files with same name.\n");
|
||||
} else if (error->code == SEAF_ERR_GC_CONFLICT) {
|
||||
error_code = -1;
|
||||
send_error_reply (req, EVHTP_RES_CONFLICT, "GC Conflict.\n");
|
||||
}
|
||||
g_clear_error (&error);
|
||||
}
|
||||
@ -1527,6 +1536,9 @@ update_blks_api_cb(evhtp_request_t *req, void *arg)
|
||||
error_code = ERROR_NOT_EXIST;
|
||||
} else if (error->code == POST_FILE_ERR_QUOTA_FULL) {
|
||||
error_code = ERROR_QUOTA;
|
||||
} else if (error->code == SEAF_ERR_GC_CONFLICT) {
|
||||
error_code = -1;
|
||||
send_error_reply (req, EVHTP_RES_CONFLICT, "GC Conflict.\n");
|
||||
}
|
||||
g_clear_error (&error);
|
||||
}
|
||||
@ -1788,6 +1800,9 @@ update_ajax_cb(evhtp_request_t *req, void *arg)
|
||||
if (error) {
|
||||
if (g_strcmp0 (error->message, "file does not exist") == 0) {
|
||||
error_code = ERROR_NOT_EXIST;
|
||||
} else if (error->code == SEAF_ERR_GC_CONFLICT) {
|
||||
error_code = -1;
|
||||
send_error_reply (req, EVHTP_RES_CONFLICT, "GC Conflict.\n");
|
||||
}
|
||||
g_clear_error (&error);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user