GithubHelp home page GithubHelp logo

gompd's Introduction

gompd's People

Contributors

bernardzhao avatar codesoap avatar dairyisscary avatar env25 avatar fhs avatar jimbojsb avatar mackross avatar macrat avatar mdlayher avatar mpeterson2 avatar naglis avatar natsukagami avatar polyfloyd avatar pscn avatar stapper avatar sydstarwave avatar toaster avatar ushis avatar yktoo avatar zefer avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

gompd's Issues

Adopt new Go modules correctly

Currently in my go.mod, this module displays as github.com/fhs/gompd v2.0.0+incompatible. I search this up and found that this is supposed to happen when:

If a repository has not opted in to modules but has been tagged with valid semver tags, meanwhile, it's a v2+ module

I am using Golang version 1.13.

On a related note, for some reason I am also not getting the most recent version of this library when I use modules, which I believe may be due to this? When I delete my go.mod and go.sum my change in #48 is expressed, but when I make it a module suddenly the bug it fixes appears. Any idea on how to avoid this?

Attrs() breaks escaped URLs

Experimenting with some encoded URLs (using gompd v2.3.0 tag) I found that addid was breaking the URLs it sends to MPD while add was not.

After some digging I found that the way Attrs() passes the command to cmd.client.cmd is different to the way OK() does it.

Ultimately, this results in printfLine trying to handle escaped characters in URLs as Go string formatting directives and complaining that they're missing in the final formatted string.

Example of problem URL before fix: https://...?text=Sorry%!C(MISSING)+I+couldn%!t(MISSING)+understand+that
An example of a problem URL after fix: https://...?text=Sorry%2C+I+couldn%27t+understand+that

The fix appears to be, to call cmd.client.cmd the same way it is called elsewhere:

