summaryrefslogtreecommitdiff
path: root/apps
diff options
context:
space:
mode:
Diffstat (limited to 'apps')
-rw-r--r--apps/couch/src/couch_httpd_db.erl22
-rw-r--r--apps/couch/src/couch_rep.erl8
-rw-r--r--apps/couch/src/couch_rep_changes_feed.erl2
-rw-r--r--apps/couch/src/couch_server.erl30
4 files changed, 37 insertions, 25 deletions
diff --git a/apps/couch/src/couch_httpd_db.erl b/apps/couch/src/couch_httpd_db.erl
index 0bf97e26..6458fe70 100644
--- a/apps/couch/src/couch_httpd_db.erl
+++ b/apps/couch/src/couch_httpd_db.erl
@@ -20,7 +20,7 @@
-import(couch_httpd,
[send_json/2,send_json/3,send_json/4,send_method_not_allowed/2,
- send_response/4,start_json_response/2,start_json_response/3,
+ start_json_response/2,
send_chunk/2,last_chunk/1,end_json_response/1,
start_chunked_response/3, absolute_uri/2, send/2,
start_response_length/4]).
@@ -236,7 +236,7 @@ db_req(#httpd{method='POST',path_parts=[DbName]}=Req, Db) ->
?LOG_INFO("Batch doc error (~s): ~p",[DocId, Error])
end
end),
-
+
send_json(Req, 202, [], {[
{ok, true},
{id, DocId}
@@ -689,7 +689,7 @@ db_doc_req(#httpd{method='PUT'}=Req, Db, DocId) ->
update_type = UpdateType
} = parse_doc_query(Req),
couch_doc:validate_docid(DocId),
-
+
Loc = absolute_uri(Req, "/" ++ ?b2l(Db#db.name) ++ "/" ++ ?b2l(DocId)),
RespHeaders = [{"Location", Loc}],
case couch_util:to_list(couch_httpd:header_value(Req, "Content-Type")) of
@@ -711,7 +711,7 @@ db_doc_req(#httpd{method='PUT'}=Req, Db, DocId) ->
"ok" ->
% batch
Doc = couch_doc_from_req(Req, DocId, couch_httpd:json_body(Req)),
-
+
spawn(fun() ->
case catch(couch_db:update_doc(Db, Doc, [])) of
{ok, _} -> ok;
@@ -776,7 +776,7 @@ send_doc_efficiently(#httpd{mochi_req = MochiReq} = Req,
send_json(Req, 200, Headers, couch_doc:to_json_obj(Doc, Options));
true ->
Boundary = couch_uuids:random(),
- JsonBytes = ?JSON_ENCODE(couch_doc:to_json_obj(Doc,
+ JsonBytes = ?JSON_ENCODE(couch_doc:to_json_obj(Doc,
[attachments, follows, att_encoding_info | Options])),
{ContentType, Len} = couch_doc:len_doc_to_multi_part_stream(
Boundary,JsonBytes, Atts, true),
@@ -793,7 +793,7 @@ send_docs_multipart(Req, Results, Options1) ->
OuterBoundary = couch_uuids:random(),
InnerBoundary = couch_uuids:random(),
Options = [attachments, follows, att_encoding_info | Options1],
- CType = {"Content-Type",
+ CType = {"Content-Type",
"multipart/mixed; boundary=\"" ++ ?b2l(OuterBoundary) ++ "\""},
{ok, Resp} = start_chunked_response(Req, 200, [CType]),
couch_httpd:send_chunk(Resp, <<"--", OuterBoundary/binary>>),
@@ -811,8 +811,8 @@ send_docs_multipart(Req, Results, Options1) ->
({{not_found, missing}, RevId}) ->
RevStr = couch_doc:rev_to_str(RevId),
Json = ?JSON_ENCODE({[{"missing", RevStr}]}),
- couch_httpd:send_chunk(Resp,
- [<<"\r\nContent-Type: application/json; error=\"true\"\r\n\r\n">>,
+ couch_httpd:send_chunk(Resp,
+ [<<"\r\nContent-Type: application/json; error=\"true\"\r\n\r\n">>,
Json,
<<"\r\n--", OuterBoundary/binary>>])
end, Results),
@@ -848,7 +848,7 @@ receive_request_data(Req, LenLeft) when LenLeft > 0 ->
{Data, fun() -> receive_request_data(Req, LenLeft - iolist_size(Data)) end};
receive_request_data(_Req, _) ->
throw(<<"expected more data">>).
-
+
make_content_range(From, To, Len) ->
?l2b(io_lib:format("bytes ~B-~B/~B", [From, To, Len])).
@@ -1078,8 +1078,8 @@ db_attachment_req(#httpd{method=Method,mochi_req=MochiReq}=Req, Db, DocId, FileN
_Else ->
ok
end,
-
-
+
+
fun(Size) -> couch_httpd:recv(Req, Size) end
end,
att_len = case couch_httpd:header_value(Req,"Content-Length") of
diff --git a/apps/couch/src/couch_rep.erl b/apps/couch/src/couch_rep.erl
index 82b69bc9..761fbd76 100644
--- a/apps/couch/src/couch_rep.erl
+++ b/apps/couch/src/couch_rep.erl
@@ -275,7 +275,7 @@ handle_info({'EXIT', _Pid, Reason}, State) ->
terminate(normal, #state{checkpoint_scheduled=nil, init_args=[RepId, _, _, Module]} = State) ->
do_terminate(State),
Module:replication_completed(RepId);
-
+
terminate(normal, #state{init_args=[RepId, _, _, Module]} = State) ->
timer:cancel(State#state.checkpoint_scheduled),
do_terminate(do_checkpoint(State)),
@@ -409,7 +409,7 @@ do_terminate(State) ->
continuous = Continuous,
source_log = #doc{body={OldHistory}}
} = State,
-
+
NewRepHistory = case CheckpointHistory of
nil ->
{[{<<"no_changes">>, true} | OldHistory]};
@@ -504,7 +504,7 @@ make_replication_id({Props}, UserCtx, 1) ->
maybe_append_filters({Props}, [HostName, Src, Tgt], UserCtx).
maybe_append_filters({Props}, Base, UserCtx) ->
- Base2 = Base ++
+ Base2 = Base ++
case couch_util:get_value(<<"filter">>, Props) of
undefined ->
case couch_util:get_value(<<"doc_ids">>, Props) of
@@ -794,7 +794,7 @@ commit_to_both(Source, Target, RequiredSeq) ->
exit(replication_link_failure)
end,
{SourceStartTime, TargetStartTime}.
-
+
ensure_full_commit(#http_db{headers = Headers} = Target) ->
Headers1 = [
{"Content-Length", 0} |
diff --git a/apps/couch/src/couch_rep_changes_feed.erl b/apps/couch/src/couch_rep_changes_feed.erl
index 651069fb..4781b583 100644
--- a/apps/couch/src/couch_rep_changes_feed.erl
+++ b/apps/couch/src/couch_rep_changes_feed.erl
@@ -242,7 +242,7 @@ handle_call({add_change, Row}, From, State) ->
handle_call(next_changes, From, State) ->
handle_next_changes(From, State);
-
+
handle_call(stop, _From, State) ->
{stop, normal, ok, State}.
diff --git a/apps/couch/src/couch_server.erl b/apps/couch/src/couch_server.erl
index f9c960c5..c7850990 100644
--- a/apps/couch/src/couch_server.erl
+++ b/apps/couch/src/couch_server.erl
@@ -199,16 +199,28 @@ try_close_lru(StartTime) ->
% There may exist an extremely small possibility of a race
% condition here, if a process could lookup the DB before the lock,
% but fail to monitor the fd before the is_idle check.
- true = ets:update_element(couch_dbs, DbName, {#db.fd_monitor, locked}),
- [#db{main_pid = Pid} = Db] = ets:lookup(couch_dbs, DbName),
- case couch_db:is_idle(Db) of true ->
- true = ets:delete(couch_dbs, DbName),
- true = ets:delete(couch_lru, DbName),
- exit(Pid, kill),
- ok;
+ %
+ % If we do hit this race condition the behavior is that the process
+ % grabbing the database will end up inserting a value into the
+ % couch_lru table. Its possible that we end up picking that up
+ % as the DbName above to close. So we here we'll just remove the
+ % couch_lru entry and ignore it.
+ case ets:update_element(couch_dbs, DbName, {#db.fd_monitor, locked}) of
+ true ->
+ [#db{main_pid = Pid} = Db] = ets:lookup(couch_dbs, DbName),
+ case couch_db:is_idle(Db) of true ->
+ true = ets:delete(couch_dbs, DbName),
+ true = ets:delete(couch_lru, DbName),
+ exit(Pid, kill),
+ ok;
+ false ->
+ Update = {#db.fd_monitor, nil},
+ true = ets:update_element(couch_dbs, DbName, Update),
+ true = ets:insert(couch_lru, {DbName, now()}),
+ try_close_lru(StartTime)
+ end;
false ->
- true = ets:update_element(couch_dbs, DbName, {#db.fd_monitor, nil}),
- true = ets:insert(couch_lru, {DbName, now()}),
+ true = ets:delete(couch_lru, DbName),
try_close_lru(StartTime)
end
end.