I had already raised this question numerous times on IRC, so I can only agree with you :) We *need* to handle the case where the connection to the Icecast server goes down, either by crashing or (better, of course), by trying to reconnect (liquidsoap doesn't crash everytime the connection goes down, it sometimes just reports error after error and eats 100 % of available CPU power).

I cannot review your patch since I'm neither an Ocaml guru or an expert of this code, so I can't criticize your code or tell you that it'll make Liq go mad ;) Anyway, I'll test it soon and we'll see if it solves my CPU-eating version of the problem ;)

Cordialement,
Vincent Tabard
Radio Pytagor : http://www.radiopytagor.com/



Romain Beauxis a écrit :
        Hi all !

One issue I'd like to raise for next release is the possibility to automatically restart a failed icecast output instead of crashing the whole app...

I need this for our complex install at radiopi, and I think it would be an important feature for some users.

I also understant that not every one want this behaviour, so I think an option could be ideal.

Here is an implementation that seems working quite ok for radiopi.

What's your point on this topic ?


Romain
------------------------------------------------------------------------

Index: src/outputs/icecast2.ml
===================================================================
--- src/outputs/icecast2.ml     (révision 4559)
+++ src/outputs/icecast2.ml     (copie de travail)
@@ -32,7 +32,8 @@
 let proto =
   [ "start", Lang.bool_t, Some (Lang.bool true),
     Some "Start output threads on operator initialization." ;
-
+    "restart", Lang.bool_t, Some (Lang.bool true),
+    Some "Restart output after any failure. If false, liquidsoap will stop if the 
output failed." ;
     "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 ;
@@ -54,7 +55,7 @@
   * value for these depends on the format of the stream (ogg/mp3). *)
 class virtual ['a] output
   ?(format=Shout.Format_vorbis) ?(protocol=Shout.Protocol_http) ?bitrate
-  ~name ~mount ~source p =
+  ~name ~mount ~source ~restart p =
let e f v = f (List.assoc v p) in
     let s v = e Lang.to_string v in
@@ -142,24 +143,35 @@
           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 ->
+                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 ;
+ + self#log#f 3 "Connection setup was successful." ;
+        connection <- Some conn
+      with
+        | e -> if restart then
+ begin + self#log#f 4 "connexion failed: %s, restarting output" (Printexc.to_string e) ; + Thread.delay 1.; + self#output_reset + end + else + raise e - self#log#f 3 "Connection setup was successful." ;
-      connection <- Some conn
-
   method output_reset =
     self#output_stop ;
     self#output_start
Index: src/outputs/lame_encoded.ml
===================================================================
--- src/outputs/lame_encoded.ml (révision 4559)
+++ src/outputs/lame_encoded.ml (copie de travail)
@@ -147,6 +147,7 @@
let stereo = e Lang.to_bool "stereo" in
   let samplerate = e Lang.to_int "samplerate" in
+  let restart = e Lang.to_bool "restart" in
   let bitrate = e Lang.to_int "bitrate" in
   let quality = e Lang.to_int "quality" in
@@ -181,7 +182,7 @@
 object (self)
   inherit
     [Lame.encoder] Icecast2.output ~format:Shout.Format_mp3 ~protocol
-      ~bitrate:(string_of_int bitrate) ~mount ~name ~source p as super
+      ~bitrate:(string_of_int bitrate) ~mount ~name ~source ~restart p as super
method reset_encoder encoder m =
     let get h k l =
Index: src/outputs/vorbis_encoded.ml
===================================================================
--- src/outputs/vorbis_encoded.ml       (révision 4559)
+++ src/outputs/vorbis_encoded.ml       (copie de travail)
@@ -313,6 +313,7 @@
let name = s "name" in
   let mount = s "mount" in
+  let restart =  e Lang.to_bool "restart"  in
   let name =
     if name = no_name then
       if mount = no_mount then
@@ -366,7 +367,7 @@
object (self)
   inherit [Vorbis.Encoder.t] Icecast2.output
-    ~bitrate:ibitrate ~mount ~name ~source p as super
+    ~bitrate:ibitrate ~mount ~name ~source ~restart p as super
   inherit base freq stereo
method new_encoder = ------------------------------------------------------------------------

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
------------------------------------------------------------------------

_______________________________________________
Savonet-devl mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/savonet-devl

Répondre à