Skip to content
Browse files

Timeout on receive too

  • Loading branch information...
1 parent cbd5489 commit 116b695cb4827d6ac89cd7893da8631584454f31 Tony Hannan committed Jun 20, 2011
Showing with 15 additions and 15 deletions.
  1. +3 −3 src/mongo.erl
  2. +11 −11 src/mongo_connect.erl
  3. +1 −1 src/mongo_replset.erl
View
6 src/mongo.erl
@@ -52,7 +52,7 @@
connect (Host) -> mongo_connect:connect (Host).
-spec connect (host(), timeout()) -> {ok, connection()} | {error, reason()}. % IO
-%@doc Connect to given MongoDB server
+%@doc Connect to given MongoDB server. Timeout used for initial connection and every query and safe write.
connect (Host, TimeoutMS) -> mongo_connect:connect (Host, TimeoutMS).
-spec disconnect (connection()) -> ok. % IO
@@ -77,7 +77,7 @@ connect_factory (Host, TimeoutMS) -> {Host, fun (H) -> connect (H, TimeoutMS) en
rs_connect (Replset) -> mongo_replset:connect (Replset).
-spec rs_connect (replset(), timeout()) -> rs_connection(). % IO
-%@doc Create new cache of connections to replica set members starting with seed members. No connection attempted until rs_primary or rs_secondary_ok called.
+%@doc Create new cache of connections to replica set members starting with seed members. No connection attempted until rs_primary or rs_secondary_ok called. Timeout used for initial connection and every query and safe write.
rs_connect (Replset, TimeoutMS) -> mongo_replset:connect (Replset, TimeoutMS).
-spec rs_disconnect (rs_connection()) -> ok. % IO
@@ -130,7 +130,7 @@ do (WriteMode, ReadMode, Connection, Database, Action) -> case connection_mode (
-spec connection_mode (read_mode(), connection() | rs_connection()) -> {ok, connection()} | {error, reason()}. % IO
%@doc For rs_connection return appropriate primary or secondary connection
-connection_mode (_, Conn = {connection, _, _}) -> {ok, Conn};
+connection_mode (_, Conn = {connection, _, _, _}) -> {ok, Conn};
connection_mode (master, RsConn = {rs_connection, _, _, _}) -> mongo_replset:primary (RsConn);
connection_mode (slave_ok, RsConn = {rs_connection, _, _, _}) -> mongo_replset:secondary_ok (RsConn).
View
22 src/mongo_connect.erl
@@ -37,7 +37,7 @@ read_host (UString) -> case string:tokens (bson:str (UString), ":") of
-type reason() :: any().
--opaque connection() :: {connection, host(), mvar:mvar (gen_tcp:socket())}.
+-opaque connection() :: {connection, host(), mvar:mvar (gen_tcp:socket()), timeout()}.
% Thread-safe, TCP connection to a MongoDB server.
% Passive raw binary socket.
% Type not opaque to mongo:connection_mode/2
@@ -47,35 +47,35 @@ read_host (UString) -> case string:tokens (bson:str (UString), ":") of
connect (Host) -> connect (Host, infinity).
-spec connect (host(), timeout()) -> {ok, connection()} | {error, reason()}. % IO
-%@doc Create connection to given MongoDB server or return reason for connection failure.
+%@doc Create connection to given MongoDB server or return reason for connection failure. Timeout is used for initial connection and every call.
connect (Host, TimeoutMS) -> try mvar:create (fun () -> tcp_connect (host_port (Host), TimeoutMS) end, fun gen_tcp:close/1)
- of VSocket -> {ok, {connection, host_port (Host), VSocket}}
+ of VSocket -> {ok, {connection, host_port (Host), VSocket, TimeoutMS}}
catch Reason -> {error, Reason} end.
-spec conn_host (connection()) -> host().
%@doc Host this is connected to
-conn_host ({connection, Host, _VSocket}) -> Host.
+conn_host ({connection, Host, _VSocket, _}) -> Host.
-spec close (connection()) -> ok. % IO
%@doc Close connection.
-close ({connection, _Host, VSocket}) -> mvar:terminate (VSocket).
+close ({connection, _Host, VSocket, _}) -> mvar:terminate (VSocket).
-spec is_closed (connection()) -> boolean(). % IO
%@doc Has connection been closed?
-is_closed ({connection, _, VSocket}) -> mvar:is_terminated (VSocket).
+is_closed ({connection, _, VSocket, _}) -> mvar:is_terminated (VSocket).
-type dbconnection() :: {mongo_protocol:db(), connection()}.
-type failure() :: {connection_failure, connection(), reason()}.
-spec call (dbconnection(), [mongo_protocol:notice()], mongo_protocol:request()) -> mongo_protocol:reply(). % IO throws failure()
%@doc Synchronous send and reply. Notices are sent right before request in single block. Exclusive access to connection during entire call.
-call ({Db, Conn = {connection, _Host, VSocket}}, Notices, Request) ->
+call ({Db, Conn = {connection, _Host, VSocket, TimeoutMS}}, Notices, Request) ->
{MessagesBin, RequestId} = messages_binary (Db, Notices ++ [Request]),
Call = fun (Socket) ->
tcp_send (Socket, MessagesBin),
- <<?get_int32 (N)>> = tcp_recv (Socket, 4),
- tcp_recv (Socket, N-4) end,
+ <<?get_int32 (N)>> = tcp_recv (Socket, 4, TimeoutMS),
+ tcp_recv (Socket, N-4, TimeoutMS) end,
try mvar:with (VSocket, Call) of
ReplyBin ->
{RequestId, Reply, <<>>} = mongo_protocol:get_reply (ReplyBin),
@@ -86,7 +86,7 @@ call ({Db, Conn = {connection, _Host, VSocket}}, Notices, Request) ->
-spec send (dbconnection(), [mongo_protocol:notice()]) -> ok. % IO throws failure()
%@doc Asynchronous send (no reply). Don't know if send succeeded. Exclusive access to the connection during send.
-send ({Db, Conn = {connection, _Host, VSocket}}, Notices) ->
+send ({Db, Conn = {connection, _Host, VSocket, _}}, Notices) ->
{NoticesBin, _} = messages_binary (Db, Notices),
Send = fun (Socket) -> tcp_send (Socket, NoticesBin) end,
try mvar:with (VSocket, Send)
@@ -113,6 +113,6 @@ tcp_send (Socket, Binary) -> case gen_tcp:send (Socket, Binary) of
ok -> ok;
{error, Reason} -> throw (Reason) end.
-tcp_recv (Socket, N) -> case gen_tcp:recv (Socket, N) of
+tcp_recv (Socket, N, TimeoutMS) -> case gen_tcp:recv (Socket, N, TimeoutMS) of
{ok, Binary} -> Binary;
{error, Reason} -> throw (Reason) end.
View
2 src/mongo_replset.erl
@@ -38,7 +38,7 @@ rotate (N, List) ->
connect (ReplSet) -> connect (ReplSet, infinity).
-spec connect (replset(), timeout()) -> rs_connection(). % IO
-%@doc Create new cache of connections to replica set members starting with seed members. No connection attempted until primary or secondary_ok called.
+%@doc Create new cache of connections to replica set members starting with seed members. No connection attempted until primary or secondary_ok called. Timeout used for initial connection and every call.
connect ({ReplName, Hosts}, TimeoutMS) ->
Dict = dict:from_list (lists:map (fun (Host) -> {mongo_connect:host_port (Host), {}} end, Hosts)),
{rs_connection, ReplName, mvar:new (Dict), TimeoutMS}.

0 comments on commit 116b695

Please sign in to comment.
Something went wrong with that request. Please try again.