Commits

Jacob Perkins committed 5628b65

emongo can somewhat gracefully handle tcp_closed and reconnect later, vsn 0.0.5

Comments (0)

Files changed (3)

 {application, emongo, [
 	{description, "Erlang MongoDB Driver"},
-	{vsn, "0.0.4"},
+	{vsn, "0.0.5"},
 	{modules, [
 		emongo, emongo_app, emongo_sup, emongo_bson, emongo_packet,
 		emongo_server, emongo_server_sup, emongo_collection
-{"0.0.4", [
+{"0.0.5", [
+	{"0.0.4", [
+		{load_module, emongo_bson},
+		{load_module, emongo}
+	]},
 	{"0.0.3", [{add_module, emongo_collection}]},
 	{"0.0.2", [
 		{load_module, emongo},
 		{apply, {emongo_app, initialize_pools, []}}
 	]}
 ], [
+	{"0.0.4", [
+		{load_module, emongo_bson},
+		{load_module, emongo}
+	]},
 	{"0.0.3", [{delete_module, emongo_collection}]},
 	{"0.0.2", [
 		{load_module, emongo},
 				database=Database,
 				size=Size
 			},
-			{ok, _SupPid} = emongo_sup:start_pool(PoolId, Host, Port),
+			emongo_sup:start_pool(PoolId, Host, Port),
 			Pool1 = do_open_connections(Pool),
 			Pools1 = [{PoolId, Pool1} | Pools];
 		Pool ->
 	
 	{reply, ok, State#state{pools=Pools1}};
 
+handle_call({pid, PoolId1}, From, #state{pools=[]}=State) ->
+	F = fun({PoolId, Props}, State1) ->
+			Host = proplists:get_value(host, Props, "localhost"),
+			Port = proplists:get_value(port, Props, 27017),
+			Database = proplists:get_value(database, Props, "test"),
+			Size = proplists:get_value(size, Props, 1),
+			Req = {add_pool, PoolId, Host, Port, Database, Size},
+			{reply, ok, State2} = handle_call(Req, From, State1),
+			State2
+		end,
+	
+	case application:get_env(emongo, pools) of
+		undefined ->
+			{reply, {undefined, undefined}, State};
+		{ok, []} ->
+			{reply, {undefined, undefined}, State};
+		{ok, Pools} ->
+			NewState = lists:foldl(F, State, Pools),
+			handle_call({pid, PoolId1}, From, NewState)
+	end;
 handle_call({pid, PoolId}, _From, #state{pools=Pools}=State) ->
 	case lists:keytake(PoolId, 1, Pools) of
 		false ->
 %%                                       {stop, Reason, State}
 %% Description: Handling all non call/cast messages
 %%--------------------------------------------------------------------
-%handle_info({'EXIT', Pid, {PoolId, tcp_closed}}, #state{pools=Pools}=State) ->
-	%io:format("EXIT ~p, {~p, tcp_closed}~n", [Pid, PoolId]),
-	%State1 =
-		%case get_pool(PoolId, Pools) of
-			%undefined ->
-				%State;
-			%{Pool, Others} ->
-				%Pids1 = queue:filter(fun(Item) -> Item =/= Pid end, Pool#pool.conn_pids),
-				%Pool1 = Pool#pool{conn_pids = Pids1},
-				%Pool2 = do_open_connections(Pool1),
-				%Pools1 = [{PoolId, Pool2}|Others],
-				%State#state{pools=Pools1}
-		%end,
-	%{noreply, State1};
+handle_info({'EXIT', _Pid, {PoolId, tcp_closed}}, #state{pools=Pools}=State) ->
+	case lists:keytake(PoolId, 1, Pools) of
+		false ->
+			{noreply, State};
+		{value, {PoolId, Pool}, Others} ->
+			Pool1 = do_open_connections(Pool),
+			{noreply, State#state{pools=[{PoolId, Pool1} | Others]}}
+	end;
 
 handle_info(_Info, State) ->
     {noreply, State}.
 do_open_connections(#pool{size=Size}=Pool) ->
 	% each connection is an emongo_server supervised by simple_one_for_one
 	% emongo_server_sup supervisor
-	F = fun(_) -> {ok, _} = emongo_server_sup:start_child(Pool#pool.id) end,
-	lists:foreach(F, lists:seq(1, Size)),
+	F = fun(_) -> catch emongo_server_sup:start_child(Pool#pool.id) end,
+	
+	case Size - emongo_server_sup:child_count(Pool#pool.id) of
+		I when I < 1 -> ok;
+		I -> lists:foreach(F, lists:seq(1, I))
+	end,
+	
 	Pool.
 
 dec2hex(Dec) ->