diff --git a/mpd/response.go b/mpd/response.go
index 3f1505b..5289fea 100644
--- a/mpd/response.go
+++ b/mpd/response.go
@@ -53,7 +53,7 @@ func (cmd *Command) OK() error {
 
 // Attrs sends command to server and reads attributes returned in response.
 func (cmd *Command) Attrs() (Attrs, error) {
-       id, err := cmd.client.cmd(cmd.cmd)
+       id, err := cmd.client.cmd("%v", cmd.cmd)
        if err != nil {
                return nil, err
        }

How long should connections stay alive?

This isn't really an issue, but rather a question. I created a Client when my program starts and was trying to reuse it after that. When my program doesn't send requests for some time and then tries to send one after that, I get read tcp [::1]:13364->[::1]:6600: read: connection reset by peer or EOF. Here is an example on how to reproduce the problem:

package main

import "github.com/fhs/gompd/mpd"
import "time"

func main() {
	c, _ := mpd.Dial("tcp", "localhost:6600")
	time.Sleep(time.Minute)
	if err := c.Pause(true); err != nil {
		panic(err)
	}
}

Am I supposed to create a new Client for every event that I create? If so: Would you take a pull request, where I document this, or do you think this is common knowledge?

Single quote and backslash should be escaped

The function quote() in client.go takes care of escaping double quotes while enclosing the passed string in double quotes.

According to MPD's docs on escaping, the following characters must be escaped too:

  • single quote
  • backslash

Especially the fact that backslash doesn't get escaped makes it difficult to implement escaping outside of this function.

New release?

Thank you for this project. As I want to package d'Uss for Debian which requires a never version than 2.2.0 and as the last release is already two years old I'd like to ask if it's possible to create a new release?

Handling of ideographic spaces in file names

I recently had trouble using the Client.Update or AddId methods with a file named:

"04 - ILL - DECAYED LOVE feat.℃iel.ogg"

gompd received a message from mpd saying the file didn't exist, even though other files in the same directory were fine, and even though I was able to add this file at the command line with mpc using my shell's autocomplete feature.

I noticed in the source of the library that that all file parameters are sent into a format string as a %q value. If I print the above song title using:

log.Printf("%q\n", "04 - ILL - DECAYED LOVE feat.℃iel.ogg")

It expands to:

2013/10/07 23:40:00 "04 - ILL - DECAYED LOVE\u3000feat.℃iel.ogg"

Note the \u3000 for the full-width space. is this being sent literally to mpd? I was able to work around this issue on my end by using strings.Map to convert all unicode spaces to the normal ASCII space character in the file name before working with it, but the library seems to have problems with the full-width space unless I'm mistaken.

Add binding for rescan

There's currently no function for the rescan command in gompd:

rescan [URI]
Same as update, but also rescans unmodified files.

Add binding for listfiles command

There's currently no function for the listfiles mpd command.

listfiles {URI}

Lists the contents of the directory URI, including files are not recognized by MPD. URI can be a path relative to the music directory or an URI understood by one of the storage plugins. The response contains at least one line for each directory entry with the prefix “file: ” or “directory: “, and may be followed by file attributes such as “Last-Modified” and “size”.

The only way to list files from MPD's database is to use the GetFiles() function that retrieves the entire file list at once. When the list is large this may introduce a performance penalty.

Add support for mpd partitions

Mpd has a feature called partitions. A partition is one frontend of a multi-player MPD process: it has separate queue, player and outputs. A client is assigned to one partition at a time.

https://www.musicpd.org/doc/html/protocol.html#partition-commands

Following should be added to client.go

//Partition commands

// Partition Switches the client to a different partition.
func (c *Client) Partition(name string) error {
	return c.Command("partition %s", name).OK()
}

// ListPartitions Print a list of partitions and their information.
func (c *Client) ListPartitions() ([]Attrs, error) {
	return c.Command("listpartitions").AttrsList("partition")
}

// NewPartition creates a new partition with the given name.
func (c *Client) NewPartition(name string) error {
	return c.Command("newpartition %s", name).OK()
}

// DelPartition deletes partition with the given name.
func (c *Client) DelPartition(name string) error {
	return c.Command("delpartition %s", name).OK()
}

// MoveOutput Move an output with the given name to the current partition.
func (c *Client) MoveOutput(name string) error {
	return c.Command("moveoutput %s", name).OK()
}

I have added this in my local branch, but it is not yet fully tested, as my mpd version on my dev machine does not yet support this feature, and I am currently having issues with updating it to the most recent version.
Should I sent a pull request, when I have fully tested this?

Possibility to expose Watcher.Client to avoid duplicate connection?

gompd/mpd/watcher.go

Lines 8 to 9 in c269f23

type Watcher struct {
conn *Client // client connection to MPD

contains unexported reference to Client instance.

Now when I need both watcher for mpd's subsystem events and also retrieve current song information, I have to create another instance with DialAuthenticated, while there is already one.

Would it be possible to allow shared access to Watcher's connection instance? I'm aware there can be a conflicting behavior, like closing from other party but such situations can happen by external causes anyway and connection instance should be handled in a defensive way in all cases.

Find error, quoted string issue

Trying to call Find("artist "David Bowie"") threw ACK 2@0 too few args.

Removed quote function from client.go, and it works. (line 554: id, err := c.cmd("find " + quote(uri)) )

Is there a correct way to pass this argument through the quote function without having to bypass it? The quote function is beyond my comprehension.

Handle connection lost to MPD

Hi, congrats for the this lib.

I'm just new here and trying to find a way to handle the connection lost to MPD.

I'm doing some tests and when I kill MPD the client are killed too.

How to handle it?

Thank you.

Add Reactor API

From #22.

The last comment mentions using an interface in the old pull request. I liked the idea and I want to implement it.

Here's how I'm imagining it would look like:

// Reactor represents an MPD connection that reacts to events.
type Reactor struct{ ... }

// NewReactor connects to MPD and reacts to events. Set handlers and other options
// by passing ReactorOptions.
func NewReactor(network, addr, password string, options ...ReactorOption) *Reactor

// Subsystems restricts subsystems watched for.
func (r *Reactor) Subsystems(subsystems ...string)

// Interrupt stops watching for event temporarily and runs the interrupt handler with args.
func (r *Reactor) Interrupt(args ...interface{})

// ReactorOption
type ReactorOption func(r *Reactor)

// ReactorSubsystems restricts the subsystems watched for.
func ReactorSubsystems(subsystems ...string) ReactorOption

// ReactorEventHandler is run for each change in MPD. The first argument is the subsystem
// that changed. See the list of subsystems:
// https://mpd.readthedocs.io/en/stable/protocol.html#command-idle
func ReactorEventHandler(f func(c *Client, subsystem string)) ReactorOption

func ReactorErrorHandler(f func(c *Client, err error)) ReactorOption

func ReactorInterruptHandler(f func(c *Client, args ...interface{})) ReactorOption

Instead of an interface, this uses the functional options pattern. This makes the API easier to use and makes any or all functionality optional.

This also adds an interrupt system, which allows using Client for external events. Interrupt will simply call noidle and send args on a channel.

We could also add ReactorOptions that send on a channel, so Watcher could be implemented in terms of Reactor.

Building type-safe wrappers around mpd.Attrs

Hello! Been playing with this package recently and it seems to work rather well. The API is nice too, but my one complaint is that since everything is a map[string]string, it requires manual parsing to deal with types such as integers, or compound fields such as audio (ex: 44100:16:2).

To remedy this issue, I've been working on: https://github.com/mdlayher/mpdx.

As stated, package mpdx is an extension of package mpd. I built it to nicely wrap some of the functions provided by this package. It returns struct types with standard field names and types.

Is this functionality something you'd be interested in merging into your package? If not, I'm happy to maintain mpdx as an extension to this package. Let me know!

TestWatcher sometimes hangs

The test seems to sometimes hang during tear-down (closing the Watcher).

=== RUN   TestWatcher
panic: test timed out after 10m0s

goroutine 43 [running]:
testing.(*M).startAlarm.func1()
	/opt/hostedtoolcache/go/1.14.1/x64/src/testing/testing.go:1460 +0x11c
created by time.goFunc
	/opt/hostedtoolcache/go/1.14.1/x64/src/time/sleep.go:168 +0x52

goroutine 1 [chan receive]:
testing.(*T).Run(0xc0000a4000, 0x6a38fc, 0xb, 0x6ae2f8, 0x1)
	/opt/hostedtoolcache/go/1.14.1/x64/src/testing/testing.go:1044 +0x699
testing.runTests.func1(0xc0000a4000)
	/opt/hostedtoolcache/go/1.14.1/x64/src/testing/testing.go:1285 +0xa7
testing.tRunner(0xc0000a4000, 0xc00007dd50)
	/opt/hostedtoolcache/go/1.14.1/x64/src/testing/testing.go:992 +0x1ec
testing.runTests(0xc00000e080, 0x84aee0, 0x13, 0x13, 0x0)
	/opt/hostedtoolcache/go/1.14.1/x64/src/testing/testing.go:1283 +0x528
testing.(*M).Run(0xc0000a0000, 0x0)
	/opt/hostedtoolcache/go/1.14.1/x64/src/testing/testing.go:1200 +0x300
main.main()
	_testmain.go:80 +0x224

goroutine 56 [chan receive]:
github.com/fhs/gompd/v2/mpd.(*Watcher).Close(0xc00015d8f0, 0x833120, 0xc000001980)
	/home/runner/work/gompd/gompd/mpd/watcher.go:115 +0xbe
github.com/fhs/gompd/v2/mpd.TestWatcher(0xc00016aea0)
	/home/runner/work/gompd/gompd/mpd/watcher_test.go:91 +0x97d
testing.tRunner(0xc00016aea0, 0x6ae2f8)
	/opt/hostedtoolcache/go/1.14.1/x64/src/testing/testing.go:992 +0x1ec
created by testing.(*T).Run
	/opt/hostedtoolcache/go/1.14.1/x64/src/testing/testing.go:1043 +0x661

goroutine 7 [IO wait]:
internal/poll.runtime_pollWait(0x7fb530cbbfa8, 0x72, 0x72)
	/opt/hostedtoolcache/go/1.14.1/x64/src/runtime/netpoll.go:203 +0x55
internal/poll.(*pollDesc).wait(0xc000106018, 0x72, 0x0, 0x0, 0x6a291a)
	/opt/hostedtoolcache/go/1.14.1/x64/src/internal/poll/fd_poll_runtime.go:87 +0xe4
internal/poll.(*pollDesc).waitRead(...)
	/opt/hostedtoolcache/go/1.14.1/x64/src/internal/poll/fd_poll_runtime.go:92
internal/poll.(*FD).Accept(0xc000106000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0)
	/opt/hostedtoolcache/go/1.14.1/x64/src/internal/poll/fd_unix.go:384 +0x2c9
net.(*netFD).accept(0xc000106000, 0xc00010a100, 0x6e40c0, 0x6e40a0)
	/opt/hostedtoolcache/go/1.14.1/x64/src/net/fd_unix.go:238 +0x56
net.(*TCPListener).accept(0xc00011e000, 0xc00010a100, 0xc000198000, 0x1000)
	/opt/hostedtoolcache/go/1.14.1/x64/src/net/tcpsock_posix.go:139 +0x50
net.(*TCPListener).Accept(0xc00011e000, 0x6ae310, 0xc000126000, 0xc00013abd0, 0xc00010a100)
	/opt/hostedtoolcache/go/1.14.1/x64/src/net/tcpsock.go:261 +0x50
github.com/fhs/gompd/v2/mpd/internal/server.Listen(0x6a20db, 0x3, 0x6a43e9, 0xe, 0xc0000662a0)
	/home/runner/work/gompd/gompd/mpd/internal/server/server.go:899 +0x160
created by github.com/fhs/gompd/v2/mpd.localDial
	/home/runner/work/gompd/gompd/mpd/client_test.go:44 +0x26b

goroutine 18 [select]:
github.com/fhs/gompd/v2/mpd/internal/server.(*server).broadcastIdleEvents(0xc000126000)
	/home/runner/work/gompd/gompd/mpd/internal/server/server.go:852 +0x4a9
created by github.com/fhs/gompd/v2/mpd/internal/server.Listen
	/home/runner/work/gompd/gompd/mpd/internal/server/server.go:896 +0x12c

goroutine 58 [IO wait]:
internal/poll.runtime_pollWait(0x7fb530cbbc28, 0x72, 0x6e43e0)
	/opt/hostedtoolcache/go/1.14.1/x64/src/runtime/netpoll.go:203 +0x55
internal/poll.(*pollDesc).wait(0xc000107498, 0x72, 0x1000, 0x1000, 0xffffffffffffffff)
	/opt/hostedtoolcache/go/1.14.1/x64/src/internal/poll/fd_poll_runtime.go:87 +0xe4
internal/poll.(*pollDesc).waitRead(...)
	/opt/hostedtoolcache/go/1.14.1/x64/src/internal/poll/fd_poll_runtime.go:92
internal/poll.(*FD).Read(0xc000107480, 0xc000198000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
	/opt/hostedtoolcache/go/1.14.1/x64/src/internal/poll/fd_unix.go:169 +0x253
net.(*netFD).Read(0xc000107480, 0xc000198000, 0x1000, 0x1000, 0x1d, 0x0, 0x0)
	/opt/hostedtoolcache/go/1.14.1/x64/src/net/fd_unix.go:202 +0x66
net.(*conn).Read(0xc00010a100, 0xc000198000, 0x1000, 0x1000, 0x1d, 0x0, 0x0)
	/opt/hostedtoolcache/go/1.14.1/x64/src/net/net.go:184 +0xa1
bufio.(*Reader).fill(0xc00010c9c0)
	/opt/hostedtoolcache/go/1.14.1/x64/src/bufio/bufio.go:100 +0x19a
bufio.(*Reader).ReadSlice(0xc00010c9c0, 0x47a70a, 0xc00011ee80, 0xc000041d10, 0x47a90f, 0xc000139540, 0xc000041d70)
	/opt/hostedtoolcache/go/1.14.1/x64/src/bufio/bufio.go:359 +0x96
bufio.(*Reader).ReadLine(0xc00010c9c0, 0x61d1a0, 0xc000139580, 0xc000036a80, 0x2, 0x7fb55a0687d0, 0x0)
	/opt/hostedtoolcache/go/1.14.1/x64/src/bufio/bufio.go:388 +0x45
net/textproto.(*Reader).readLineSlice(0xc00013abd0, 0x473427, 0x412630, 0x7fb52c011238, 0xc00013ac18, 0x473427)
	/opt/hostedtoolcache/go/1.14.1/x64/src/net/textproto/reader.go:58 +0x9e
net/textproto.(*Reader).ReadLine(...)
	/opt/hostedtoolcache/go/1.14.1/x64/src/net/textproto/reader.go:39
github.com/fhs/gompd/v2/mpd/internal/server.(*server).readRequest(0xc000126000, 0xc00013abd0, 0xc000126000, 0xc00013abd0, 0x5)
	/home/runner/work/gompd/gompd/mpd/internal/server/server.go:684 +0x53
github.com/fhs/gompd/v2/mpd/internal/server.(*server).handleConnection(0xc000126000, 0xc00013abd0)
	/home/runner/work/gompd/gompd/mpd/internal/server/server.go:767 +0x1e1
created by github.com/fhs/gompd/v2/mpd/internal/server.Listen
	/home/runner/work/gompd/gompd/mpd/internal/server/server.go:904 +0x241

goroutine 57 [IO wait]:
internal/poll.runtime_pollWait(0x7fb530cbbd08, 0x72, 0x6e43e0)
	/opt/hostedtoolcache/go/1.14.1/x64/src/runtime/netpoll.go:203 +0x55
internal/poll.(*pollDesc).wait(0xc000107298, 0x72, 0x1000, 0x1000, 0xffffffffffffffff)
	/opt/hostedtoolcache/go/1.14.1/x64/src/internal/poll/fd_poll_runtime.go:87 +0xe4
internal/poll.(*pollDesc).waitRead(...)
	/opt/hostedtoolcache/go/1.14.1/x64/src/internal/poll/fd_poll_runtime.go:92
internal/poll.(*FD).Read(0xc000107280, 0xc00018c000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
	/opt/hostedtoolcache/go/1.14.1/x64/src/internal/poll/fd_unix.go:169 +0x253
net.(*netFD).Read(0xc000107280, 0xc00018c000, 0x1000, 0x1000, 0x9, 0x0, 0x0)
	/opt/hostedtoolcache/go/1.14.1/x64/src/net/fd_unix.go:202 +0x66
net.(*conn).Read(0xc00010a0f0, 0xc00018c000, 0x1000, 0x1000, 0x9, 0x0, 0x0)
	/opt/hostedtoolcache/go/1.14.1/x64/src/net/net.go:184 +0xa1
bufio.(*Reader).fill(0xc00010c900)
	/opt/hostedtoolcache/go/1.14.1/x64/src/bufio/bufio.go:100 +0x19a
bufio.(*Reader).ReadSlice(0xc00010c900, 0x47a70a, 0xc0000e2060, 0xc000165d10, 0x47a90f, 0xc00000ec00, 0xc000165d70)
	/opt/hostedtoolcache/go/1.14.1/x64/src/bufio/bufio.go:359 +0x96
bufio.(*Reader).ReadLine(0xc00010c900, 0x61d1a0, 0xc000013c40, 0xc000036700, 0x1, 0x7fb55a068108, 0x0)
	/opt/hostedtoolcache/go/1.14.1/x64/src/bufio/bufio.go:388 +0x45
net/textproto.(*Reader).readLineSlice(0xc00013aab0, 0x473427, 0x412630, 0x7fb52c031038, 0xc00013ab10, 0x473427)
	/opt/hostedtoolcache/go/1.14.1/x64/src/net/textproto/reader.go:58 +0x9e
net/textproto.(*Reader).ReadLine(...)
	/opt/hostedtoolcache/go/1.14.1/x64/src/net/textproto/reader.go:39
github.com/fhs/gompd/v2/mpd/internal/server.(*server).readRequest(0xc000126000, 0xc00013aab0, 0xc00000ec00, 0x2, 0x2)
	/home/runner/work/gompd/gompd/mpd/internal/server/server.go:684 +0x53
github.com/fhs/gompd/v2/mpd/internal/server.(*server).handleConnection(0xc000126000, 0xc00013aab0)
	/home/runner/work/gompd/gompd/mpd/internal/server/server.go:767 +0x1e1
created by github.com/fhs/gompd/v2/mpd/internal/server.Listen
	/home/runner/work/gompd/gompd/mpd/internal/server/server.go:904 +0x241

goroutine 59 [IO wait]:
internal/poll.runtime_pollWait(0x7fb530cbbde8, 0x72, 0x6e43e0)
	/opt/hostedtoolcache/go/1.14.1/x64/src/runtime/netpoll.go:203 +0x55
internal/poll.(*pollDesc).wait(0xc000107418, 0x72, 0x1000, 0x1000, 0xffffffffffffffff)
	/opt/hostedtoolcache/go/1.14.1/x64/src/internal/poll/fd_poll_runtime.go:87 +0xe4
internal/poll.(*pollDesc).waitRead(...)
	/opt/hostedtoolcache/go/1.14.1/x64/src/internal/poll/fd_poll_runtime.go:92
internal/poll.(*FD).Read(0xc000107400, 0xc000196000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
	/opt/hostedtoolcache/go/1.14.1/x64/src/internal/poll/fd_unix.go:169 +0x253
net.(*netFD).Read(0xc000107400, 0xc000196000, 0x1000, 0x1000, 0xc000042800, 0xc0000428e8, 0x4ca88c)
	/opt/hostedtoolcache/go/1.14.1/x64/src/net/fd_unix.go:202 +0x66
net.(*conn).Read(0xc00010a0f8, 0xc000196000, 0x1000, 0x1000, 0x0, 0xc000042bc8, 0x0)
	/opt/hostedtoolcache/go/1.14.1/x64/src/net/net.go:184 +0xa1
bufio.(*Reader).fill(0xc00010c960)
	/opt/hostedtoolcache/go/1.14.1/x64/src/bufio/bufio.go:100 +0x19a
bufio.(*Reader).ReadSlice(0xc00010c960, 0xa, 0xc000153ba0, 0x9, 0xc000153ba0, 0x9, 0x9)
	/opt/hostedtoolcache/go/1.14.1/x64/src/bufio/bufio.go:359 +0x96
bufio.(*Reader).ReadLine(0xc00010c960, 0x9, 0x2, 0x1, 0x2, 0xc000153ba0, 0xc000153ba7)
	/opt/hostedtoolcache/go/1.14.1/x64/src/bufio/bufio.go:388 +0x45
net/textproto.(*Reader).readLineSlice(0xc00013ab40, 0x6a2936, 0x7, 0x6a1f87, 0x2, 0xc000153ba0)
	/opt/hostedtoolcache/go/1.14.1/x64/src/net/textproto/reader.go:58 +0x9e
net/textproto.(*Reader).ReadLine(...)
	/opt/hostedtoolcache/go/1.14.1/x64/src/net/textproto/reader.go:39
github.com/fhs/gompd/v2/mpd.(*Client).readList(0xc00011ed00, 0x6a2936, 0x7, 0x0, 0x0, 0x0, 0x4, 0x0)
	/home/runner/work/gompd/gompd/mpd/client.go:163 +0xe9
github.com/fhs/gompd/v2/mpd.(*Command).Strings(0xc00000ec20, 0x6a2936, 0x7, 0x0, 0x0, 0x0, 0x0, 0x0)
	/home/runner/work/gompd/gompd/mpd/response.go:86 +0x1fc
github.com/fhs/gompd/v2/mpd.(*Client).idle(0xc00011ed00, 0xc00011ede0, 0x2, 0x2, 0xc0000e2000, 0x1, 0x1, 0x0, 0x0)
	/home/runner/work/gompd/gompd/mpd/client.go:284 +0x10d
github.com/fhs/gompd/v2/mpd.(*Watcher).watch(0xc00015d8f0, 0xc000105b00, 0x2, 0x2)
	/home/runner/work/gompd/gompd/mpd/watcher.go:46 +0x335
created by github.com/fhs/gompd/v2/mpd.NewWatcher
	/home/runner/work/gompd/gompd/mpd/watcher.go:36 +0x300

goroutine 62 [select]:
github.com/fhs/gompd/v2/mpd/internal/server.(*server).writeIdleResponse(0xc000126000, 0xc00013abd0, 0x5, 0xc000124e40, 0xc000139550, 0x2, 0x3)
	/home/runner/work/gompd/gompd/mpd/internal/server/server.go:742 +0x320
created by github.com/fhs/gompd/v2/mpd/internal/server.(*server).handleConnection
	/home/runner/work/gompd/gompd/mpd/internal/server/server.go:780 +0x2e3
FAIL	github.com/fhs/gompd/v2/mpd	600.013s

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.