Le Tuesday 11 September 2007 07:50:47 David Baelde, vous avez écrit :
> A possible way to do it: add an instance variable containing the time
> of the last connection attempt. If an attempt fails, just update it.
> At every output round (method send), if there is no connection, and
> the previous attempt was long ago (say, 3 seconds) try to start the
> output. This will be less violent, also the connection in the middle
> of streaming might cause a little latency if the server doesn't
> respond quickly... that's probably reasonable as a first
> implementation.

Here is the patch I just commited..


Romain
-- 
mama say
son, you've got to stay home today
there's a hole in the roof
you've got to make it waterproof
Index: outputs/icecast2.ml
===================================================================
--- outputs/icecast2.ml	(révision 4559)
+++ outputs/icecast2.ml	(copie de travail)
@@ -32,7 +32,11 @@
 let proto =
   [ "start", Lang.bool_t, Some (Lang.bool true),
     Some "Start output threads on operator initialization." ;
-
+    "restart", Lang.bool_t, Some (Lang.bool false),
+    Some "Restart output after a failure. By default, liquidsoap will stop if the 
+    output failed. Wrong user or password are not afected by this option" ;
+    "restart_delay", Lang.int_t, Some (Lang.int 3),
+    Some "Delay, in decond, before attempting new connection, if restart is enabled." ;
     "host", Lang.string_t, Some (Lang.string "localhost"), None ;
     "port", Lang.int_t, Some (Lang.int 8000), None ;
     "user", Lang.string_t, Some (Lang.string "source"), None ;
@@ -60,7 +64,8 @@
     let s v = e Lang.to_string v in
 
     let autostart = e Lang.to_bool "start" in
-
+    let restart = e Lang.to_bool "restart" in
+    let restart_delay = float_of_int (e Lang.to_int "restart_delay") in
     let host = s "host" in
     let port = e Lang.to_int "port" in
     let user = s "user" in
@@ -78,6 +83,7 @@
     as super
 
   val mutable connection = None
+  val mutable last_attempt = -1.
 
   initializer
     if sync then
@@ -85,20 +91,29 @@
 
   method send b =
     match connection with
-      | None -> assert false
+      | None -> if restart && 
+                   (last_attempt = -1. 
+		     || 
+		   ((Unix.time ()) -. last_attempt) > restart_delay) 
+                  then 
+                begin
+		  self#output_start ;
+		  self#send b
+		end
+		  else if not restart then
+		failwith "shout connection failed!"
       | Some c ->
           (* TODO think about some limitation of shout restarting *)
-          begin try
-            if sync then Shout.sync c ;
-            Shout.send c b
-          with
-            | Shout.Socket ->
-                self#log#f 3 "%s"
-                  ("Shout socket error: timeout, network failure, "^
-                   "server shutdown? Restarting the output...") ;
-                stop_output <- true ;
-                start_output <- true
-          end
+            begin try
+              if sync then Shout.sync c ;
+              Shout.send c b
+            with
+              | Shout.Socket ->
+                  self#log#f 3 "%s"
+                    ("Shout socket error: timeout, network failure, "^
+                     "server shutdown? Restarting the output...") ;
+		     last_attempt <- Unix.time ()
+            end
 
   method output_stop =
     match connection with
@@ -142,24 +157,39 @@
           Configure.version
           (get_agent conn)) ;
 
-      begin
-        try
-          open_shout conn ;
-        with
-          | No_connect ->
-              failwith
-                (Printf.sprintf
-                   "unable to connect to icecast server %s:%d!"
-                   host port)
-          | Socket ->
-              failwith "invalid user or password for icecast login!"
-          | No_login ->
-              failwith "icecast mount point already taken, or wrong password!"
-      end ;
+      (* Final *)
+      try
+        begin
+          try
+            open_shout conn ;
+          with
+            | No_connect as e ->
+                  self#log#f 3
+                     "unable to connect to icecast server %s:%d!"
+                     host port ;
+		  raise e
+            | Socket as e ->
+                self#log#f 3  "invalid user or password for icecast login!" ;
+		raise e
+            | No_login as e ->
+                self#log#f 3 "icecast mount point already taken, or wrong password!" ;
+		raise e
+        end ;
+  
+        self#log#f 3 "Connection setup was successful." ;
+        connection <- Some conn
+      with
+        | No_connect | No_login as e -> 
+	      if restart then
+	           begin 
+	             self#log#f 3 "connection failed, restarting output in %d sec" 
+		     (int_of_float restart_delay);
+		     self#output_stop ;
+		     last_attempt <- Unix.time ()
+		   end
+	       else 
+	         raise e
 
-      self#log#f 3 "Connection setup was successful." ;
-      connection <- Some conn
-
   method output_reset =
     self#output_stop ;
     self#output_start

Répondre à