From f6ef7584f281ba1335958bdc79186fc4400adc7a Mon Sep 17 00:00:00 2001 From: Mark Wooding Date: Tue, 2 Jun 2020 11:06:44 +0100 Subject: [PATCH] bin/disorder-notify: Use `select' to read the log in non-blocking mode. This involves handling the line splitting ourselves, but this is quite straightforward in Perl. --- bin/disorder-notify | 68 ++++++++++++++++++++++++++++++++++------------------- 1 file changed, 44 insertions(+), 24 deletions(-) diff --git a/bin/disorder-notify b/bin/disorder-notify index c68e50c..3c57073 100755 --- a/bin/disorder-notify +++ b/bin/disorder-notify @@ -187,36 +187,56 @@ sub watch_and_notify0 ($) { notify "$TITLE: Now playing", format_now_playing %$info; } - while (my $line = readline $sk_log) { - my @f = split_fields $line; - - if ($f[1] eq "state") { - my $msg = undef; - if ($f[2] eq "disable_random") { $msg = "Random play disabled"; } - elsif ($f[2] eq "enable_random") { $msg = "Random play enabled"; } - elsif ($f[2] eq "disable_play") { $msg = "Playing disabled"; } - elsif ($f[2] eq "enable_play") { $msg = "Playing enabled"; } - elsif ($f[2] eq "pause") { $msg = "Paused"; } - elsif ($f[2] eq "resume") { $msg = "Playing"; } - notify "$TITLE state", $msg if defined $msg; - } elsif ($f[1] eq "playing") { - my %info; - $info{track} = $f[2]; - $info{submitter} = $f[3] if @f > 3; - decode_track_name $sk, %info; - notify "$TITLE: Now playing", format_now_playing %info; - } elsif ($f[1] eq "scratched") { - my %info; - $info{track} = $f[2]; - decode_track_name $sk, %info; - notify "$TITLE: Scratched by $f[3]", format_now_playing %info; + fcntl $sk_log, F_SETFL, (fcntl $sk_log, F_GETFL, 0) | O_NONBLOCK; + my $buffer = ""; + my @lines = (); + my $rdin = ""; vec($rdin, (fileno $sk_log), 1) = 1; + + WATCH: for (;;) { + for my $line (@lines) { + my @f = split_fields $line; + if ($f[1] eq "state") { + my $msg = undef; + if ($f[2] eq "disable_random") { $msg = "Random play disabled"; } + elsif ($f[2] eq "enable_random") { $msg = "Random play enabled"; } + elsif ($f[2] eq "disable_play") { $msg = "Playing disabled"; } + elsif ($f[2] eq "enable_play") { $msg = "Playing enabled"; } + elsif ($f[2] eq "pause") { $msg = "Paused"; } + elsif ($f[2] eq "resume") { $msg = "Playing"; } + notify "$TITLE state", $msg if defined $msg; + } elsif ($f[1] eq "playing") { + my %info; + $info{track} = $f[2]; + $info{submitter} = $f[3] if @f > 3; + decode_track_name $sk, %info; + notify "$TITLE: Now playing", format_now_playing %info; + } elsif ($f[1] eq "scratched") { + my %info; + $info{track} = $f[2]; + decode_track_name $sk, %info; + notify "$TITLE: Scratched by $f[3]", format_now_playing %info; + } } + + last WATCH unless $sk_log; + select my $rdout = $rdin, undef, undef, undef; + READ: for (;;) { + my ($b, $n); + eval { $n = sysread $sk_log, $b, 4096; }; + if ($@ && $@->errno == EAGAIN) { last READ; } + elsif ($@) { die $@; } + elsif (!$n) { close $sk_log; $sk_log = undef; } + else { $buffer .= $b; } + } + + @lines = split /\n/, $buffer, -1; + $buffer = pop @lines; } notify "$TITLE state", "Lost connection"; close $sk; - close $sk_log; + close $sk_log if defined $sk_log; } sub watch_and_notify ($) { -- 2.11.0