diff options
author | Eric Wong <normalperson@yhbt.net> | 2013-09-01 02:06:51 +0000 |
---|---|---|
committer | Eric Wong <normalperson@yhbt.net> | 2013-09-01 02:12:13 +0000 |
commit | 0208f3bfd132d58c31d5db06db6378277fa71c7b (patch) | |
tree | 8ed0c5b21b7bc12f7f7f891a6454a88014bdc29b | |
parent | 53b984b1e054a0804884ee83e2debe5baea8a222 (diff) | |
download | dtas-0208f3bfd132d58c31d5db06db6378277fa71c7b.tar.gz |
This helps in case dtas-player is hit with SIGKILL or the system crashes. This does not fsync(2) as that could introduce delays on slow filesystems. Users should open the file manually and fsync themselves if they need to.
-rw-r--r-- | Documentation/dtas-player_protocol.txt | 8 | ||||
-rw-r--r-- | lib/dtas/player.rb | 2 | ||||
-rw-r--r-- | lib/dtas/player/client_handler.rb | 21 | ||||
-rw-r--r-- | lib/dtas/state_file.rb | 2 | ||||
-rw-r--r-- | test/test_player_integration.rb | 18 |
5 files changed, 51 insertions, 0 deletions
diff --git a/Documentation/dtas-player_protocol.txt b/Documentation/dtas-player_protocol.txt index efbd065..b431180 100644 --- a/Documentation/dtas-player_protocol.txt +++ b/Documentation/dtas-player_protocol.txt @@ -203,6 +203,14 @@ Commands here should be alphabetized according to `LC_ALL=C sort' 1. input type (flac/opus/mp3/etc) 2. transport protocol (local FS/http/ftp/sftp/etc) +* state dump [FILENAME] + Immediately dump the state of the player. If a FILENAME is specified, + the state is written to that file. Otherwise, the default state file + (configured via DTAS_PLAYER_STATE environment variable, defaulting + to ~/.dtas/player_state.yml) is written to. This does not use fsync(2), + users requiring fsync should open(2) that file and fsync(2) it + themselves if necessary. + * watch - adds the client to the passive watch list for notifications. It is recommended clients issue no further commands and open another client socket to issue non-watch commands. diff --git a/lib/dtas/player.rb b/lib/dtas/player.rb index ba42490..3571a7f 100644 --- a/lib/dtas/player.rb +++ b/lib/dtas/player.rb @@ -212,6 +212,8 @@ class DTAS::Player # :nodoc: io.emit("OK") when "source" source_handler(io, msg) + when "state" + state_file_handler(io, msg) when "cd" chdir_handler(io, msg) when "pwd" diff --git a/lib/dtas/player/client_handler.rb b/lib/dtas/player/client_handler.rb index f601d46..bbdc1c5 100644 --- a/lib/dtas/player/client_handler.rb +++ b/lib/dtas/player/client_handler.rb @@ -479,5 +479,26 @@ module DTAS::Player::ClientHandler # :nodoc: # echo(%W(cd msg[0])) # should we broadcast this? io.emit("OK") end + + def state_file_handler(io, msg) + case msg.shift + when "dump" + dest = msg.shift + if dest + sf = DTAS::StateFile.new(dest, false) + elsif @state_file + sf = @state_file + dest = sf.path + else + return io.emit("ERR no state file configured") + end + begin + sf.dump(self) + rescue => e + return io.emit("ERR dumping to #{xs(Array(dest))} #{e.message}") + end + end + io.emit("OK") + end end # :startdoc: diff --git a/lib/dtas/state_file.rb b/lib/dtas/state_file.rb index c009797..0ba876f 100644 --- a/lib/dtas/state_file.rb +++ b/lib/dtas/state_file.rb @@ -3,6 +3,8 @@ require 'yaml' require 'tempfile' class DTAS::StateFile # :nodoc: + attr_reader :path + def initialize(path, do_fsync = false) @path = path @do_fsync = do_fsync diff --git a/test/test_player_integration.rb b/test/test_player_integration.rb index b60ed36..e7f7306 100644 --- a/test/test_player_integration.rb +++ b/test/test_player_integration.rb @@ -188,6 +188,24 @@ class TestPlayerIntegration < Minitest::Unit::TestCase assert_equal "/", s.req("pwd") end + def test_state_file + state = Tempfile.new(%w(state .yml)) + state_path = state.path + state.close! + s = client_socket + s.req_ok(%W(state dump #{state_path})) + hash = YAML.load(IO.binread(state_path)) + assert_equal @sock_path, hash["socket"] + assert_equal "default", hash["sinks"][0]["name"] + + assert_equal "", IO.binread(@state_tmp.path) + s.req_ok(%W(state dump)) + orig = YAML.load(IO.binread(@state_tmp.path)) + assert_equal orig, hash + ensure + File.unlink(state_path) + end + def test_source_ed s = client_socket assert_equal "sox av ff", s.req("source ls") |