Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

XOP-229: stunnel cache improvements

Raise limits to 22 stunnels, idle 5min, age 3h.
Discard cache index entries for endpoints with no tunnels.
Better hashtable initial capacities.
Debug-logging to enable calculation of time saved by cache.

Signed-off-by: Thomas Sanders <thomas.sanders@citrix.com>
  • Loading branch information...
commit edc7752aace9e992041bb007b4533cd5267b9321 1 parent b17ab35
@thomassa thomassa authored
Showing with 27 additions and 12 deletions.
  1. +10 −2 http-svr/xmlrpc_client.ml
  2. +17 −10 stunnel/stunnel_cache.ml
View
12 http-svr/xmlrpc_client.ml
@@ -97,6 +97,7 @@ let get_new_stunnel_id =
(** Returns an stunnel, either from the persistent cache or a fresh one which
has been checked out and guaranteed to work. *)
let get_reusable_stunnel ?use_fork_exec_helper ?write_to_log host port =
+ let start_time = Unix.gettimeofday () in
let found = ref None in
(* 1. First check if there is a suitable stunnel in the cache. *)
begin
@@ -113,10 +114,13 @@ let get_reusable_stunnel ?use_fork_exec_helper ?write_to_log host port =
with Not_found -> ()
end;
match !found with
- | Some x -> x
+ | Some x ->
+ StunnelDebug.debug "get_reusable_stunnel: got from cache in %.2f ms for %s:%d." ((Unix.gettimeofday () -. start_time) *. 1000.) host port;
+ x
| None ->
StunnelDebug.debug "get_reusable_stunnel: stunnel cache is empty; creating a fresh connection to %s:%d" host port;
(* 2. Create a fresh connection and make sure it works *)
+ let start_time_2 = Unix.gettimeofday () in
begin
let max_attempts = 10 in
let attempt_number = ref 0 in
@@ -139,7 +143,11 @@ let get_reusable_stunnel ?use_fork_exec_helper ?write_to_log host port =
done
end;
begin match !found with
- | Some x -> x
+ | Some x ->
+ let now = Unix.gettimeofday () in
+ StunnelDebug.debug "get_reusable_stunnel: done in %.2f ms of which %.2f ms for new stunnel to %s:%d"
+ ((now -. start_time) *. 1000.) ((now -. start_time_2) *. 1000.) host port;
+ x
| None ->
StunnelDebug.error "get_reusable_stunnel: failed to acquire a working stunnel to connect to %s:%d" host port;
raise Stunnel_connection_failed
View
27 stunnel/stunnel_cache.ml
@@ -25,12 +25,21 @@ open D
type endpoint = { host: string; port: int }
+(* Need to limit the absolute number of stunnels as well as the maximum age *)
+let max_stunnel = 22
+let max_age = 180. *. 60. (* seconds *)
+let max_idle = 5. *. 60. (* seconds *)
+
+(* The add function adds the new stunnel before doing gc, so the cache *)
+(* can briefly contain one more than maximum. *)
+let capacity = max_stunnel + 1
+
(** An index of endpoints to stunnel IDs *)
-let index : (endpoint, int list) Hashtbl.t ref = ref (Hashtbl.create 10)
+let index : (endpoint, int list) Hashtbl.t ref = ref (Hashtbl.create capacity)
(** A mapping of stunnel unique IDs to donation times *)
-let times : (int, float) Hashtbl.t ref = ref (Hashtbl.create 10)
+let times : (int, float) Hashtbl.t ref = ref (Hashtbl.create capacity)
(** A mapping of stunnel unique ID to Stunnel.t *)
-let stunnels : (int, Stunnel.t) Hashtbl.t ref = ref (Hashtbl.create 10)
+let stunnels : (int, Stunnel.t) Hashtbl.t ref = ref (Hashtbl.create capacity)
open Pervasiveext
open Threadext
@@ -38,11 +47,6 @@ open Listext
let m = Mutex.create ()
-(* Need to limit the absolute number of stunnels as well as the maximum age *)
-let max_stunnel = 4
-let max_age = 5. *. 60. (* seconds *)
-let max_idle = 2. *. 60. (* seconds *)
-
let id_of_stunnel stunnel =
Opt.default "unknown" (Opt.map string_of_int stunnel.Stunnel.unique_id)
@@ -95,10 +99,13 @@ let unlocked_gc () =
let s = Hashtbl.find !stunnels id in
Stunnel.disconnect s) !to_gc;
(* Remove all reference to them from our cache hashtables *)
- let index' = Hashtbl.create 10 in
+ let index' = Hashtbl.create capacity in
Hashtbl.iter
(fun ep ids ->
- Hashtbl.add index' ep (List.filter (fun id -> not(List.mem id !to_gc)) ids)) !index;
+ let kept_ids = (List.filter (fun id -> not(List.mem id !to_gc)) ids) in
+ if kept_ids != [] then Hashtbl.add index' ep kept_ids
+ else ()
+ ) !index;
let times' = Hashtbl.copy !times in
List.iter (fun idx -> Hashtbl.remove times' idx) !to_gc;
let stunnels' = Hashtbl.copy !stunnels in
Please sign in to comment.
Something went wrong with that request. Please try again.