savonet / liquidsoap

Liquidsoap is a statically typed scripting general-purpose language with dedicated operators and backend for all thing media, streaming, file generation, automation, HTTP backend and more.
http://liquidsoap.info
GNU General Public License v2.0
1.39k stars 128 forks source link

on_connect/on_disconnect for input.http #234

Closed toots closed 5 years ago

toots commented 9 years ago

ditto

S54B32 commented 9 years ago

I'm trying to write a function for on_connect and on_disconnect for input.http. I have it working, BUT it seems to run the function twice whenever I get a connect/disconnect event. So in this case the echo command I run is executed twice every time. My function is:

Function On Main Connect def main_start(start) = system("echo $(date) " ^ name ^ " main_input started! >> " ^ connection.log) log(name ^ "main_input started!") end

Any ideas? Thank you

S54B32 commented 9 years ago

Toots were you able to replicate this? Have you found a remedy? Thanks

smimram commented 9 years ago

As a temporary fix, you can prevent the function from running twice using a reference. Something like:

already = ref false

def main_start(start) =
  if not !already then
    already := true
    system("echo $(date) " ^ name ^ " main_input started! >> " ^ connection.log)
    log(name ^ "main_input started!")
  end
end
toots commented 9 years ago

Quick glance at the code didn't seem to show any obvious cause for this issue. Could you describe us in more details what you are trying to do?

dbaelde commented 9 years ago

While we're looking at this I'm noticing typos in the on_disconnect doc: "excecute" should be "execute" and there should be a dot at the end of the doc. I would fix it right now but there's also a strange wording for on_connect and I don't know how to fix it: "Function to execute when a source is connected" is strange because it seems to talk about liquidsoap sources, whereas as far as I understand on_connect is about connecting to an HTTP stream.

dbaelde commented 9 years ago

I tried to reproduce the issue with a minimal setup but did not succeed. I ran

output.icecast(%vorbis,mount="toto.ogg",mksafe(playlist("~/media/audio")))

to create an HTTP stream and then ran

output.dummy(fallible=true,input.http("http://localhost:8000/toto.ogg",on_connect=fun(_)->log("XXXXXXXXXXXXXXXXX")))

to connect to it, but I saw only one line of XXX... in my logs.

dbaelde commented 9 years ago

By the way, what was the initial purpose of this issue? I thought it was a feature request, but we already have the feature. Now it has become a bug report... we should perhaps update the title.

toots commented 9 years ago

You're right on the initial intent for this ticket. I'll be closing it for now until we have more info on how to reproduce the issue.

S54B32 commented 8 years ago

Hi dbaelde and toots, I didn't realise you guys had responded! Thanks for the replies.

To clarify, this was a bug report - my code was producing some strange results. Basically, these two functions are run when a HTTP harbour is connected/disconnected. My functions are doing the following when the HTTP harbour disconnects/connects: Write a line to a log file Write a 1 or 0 to a second log file Write a log entry in the liquidsoap log

My code is as follows:

# Function On Main Connect
def main_start(start) =
    system("echo " ^ date.cmd ^ " " ^ name ^ " main_input started! >> " ^ connection.log)
    system("echo [1] > " ^ main.input.status)
    log(name ^ " main_input started!")
end

# Function On Main Disconnect
def main_stop( )=
    system("echo " ^ date.cmd ^ " " ^ name ^ " main_input stopped! >> " ^ connection.log)
    system("echo [0] > " ^ main.input.status)
    log(name ^ " main_input stopped!")
end

My main_start function works as expected. The issue I have is that the disconnect function is run twice and writes two log entries to the connection.log and main.input.status files that I have defined in my script.

Am I missing something in my code?

Thanks again :-)

Edit to say, smimram, thank you for suggesting the temporary workaround. I'm yet to try this with my code. I would of course rather have a working method than using a workaround if possible but I will try and experiment with it tomorrow.

