From 44a1c6606cf06d78ca82349c8b1cf11734bb0808 Mon Sep 17 00:00:00 2001 From: "Damien F. Katz" Date: Thu, 26 Feb 2009 21:01:24 +0000 Subject: Fix and test for file descriptor leaks git-svn-id: https://svn.apache.org/repos/asf/couchdb/trunk@748299 13f79535-47bb-0310-9956-ffa450edef68 --- src/couchdb/Makefile.am | 2 - src/couchdb/couch_file.erl | 10 +++-- src/couchdb/couch_file_stats.erl | 68 ---------------------------------- src/couchdb/couch_stats_aggregator.erl | 1 + 4 files changed, 8 insertions(+), 73 deletions(-) delete mode 100644 src/couchdb/couch_file_stats.erl (limited to 'src') diff --git a/src/couchdb/Makefile.am b/src/couchdb/Makefile.am index dc48c983..51e4878c 100644 --- a/src/couchdb/Makefile.am +++ b/src/couchdb/Makefile.am @@ -51,7 +51,6 @@ source_files = \ couch_external_manager.erl \ couch_external_server.erl \ couch_file.erl \ - couch_file_stats.erl \ couch_httpd.erl \ couch_httpd_db.erl \ couch_httpd_external.erl \ @@ -92,7 +91,6 @@ compiled_files = \ couch_external_manager.beam \ couch_external_server.beam \ couch_file.beam \ - couch_file_stats.beam \ couch_httpd.beam \ couch_httpd_db.beam \ couch_httpd_external.beam \ diff --git a/src/couchdb/couch_file.erl b/src/couchdb/couch_file.erl index d1103030..364eafd6 100644 --- a/src/couchdb/couch_file.erl +++ b/src/couchdb/couch_file.erl @@ -35,7 +35,6 @@ open(Filepath, Options) -> case gen_server:start_link(couch_file, {Filepath, Options, self(), Ref = make_ref()}, []) of {ok, Fd} -> - couch_file_stats:track_file(Fd), {ok, Fd}; ignore -> % get the error @@ -270,6 +269,7 @@ init_status_error(ReturnPid, Ref, Error) -> % server functions init({Filepath, Options, ReturnPid, Ref}) -> + process_flag(trap_exit, true), case lists:member(create, Options) of true -> filelib:ensure_dir(Filepath), @@ -285,12 +285,14 @@ init({Filepath, Options, ReturnPid, Ref}) -> true -> {ok, 0} = file:position(Fd, 0), ok = file:truncate(Fd), + couch_stats_collector:increment({couchdb, os_files_open}), {ok, Fd}; false -> ok = file:close(Fd), init_status_error(ReturnPid, Ref, file_exists) end; false -> + couch_stats_collector:increment({couchdb, os_files_open}), {ok, Fd} end; Error -> @@ -302,6 +304,7 @@ init({Filepath, Options, ReturnPid, Ref}) -> {ok, Fd_Read} -> {ok, Fd} = file:open(Filepath, [read, write, raw, binary]), ok = file:close(Fd_Read), + couch_stats_collector:increment({couchdb, os_files_open}), {ok, Fd}; Error -> init_status_error(ReturnPid, Ref, Error) @@ -310,6 +313,7 @@ init({Filepath, Options, ReturnPid, Ref}) -> terminate(_Reason, _Fd) -> + couch_stats_collector:decrement({couchdb, os_files_open}), ok. @@ -345,5 +349,5 @@ handle_cast(close, Fd) -> code_change(_OldVsn, State, _Extra) -> {ok, State}. -handle_info(foo, Fd) -> - {stop, foo, Fd}. +handle_info({'EXIT', _, Reason}, Fd) -> + {stop, Reason, Fd}. diff --git a/src/couchdb/couch_file_stats.erl b/src/couchdb/couch_file_stats.erl deleted file mode 100644 index 5e7d550b..00000000 --- a/src/couchdb/couch_file_stats.erl +++ /dev/null @@ -1,68 +0,0 @@ -% Licensed under the Apache License, Version 2.0 (the "License"); you may not -% use this file except in compliance with the License. You may obtain a copy of -% the License at -% -% http://www.apache.org/licenses/LICENSE-2.0 -% -% Unless required by applicable law or agreed to in writing, software -% distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -% WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -% License for the specific language governing permissions and limitations under -% the License. - --module(couch_file_stats). --behaviour(gen_server). - --export([init/1, terminate/2, handle_call/3, handle_cast/2, code_change/3, - handle_info/2]). - --export([start_link/0,track_file/1,get_stats/0]). - --record(stats,{ - opened=0, - closed=0 - }). - - -track_file(Fd) -> - catch gen_server:cast(couch_file_stats, {track, Fd}). - - -get_stats() -> - #stats{opened=Opened,closed=Closed}=gen_server:call(couch_file_stats,get), - [{files_open,Opened-Closed}, {files_closed,Closed}]. - - -start_link() -> - gen_server:start_link({local, couch_file_stats}, couch_file_stats, [], []). - - -init([]) -> - {ok, #stats{}}. - - -terminate(_Reason, _Fd) -> - ok. - - -handle_call(get, _From, Stats) -> - {reply, Stats, Stats}. - - -handle_cast({track, Fd}, #stats{opened=Opened,closed=Closed}=Stats) -> - try erlang:monitor(process, Fd) of - _Ref -> - {noreply, Stats#stats{opened=Opened+1}} - catch - _Error -> - {noreply, Stats#stats{opened=Opened+1, closed=Closed+1}} - end. - - -handle_info({'DOWN',_MonRef,_Type,_Pid,_Info}, #stats{closed=Closed}=Stats) -> - {noreply, Stats#stats{closed=Closed+1}}. - - -code_change(_OldVsn, State, _Extra) -> - {ok, State}. - diff --git a/src/couchdb/couch_stats_aggregator.erl b/src/couchdb/couch_stats_aggregator.erl index 2a1e5797..eef8f22f 100644 --- a/src/couchdb/couch_stats_aggregator.erl +++ b/src/couchdb/couch_stats_aggregator.erl @@ -299,6 +299,7 @@ init_descriptions() -> ets:insert(?MODULE, {{couchdb, database_changes}, <<"Number of times a database was changed">>}), ets:insert(?MODULE, {{couchdb, database_reads}, <<"Number of times a document was read from a database">>}), ets:insert(?MODULE, {{couchdb, open_databases}, <<"Number of open databases">>}), + ets:insert(?MODULE, {{couchdb, os_files_open}, <<"Number of file descriptors CouchDB has open.">>}), ets:insert(?MODULE, {{couchdb, request_time}, <<"Length of a request inside CouchDB without Mochiweb">>}), ets:insert(?MODULE, {{http_status_codes, '200'}, <<"Number of HTTP 200 OK responses">>}), -- cgit v1.2.3