S54B32 commented 8 years ago

I have tested the workaround that smimram suggested and have found some odd results. The workaround does work but only for the first attempt.

Here is what happens with the harbour and the log result when I start the liq. Connect to harbour - main_input started! Disconnect from harbour - main_input stopped! Connect to harbour - main_input started! Disconnect - no log entry Connect to harbour - main_input started! Disconnect - no log entry Connect to harbour - main_input started!

and so on. The workaround only works for the first attempt.

Any other ideas are greatly appreciated. Thanks

smimram commented 8 years ago

A simple modification of the script will allow for the function to be called once every two rounds:

already = ref false

def main_start(start) =
  if not !already then
    already := true
    system("echo $(date) " ^ name ^ " main_input started! >> " ^ connection.log)
    log(name ^ "main_input started!")
  else
    already := false
  end
end
S54B32 commented 8 years ago

Thank you very much for this. Supposed I have four functions, two for when the main harbour starts and stops. And two for when a backup harbour starts and stops. Would I need to add 4 different already = ref false to the code? Or would just one suffice?

And I am struggling to understand why my code for start is setout with: def main_start(start) =

But for my stop I have to use def main_stop( ) =

If I set to def main_stop(stop) =

I get error this value has type ()-> (inferred at line 55 char 1 - line 59 char 3) but it should be a subtype of ()->unit

Thanks very much

S54B32 commented 8 years ago

The fix is working nicely - I have a main harbour and backup habour, each with a on_connect and on_disconnect function. Is there a way to define two functions, one for stop and start and take the value of which harbour has dropped instead of defining a function for each harbour separately?

S54B32 commented 8 years ago

I am still having issues with the fix - I have had to define main_already and backup_already for use with the main and backup harbour. Even still, half the time the stop command should be executed it isn't.

My code:

# Define already so the stop functions aren't run twice on disconnect
main_already = ref false
backup_already = ref false

# Function On Main Connect
def main_start(start) =
    ignore(system("echo " ^ date.cmd ^ " " ^ name ^ " main_input started! >> " ^ connection.log))
    ignore(system("echo [1] > " ^ main.input.status))
    log(name ^ " main_input started!")
end

# Function On Main Disconnect
def main_stop( ) =
    if not !main_already then
        main_already := true
        ignore(system("echo " ^ date.cmd ^ " " ^ name ^ " main_input stopped! >> " ^ connection.log))
        ignore(system("echo [0] > " ^ main.input.status))
        log(name ^ " main_input stopped!")
    else
        main_already := false
    end
end

# Function On Backup Connect
def backup_start(start) =
    ignore(system("echo " ^ date.cmd ^ " " ^ name ^ " backup_input started! >> " ^ connection.log))
    ignore(system("echo [1] > " ^ backup.input.status))
    log(name ^ " backup_input started!")
end

# Function On Backup Disconnect
def backup_stop( ) =
    if not !backup_already then
        backup_already := true
        ignore(system("echo " ^ date.cmd ^ " " ^ name ^ " backup_input stopped! >> " ^ connection.log))
        ignore(system("echo [0] > " ^ backup.input.status))
        log(name ^ " backup_input stopped!")
    else
        backup_already := false
    end
end

Any ideas would be massively appreciated Thanks

S54B32 commented 8 years ago

I fixed my code!

All I had to do was remove the space in: def backup_stop( ) =

so it becomes: def backup_stop() =

I'm not sure if this is expected behaviour with Liquidsoap or a potential issue...

Thanks for your advice and creating a fantastic utility!

toots commented 8 years ago

@S54B32 I think we'd need to see more context from your script to be able to assess the issue further. So far, I'll mark it as not reproducible..

stale[bot] commented 5 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

stale[bot] commented 5 years ago

This issue was closed for lack of activity. If you believe that it is still relevant, please confirm that it applies to the latest released version of liquidsoap and re-open the ticket. Thanks!