Git Product home page Git Product logo

relaym-server's People

Contributors

dependabot-preview[bot] avatar dependabot[bot] avatar dora1998 avatar p1ass avatar panorama32 avatar sanposhiho 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

relaym-server's Issues

[docs] データベースのドキュメントを作成

概要

データベースに関するドキュメントを作成する。

要件

  • MySQLを使っていることが分かる
  • スキーマのドキュメントが自動生成されていることが分かる

タスク

  • docs/database.md に内容を書く

[Session] サーバを再起動したときにセッションのタイマーがちゃんと復活されるか確認

概要

セッションのタイマーはオンメモリで持っているためサーバが再起動されるとなくなってしまう。
その対策として、WebSocket接続時にタイマーがないならタイマーを生成するというロジックを書いてある(コメントアウトしている)

https://github.com/camphor-/relaym-server/blob/master/usecase/session.go#L179-L193

ただ、この実装でうまくいくか分からないので、サーバを再起動したときにセッションのタイマーがちゃんと復活されるか確認したい。

要件

  • セッションのタイマーが復活できる
    • もしだめなら別の案を考える ( #39 で色々考えたがあまりしっくり来ていない)

タスク

  • 実装を本体に追加する

[Auth] SpotifyのOAuth2認証を実装

概要

SpotifyのOAuth2認証を行えるようにする。

要件

  • クライアントがログイン用のエンドポイントを叩くことでSpotifyの認証画面に飛べる
  • Spotifyからのコールバックを受け取ってクライアントにリダイレクトされる

ユーザの情報をDBに保存したり、アクセストークンを更新したりする処理はOut of Scopeです。 #11

API仕様

GET /login

非同期でリクエストされるのではなく、aタグで飛んできます。
内部で処理が終わったらSpotifyの認証画面にリダイレクトされます。

クエリパラメータ

  • redirect_url : Spotifyの認証が終わった後リダイレクトされるクライアントのURLを指定します

レスポンス

ステータスコード 説明
302 Spotifyの認証画面にリダイレクト

GET /callback

Spotifyの認証が終わった際にリダイレクトされてくるAPIです。

レスポンス

ステータスコード 説明
302 GET /login で受け取ったredirect_url にリダイレクト

タスク

  • GET /login エンドポイントを生やす
  • go-spotify ライブラリを導入
  • SpotifyのOAuth認証に必要なstateをMySQLに保存する処理を実装
  • GET /callback エンドポイントを生やす

[Session] プレイヤーの操作ができなくなった

概要

PUT /sessions/:id/playback が500を返すようになった

再現方法

ログイン後APIを叩くと必ず起きる

ログ

{"time":"2020-05-30T15:08:23.48358+09:00","level":"ERROR","prefix":"echo","file":"session.go","line":"126","message":"change playback: play sessionID=480f9793-40b4-44f7-abdf-8ba7c27980b0: call play api: token not found"}
{"time":"2020-05-30T15:08:23.483622+09:00","id":"","remote_ip":"::1","host":"relaym.local:8080","method":"PUT","uri":"/api/v3/sessions/480f9793-40b4-44f7-abdf-8ba7c27980b0/playback","user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36","status":500,"error":"code=500, message=Internal Server Error","latency":9130605,"latency_human":"9.130605ms","bytes_in":16,"bytes_out":36}

対処方法

  • セッション作成者以外がSpotify APIを叩くときは作成者のトークンを使えるようにする。
    • 具体的には、ミドルウェアで差し込む

[Session] キューの順番がおかしい

概要

既に「次に再生される曲」に曲が詰まれてある状態でセッションを開始すると、 1曲目は新規の曲が再生されるが、残りのキューの曲は「次に再生される曲」の後に再生されてしまう。

再現方法

  1. セッションを作成する
  2. 2曲追加する (適当な数で良い) (A,Bとする)
  3. 再生を始める
  4. 曲を追加する(C)とする

このとき曲の順番は
A,C,Bとなってしまう。

ログ

<img src="https://user-images.githubusercontent.com/30015728/84969626-0b1c6180-b154-11ea-8dfa-6fa671605c66.png" width="300px")

対処方法

  • PlayWithTracks() で曲を追加すると、1曲目が「再生中」、それ以降が「再生待ち」に追加される
  • AddToQueue() で追加すると「次に再生される曲」に追加される

優先度は「次に再生される曲」の方が高いので、AddToQueue の方が先に読まれてしまう。

PlayWithTracks() の中で

  • 1曲だけPlay() で再生中にする
  • 残りはAddToQueue でキューに追加

する実装に変更する

[deploy] dev環境を構築する

概要

開発時に使えるdev環境を構築する

要件

  • Publicなインターネットからアクセスできる
  • master push時に自動でデプロイされる

API仕様 (あれば)

タスク

  • デプロイ先の選定
  • デプロイスクリプトを書く

[WebSocket] WebSocketが数分経つと切れてしまう

概要

WebSocketを接続して数分たった後にメッセージを送信しようとするとエラーになる

再現方法

細かいところは調査中

ログ

failed to WriteJSON: write tcp [::1]:8080->[::1]:52796: i/o timeout

対処方法

まだ分からん

[Session] セッションの再開処理を実装

概要

同期チェックに失敗した後に、セッションを再開するときの復帰処理を実装する

要件

https://github.com/camphor-/relaym-server/blob/master/docs/prd.md#spotify%E3%81%A8%E3%81%AE%E6%9B%B2%E3%81%AE%E5%90%8C%E6%9C%9F%E3%81%AB%E5%A4%B1%E6%95%97%E3%81%97%E3%81%9F%E3%81%A8%E3%81%8D

API仕様 (あれば)

https://github.com/camphor-/relaym-server/blob/master/docs/api.md#resume

メモ

復帰処理は #66 と処理が共通化できそう

[WebSocket] Websocketのエンドポイントを追加

概要

曲の追加などのイベントをWebSocketで送るエンドポイントを追加する

要件

  • 曲の追加を通知できる
  • 次の曲に移ったことを通知できる
    • headの値を送信できる
  • セッションの開始を通知できる
  • セッションの一時停止を通知できる
  • セッションの再開を通知できる これは #67 で実装
  • Spotify本体側のアプリを操作されて、同期がとれなくなったことを通知できる

API仕様 (あれば)

https://github.com/camphor-/relaym-server/blob/master/docs/api.md#get-wsid

[Logging] ログをどのpackageからも吐けるようにする

概要

現在、 echoのロガーを使ってjsonのログを吐いているが、これだと他のパッケージでログを吐けない。

logging package を作るなどして、どこからでもログを吐けるようにする

要件

  • INFO、WARN、ERRORなどのログレベルが設定できる
  • jsonでログを出力できる
  • echoのロガーを良い感じに使い回せると良さそう

API仕様 (あれば)

[Session] SpotifyとRelaymが正しく同期を取れているかチェックする機構を追加

概要

Spotify側のアプリを操作されると同期が取れなくなるので、それをキャッチできるようにする

要件

  • PRD を参照

API仕様 (あれば)

https://github.com/camphor-/relaym-server/blob/master/docs/api.md#interrupt

タスク

  • 何をもって同期が取れてないとみなすか決める
  • チェックの間隔を決める
  • サーバが死んだときに復帰できる / スケールアウトに対応できる設計を考える #73 へ移行
    • めんどくさそうなら一旦なしでも良いかも

[Session] n曲目終了後n+1曲目が自動で再生される

概要

曲が終わった後、次の曲が再生されるようにする。

要件

  • 次の曲が存在する場合、曲が終わった後、次の曲が再生される
  • 次の曲が存在しない場合、playbackを STOP にする

API仕様

このSpotify APIを使えばできそう
https://developer.spotify.com/documentation/web-api/reference-beta/#endpoint-add-to-queue

リピートがオンになってると、最後の曲の後ループしてしまう可能性があるので注意する

一部デバイスで再生を検知できない

概要

Echo dotで再生時、たまに曲が正常に始まるがRelaym側で再生状態にならない。
再生開始までに他のデバイスより時間がかかるのが原因…?

再現方法

  1. セッションを作り、曲を適当に追加する
  2. Echo dotを再生デバイスとして指定
  3. 再生ボタンを押す
  4. Relaym側で再生状態にならない(リロードしても同じ)
  5. 一曲終わると次が再生されず止まる
  6. もう一度再生ボタンを押す
  7. 再度1曲目の再生が始まり、Relaym側でも再生状態になる

ログ

対処方法

  • Task1

TrackをSpotify APIから取得した際にキャッシュ

概要

TrackをspotifyのAPIから取得した際にキャッシュにレスポンスを保存
#14

要件

  • 一旦インメモリキャッシュで
  • 背景としては#14 で全てのTrack情報をDBで持ちたくない。が、GET /sessions/:id とかの時にTracksの数だけspotifyのAPI叩かなきゃになるのも🙅‍♂️

API仕様 (あれば)

タスク

[Session] デバイスIDを指定できるところは指定してSpotify APIを叩く

概要

TODOでコメントしているデバイスIDを空にしてSpotify APIを叩いているところで、ちゃんとデバイスIDを使うようにする。

要件

  • デバイスIDを指定してSpotify APIをコールできる
  • 存在しないときはこれまで通り空文字列で

API仕様 (あれば)

タスク

  • E2EテストでデバイスをセットするAPIを確かめる

[Session] 1曲目の再生スタート時に別の曲の再生途中だとその曲が流れてしまう

概要

1曲目の再生スタート時に別の曲の再生途中だとその曲が流れてしまう 。
本来であればキューに追加した1曲目が再生されてほしい。

再現方法

  1. Spotifyアプリで適当な曲を再生して一時停止
  2. Relaym側でAdd Queue
  3. 再生APIを叩く
  4. 適当な曲の再生が再開してしまう

ログ

対処方法

  • [ ] Playするタイミングでも同期チェックのロジックを走らせて、失敗したら次の曲の再生を開始するように指示する

Add Queueを毎回しないことで対応した #70

[Session] デバイスがオフラインのときにE2Eテストを走らすと500が返ってくる

概要

デバイスがオフラインのときにE2Eテストを走らすと500が返ってくる

再現方法

デバイスをオフラインにしてe2eを実行

ログ

{"time":"2020-06-18T16:11:41.555162+09:00","id":"","remote_ip":"::1","host":"relaym.local:8080","method":"GET","uri":"/api/v3/users/me","user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36","status":200,"error":"","latency":242819690,"latency_human":"242.81969ms","bytes_in":0,"bytes_out":117}
{"time":"2020-06-18T16:11:41.784802+09:00","id":"","remote_ip":"::1","host":"relaym.local:8080","method":"GET","uri":"/api/v3/users/me/devices","user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36","status":200,"error":"","latency":219288627,"latency_human":"219.288627ms","bytes_in":0,"bytes_out":115}
{"time":"2020-06-18T16:11:41.804416+09:00","id":"","remote_ip":"::1","host":"relaym.local:8080","method":"POST","uri":"/api/v3/sessions","user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36","status":201,"error":"","latency":14292822,"latency_human":"14.292822ms","bytes_in":15,"bytes_out":221}
{"time":"2020-06-18T16:11:41.82208+09:00","level":"DEBUG","prefix":"application","file":"hub.go","line":"52","event":{"type":"ADDTRACK"},"message":"push message","sessionID":"a68456b1-5df3-4e97-b3ba-8a873c48c91c"}
{"time":"2020-06-18T16:11:41.822107+09:00","id":"","remote_ip":"::1","host":"relaym.local:8080","method":"POST","uri":"/api/v3/sessions/a68456b1-5df3-4e97-b3ba-8a873c48c91c/queue","user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36","status":204,"error":"","latency":12141581,"latency_human":"12.141581ms","bytes_in":46,"bytes_out":0}
{"time":"2020-06-18T16:11:41.840561+09:00","level":"DEBUG","prefix":"application","file":"hub.go","line":"52","event":{"type":"ADDTRACK"},"message":"push message","sessionID":"a68456b1-5df3-4e97-b3ba-8a873c48c91c"}
{"time":"2020-06-18T16:11:41.84058+09:00","id":"","remote_ip":"::1","host":"relaym.local:8080","method":"POST","uri":"/api/v3/sessions/a68456b1-5df3-4e97-b3ba-8a873c48c91c/queue","user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36","status":204,"error":"","latency":13396891,"latency_human":"13.396891ms","bytes_in":46,"bytes_out":0}
{"time":"2020-06-18T16:11:41.973607+09:00","level":"DEBUG","prefix":"application","file":"session.go","line":"133","message":"playORResume sessionID=a68456b1-5df3-4e97-b3ba-8a873c48c91c: call set repeat off api: spotify api: set repeat mode: Player command failed: No active device found: active device not found"}
{"time":"2020-06-18T16:11:41.973669+09:00","id":"","remote_ip":"::1","host":"relaym.local:8080","method":"PUT","uri":"/api/v3/sessions/a68456b1-5df3-4e97-b3ba-8a873c48c91c/playback","user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36","status":403,"error":"code=403, message=active device not found","latency":128084718,"latency_human":"128.084718ms","bytes_in":16,"bytes_out":38}
{"time":"2020-06-18T16:11:47.086178+09:00","level":"DEBUG","prefix":"application","file":"sync_check_timer.go","line":"74","message":"stop timer","sessionID":"a68456b1-5df3-4e97-b3ba-8a873c48c91c"}
{"time":"2020-06-18T16:11:47.086232+09:00","level":"DEBUG","prefix":"application","file":"sync_check_timer.go","line":"84","message":"timer not existed","sessionID":"a68456b1-5df3-4e97-b3ba-8a873c48c91c"}
{"time":"2020-06-18T16:11:47.086327+09:00","level":"ERROR","prefix":"application","file":"session.go","line":"136","error":"pause sessionID=a68456b1-5df3-4e97-b3ba-8a873c48c91c: move to pause id=a68456b1-5df3-4e97-b3ba-8a873c48c91c: state type from STOP to Pause: change session state is not permits","message":"failed to change playback"}
{"time":"2020-06-18T16:11:47.086369+09:00","id":"","remote_ip":"::1","host":"relaym.local:8080","method":"PUT","uri":"/api/v3/sessions/a68456b1-5df3-4e97-b3ba-8a873c48c91c/playback","user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36","status":500,"error":"code=500, message=Internal Server Error","latency":104997355,"latency_human":"104.997355ms","bytes_in":17,"bytes_out":36}
{"time":"2020-06-18T16:11:52.214022+09:00","level":"DEBUG","prefix":"application","file":"session.go","line":"133","message":"playORResume sessionID=a68456b1-5df3-4e97-b3ba-8a873c48c91c: call set repeat off api: spotify api: set repeat mode: Player command failed: No active device found: active device not found"}
{"time":"2020-06-18T16:11:52.214064+09:00","id":"","remote_ip":"::1","host":"relaym.local:8080","method":"PUT","uri":"/api/v3/sessions/a68456b1-5df3-4e97-b3ba-8a873c48c91c/playback","user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36","status":403,"error":"code=403, message=active device not found","latency":111172704,"latency_human":"111.172704ms","bytes_in":16,"bytes_out":38}
{"time":"2020-06-18T16:11:52.239199+09:00","level":"DEBUG","prefix":"application","file":"hub.go","line":"52","event":{"type":"ADDTRACK"},"message":"push message","sessionID":"a68456b1-5df3-4e97-b3ba-8a873c48c91c"}
{"time":"2020-06-18T16:11:52.239242+09:00","id":"","remote_ip":"::1","host":"relaym.local:8080","method":"POST","uri":"/api/v3/sessions/a68456b1-5df3-4e97-b3ba-8a873c48c91c/queue","user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36","status":204,"error":"","latency":18787554,"latency_human":"18.787554ms","bytes_in":46,"bytes_out":0}

対処方法

  • 再生の開始に失敗してStopの状態でPauseに移行しようとしてエラーになってるっぽい。errors.Isで400を返してあげれば良さそう

session.queueが空の時にGET /sessions/:idが正常に動作しない

概要

session.queueが空の時にGET /sessions/:idが正常に動作しない

再現方法

  1. sessionを作成する
  2. GET /sessions/:idを叩く

ログ

{"time":"2020-06-17T08:15:07.830573+09:00","level":"DEBUG","prefix":"echo","file":"session.go","line":"60","message":"getSession from db: get tracks: track_uris=[]: get track uris=[]: invalid id"}

対処方法

[Auth] オンメモリで持っているログインセッションをMySQLに移行する

概要

仮実装として、ログインセッションをオンメモリで持つ実装をしていたが、これをMySQLで実装する。

なお、ドキュメントでRedisと書いていたが、ミドルウェアが増えると複雑になるのでMySQLに統一する。パフォーマンスが出ないならそのタイミングで移行を検討する

https://github.com/camphor-/relaym-server/blob/master/database/auth.go#L61-L67

要件

  • ログインセッションが永続化され、サーバを再起動してもセッションが残っている

API仕様 (あれば)

タスク

  • Redisを使うと書いてあったドキュメントを削除

[docs] アーキテクチャのドキュメントを作成

概要

アーキテクチャに関するドキュメントを作成する。

要件

  • どのようなミドルウェアや外部APIを使っているかが分かる。

タスク

  • docs/architecture.md に内容を書く
  • 本番環境のアーキテクチャを書く

[Session] 意図しないタイミングでInterruptが送られてきがち

概要

意図しないタイミングでInterruptが送られてくることがある

再現方法

いまいち分かってない。

全ての再生が終わった後に、追加で曲を追加するとINTERRUPT送られてくる匂いを感じている。

その他のパターンもありそう

ログ

対処方法

  • Task1

[Auth] Spotify Web APIを呼び出す時に有効期限が切れていたら再度アクセストークンを発行する

概要

アクセストークンの有効期限が切れていたら、リフレッシュトークンを使って再度アクセストークンを取得する。

#11 の後

要件

  • API呼び出し前にアクセストークンの有効期限をチェックできる
  • アクセストークンの有効期限が切れていたら更新処理をする
  • 有効期限が切れていないときは更新処理をしない

参考

Goのoauth2 packageには有効期限を確かめるメソッドがあります。
https://pkg.go.dev/golang.org/x/oauth2?tab=doc#Token.Valid

Spotify APIのライブラリ側のissue
zmb3/spotify#108

[CI] Goのテストと静的解析を実行する

概要

Goのテストや静的解析を実行する。

方法

  • GitHub Actionsを使います。

要件

  • go build を実行
  • go test ./... を実行
  • goimports, golint go vetの静的解析を実行

タスク

  • MySQをGitHub Actionsで用意する方法の調査
  • ワークフローファイルを書く

[Session] 全ての再生が終わった後再生を始めると1曲目から再生されてしまう

概要

全ての再生が終わった後再生を始めると1曲目から再生されてしまう 。
意図した挙動は、再生が終わった後に追加された曲が再生されること。

再現方法

  1. 曲を2曲(A,Bとする)追加
  2. 再生を始める
  3. 全て再生がおわる
  4. 新しい曲(C)を追加する
  5. 再度再生を始める
  6. Aの曲が再生されてしまう

ログ

対処方法

バルクでSpotifyに追加するときに、QueueHead以降のものだけを追加するように修正する

https://github.com/camphor-/relaym-server/blob/master/usecase/session.go#L120-L130

[Session] セッションやキューを読み書きするリポジトリを実装

概要

セッションやキューを読み書きするリポジトリを実装する。

要件

すこし重たいので、テーブル設計とrepositoryの実装でPRを分けたほうが良いです。

  • IDを指定してセッションを取得できる
    • 基本情報
    • セッションの作成者
    • 現在の再生状況
  • 新規でセッションを作成できる
  • キューに曲を追加できる (削除はできなくてよい)

API仕様

API仕様をみつつ必要なデータベースのカラムを考える。

タスク

  • テーブル設計

[Auth] Spotify Web APIのアクセストークンを読み書きする処理を実装

概要

OAuth成功時にアクセストークンをMySQLに保存する

要件

  • 既存ユーザのアクセストークンを更新できる
  • 新規ユーザの場合は、usersテーブルも同時に作成する
  • API呼び出し時にアクセストークンを取得できる

タスク

  • アクセストークンを保存できるテーブル設計を考える
  • 読み書き用のリポジトリを作成
  • /callback のエンドポイントから保存する処理を呼ぶ
  • middlewareでトークンを取得する処理を追加

[session] Spotifyにログインしなくてもセッションに参加できるようにする

概要

https://github.com/camphor-/relaym-server/pull/37#discussion_r422262759

利便性の面から、Spotifyにログインしていなくてもセッションに参加できるようにする。

要件

  • セッションの参加者はSpotifyにログインしていなくてもセッションを見ることができる
    • これは #48 で実装
  • セッションの参加者はセッションの作成者のトークンを使って検索を行う
    • これをやる
  • セッションの参加者は再生プレイヤーを操作することができる
    • これもセッション作成者のトークンを使って行う

API仕様 (あれば)

タスク

Prod環境の構築

概要

頑張ってProd環境を構築する

要件

API仕様 (あれば)

タスク

意図しないメンバーによってSpotifyが乗っ取られるのを防ぐ

概要

現状の仕組みだと、セッションのURLさえわかれば誰でも作成者のSpotifyを乗っとれてしまう。
使用後のURLがいつまでも有効なため、これは運用が長期に渡るほど問題になるので、対策を考えたい。

要件

  • セッション作成者が好きなタイミングでセッションを無効にできる
  • セッション使用後放置してても、セッションが無効になる

API仕様 (あれば)

タスク

  • 変更した内容をPRDに書く

sessionのqueueTrackの操作周りがなんかあやしい

概要

時々、1曲目を再生してから、2曲目に移行しない。

再現方法

Spotifyのプレイヤーを直接操作して以下のログがでてからうまく動作しなくなったので何かこの辺りの処理と関係があるのかもしれない。知らんけど…

&{d82dc39d-582f-4b8f-8c05-a3ddaf9e7646 test c7b07b1a-4014-46ea-b82f-a0ee113d0817  PLAY 2 [0xc000203770 0xc0002037a0 0xc0002037d0]}
session playing different track: queue track spotify:track:06QTSGUEgcmKwiEJ0IMPig, but playing track &{spotify:track:5uQ0vKy2973Y9IUCd1wMEF 5uQ0vKy2973Y9IUCd1wMEF 新芽探して 45.759s [0xc0003d77c0] https://open.spotify.com/track/5uQ073Y9IUCd1wMEF 0xc000203980}

この後の操作では

  • Playbackで1曲目のremainDurationは吐かれる(= startTrackEndTrigerは呼ばれてる)
  • 次の曲への移動などが検知されない(= queueHeadが0のまま、stateはPLAYになってる)

ログ

{"time":"2020-06-17T15:45:14.701279+09:00","id":"","remote_ip":"::1","host":"relaym.local:8080","method":"PUT","uri":"/api/v3/sessions/d82dc39d-582f-4b8f-8c05-a3ddaf9e7646/playback","user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36","status":202,"error":"","latency":816014511,"latency_human":"816.014511ms","bytes_in":16,"bytes_out":0}
39.855s
{"time":"2020-06-17T15:45:26.626008+09:00","id":"","remote_ip":"::1","host":"relaym.local:8080","method":"GET","uri":"/api/v3/sessions/d82dc39d-582f-4b8f-8c05-a3ddaf9e7646/","user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36","status":200,"error":"","latency":321468887,"latency_human":"321.468887ms","bytes_in":0,"bytes_out":1574}
&{d82dc39d-582f-4b8f-8c05-a3ddaf9e7646 test c7b07b1a-4014-46ea-b82f-a0ee113d0817  PLAY 1 [0xc000202a80 0xc000202ab0]}
13.523s
{"time":"2020-06-17T15:46:22.245677+09:00","id":"","remote_ip":"::1","host":"relaym.local:8080","method":"POST","uri":"/api/v3/sessions/d82dc39d-582f-4b8f-8c05-a3ddaf9e7646/queue","user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36","status":204,"error":"","latency":209221479,"latency_human":"209.221479ms","bytes_in":46,"bytes_out":0}
&{d82dc39d-582f-4b8f-8c05-a3ddaf9e7646 test c7b07b1a-4014-46ea-b82f-a0ee113d0817  PLAY 2 [0xc000203770 0xc0002037a0 0xc0002037d0]}
session playing different track: queue track spotify:track:06QTSGUEgcmKwiEJ0IMPig, but playing track &{spotify:track:5uQ0vKy2973Y9IUCd1wMEF 5uQ0vKy2973Y9IUCd1wMEF 新芽探して 45.759s [0xc0003d77c0] https://open.spotify.com/track/5uQ073Y9IUCd1wMEF 0xc000203980}
{"time":"2020-06-17T15:46:39.765812+09:00","id":"","remote_ip":"::1","host":"relaym.local:8080","method":"GET","uri":"/api/v3/users/me","user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36","status":200,"error":"","latency":89650218,"latency_human":"89.650218ms","bytes_in":0,"bytes_out":140}
{"time":"2020-06-17T15:46:39.865782+09:00","id":"","remote_ip":"::1","host":"relaym.local:8080","method":"GET","uri":"/api/v3/users/me/devices","user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36","status":200,"error":"","latency":94237935,"latency_human":"94.237935ms","bytes_in":0,"bytes_out":315}
{"time":"2020-06-17T15:46:39.885708+09:00","id":"","remote_ip":"::1","host":"relaym.local:8080","method":"POST","uri":"/api/v3/sessions","user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36","status":201,"error":"","latency":13059394,"latency_human":"13.059394ms","bytes_in":15,"bytes_out":227}
{"time":"2020-06-17T15:46:39.904446+09:00","id":"","remote_ip":"::1","host":"relaym.local:8080","method":"POST","uri":"/api/v3/sessions/56c75adc-3d94-4ae7-8f37-a8ade1668983/queue","user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36","status":204,"error":"","latency":13486792,"latency_human":"13.486792ms","bytes_in":46,"bytes_out":0}
{"time":"2020-06-17T15:46:39.923466+09:00","id":"","remote_ip":"::1","host":"relaym.local:8080","method":"POST","uri":"/api/v3/sessions/56c75adc-3d94-4ae7-8f37-a8ade1668983/queue","user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36","status":204,"error":"","latency":13254183,"latency_human":"13.254183ms","bytes_in":46,"bytes_out":0}
{"time":"2020-06-17T15:46:40.859771+09:00","id":"","remote_ip":"::1","host":"relaym.local:8080","method":"PUT","uri":"/api/v3/sessions/56c75adc-3d94-4ae7-8f37-a8ade1668983/playback","user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36","status":202,"error":"","latency":931340476,"latency_human":"931.340476ms","bytes_in":16,"bytes_out":0}
40.064s
{"time":"2020-06-17T15:46:49.226604+09:00","id":"","remote_ip":"::1","host":"relaym.local:8080","method":"GET","uri":"/api/v3/sessions/56c75adc-3d94-4ae7-8f37-a8ade1668983/","user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36","status":200,"error":"","latency":162861151,"latency_human":"162.861151ms","bytes_in":0,"bytes_out":1576}
{"time":"2020-06-17T15:47:54.792113+09:00","id":"","remote_ip":"::1","host":"relaym.local:8080","method":"GET","uri":"/api/v3/sessions/56c75adc-3d94-4ae7-8f37-a8ade1668983/","user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36","status":200,"error":"","latency":179408490,"latency_human":"179.40849ms","bytes_in":0,"bytes_out":1576}
{"time":"2020-06-17T15:47:59.326295+09:00","id":"","remote_ip":"::1","host":"relaym.local:8080","method":"GET","uri":"/api/v3/users/me","user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36","status":200,"error":"","latency":176662558,"latency_human":"176.662558ms","bytes_in":0,"bytes_out":140}
{"time":"2020-06-17T15:47:59.484326+09:00","id":"","remote_ip":"::1","host":"relaym.local:8080","method":"GET","uri":"/api/v3/users/me/devices","user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36","status":200,"error":"","latency":153041961,"latency_human":"153.041961ms","bytes_in":0,"bytes_out":315}
{"time":"2020-06-17T15:47:59.505681+09:00","id":"","remote_ip":"::1","host":"relaym.local:8080","method":"POST","uri":"/api/v3/sessions","user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36","status":201,"error":"","latency":14128185,"latency_human":"14.128185ms","bytes_in":15,"bytes_out":227}
{"time":"2020-06-17T15:47:59.525643+09:00","id":"","remote_ip":"::1","host":"relaym.local:8080","method":"POST","uri":"/api/v3/sessions/8ad2607c-ba7d-404a-bbac-daee0ac6b9b0/queue","user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36","status":204,"error":"","latency":14841316,"latency_human":"14.841316ms","bytes_in":46,"bytes_out":0}
{"time":"2020-06-17T15:47:59.548645+09:00","id":"","remote_ip":"::1","host":"relaym.local:8080","method":"POST","uri":"/api/v3/sessions/8ad2607c-ba7d-404a-bbac-daee0ac6b9b0/queue","user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36","status":204,"error":"","latency":17015741,"latency_human":"17.015741ms","bytes_in":46,"bytes_out":0}
{"time":"2020-06-17T15:48:00.718509+09:00","id":"","remote_ip":"::1","host":"relaym.local:8080","method":"PUT","uri":"/api/v3/sessions/8ad2607c-ba7d-404a-bbac-daee0ac6b9b0/playback","user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36","status":202,"error":"","latency":1164800978,"latency_human":"1.164800978s","bytes_in":16,"bytes_out":0}
40.059s
{"time":"2020-06-17T15:48:09.176102+09:00","id":"","remote_ip":"::1","host":"relaym.local:8080","method":"GET","uri":"/api/v3/sessions/8ad2607c-ba7d-404a-bbac-daee0ac6b9b0/","user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36","status":200,"error":"","latency":246266488,"latency_human":"246.266488ms","bytes_in":0,"bytes_out":1576}
{"time":"2020-06-17T15:49:15.252935+09:00","id":"","remote_ip":"::1","host":"relaym.local:8080","method":"GET","uri":"/api/v3/sessions/8ad2607c-ba7d-404a-bbac-daee0ac6b9b0/","user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36","status":200,"error":"","latency":512515585,"latency_human":"512.515585ms","bytes_in":0,"bytes_out":1576}
{"time":"2020-06-17T15:49:38.428509+09:00","id":"","remote_ip":"::1","host":"relaym.local:8080","method":"GET","uri":"/api/v3/users/me","user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36","status":200,"error":"","latency":485544353,"latency_human":"485.544353ms","bytes_in":0,"bytes_out":140}
{"time":"2020-06-17T15:49:38.780333+09:00","id":"","remote_ip":"::1","host":"relaym.local:8080","method":"GET","uri":"/api/v3/users/me/devices","user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36","status":200,"error":"","latency":345794954,"latency_human":"345.794954ms","bytes_in":0,"bytes_out":315}
{"time":"2020-06-17T15:49:38.806689+09:00","id":"","remote_ip":"::1","host":"relaym.local:8080","method":"POST","uri":"/api/v3/sessions","user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36","status":201,"error":"","latency":17035711,"latency_human":"17.035711ms","bytes_in":15,"bytes_out":227}
{"time":"2020-06-17T15:49:38.82734+09:00","id":"","remote_ip":"::1","host":"relaym.local:8080","method":"POST","uri":"/api/v3/sessions/fed77ba2-349a-4df4-b3de-b183158a09d7/queue","user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36","status":204,"error":"","latency":15296904,"latency_human":"15.296904ms","bytes_in":46,"bytes_out":0}
{"time":"2020-06-17T15:49:38.848952+09:00","id":"","remote_ip":"::1","host":"relaym.local:8080","method":"POST","uri":"/api/v3/sessions/fed77ba2-349a-4df4-b3de-b183158a09d7/queue","user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36","status":204,"error":"","latency":14024337,"latency_human":"14.024337ms","bytes_in":46,"bytes_out":0}
{"time":"2020-06-17T15:49:40.32785+09:00","id":"","remote_ip":"::1","host":"relaym.local:8080","method":"PUT","uri":"/api/v3/sessions/fed77ba2-349a-4df4-b3de-b183158a09d7/playback","user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36","status":202,"error":"","latency":1473746135,"latency_human":"1.473746135s","bytes_in":16,"bytes_out":0}
39.967s
{"time":"2020-06-17T15:49:49.19527+09:00","id":"","remote_ip":"::1","host":"relaym.local:8080","method":"GET","uri":"/api/v3/sessions/fed77ba2-349a-4df4-b3de-b183158a09d7/","user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36","status":200,"error":"","latency":809213462,"latency_human":"809.213462ms","bytes_in":0,"bytes_out":1574}
{"time":"2020-06-17T15:50:55.69981+09:00","id":"","remote_ip":"::1","host":"relaym.local:8080","method":"GET","uri":"/api/v3/sessions/fed77ba2-349a-4df4-b3de-b183158a09d7/","user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36","status":200,"error":"","latency":184547215,"latency_human":"184.547215ms","bytes_in":0,"bytes_out":1574}
{"time":"2020-06-17T15:50:59.454844+09:00","id":"","remote_ip":"::1","host":"relaym.local:8080","method":"GET","uri":"/api/v3/sessions/fed77ba2-349a-4df4-b3de-b183158a09d7/","user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36","status":200,"error":"","latency":168935218,"latency_human":"168.935218ms","bytes_in":0,"bytes_out":1574}
{"time":"2020-06-17T15:51:10.425086+09:00","id":"","remote_ip":"::1","host":"relaym.local:8080","method":"GET","uri":"/api/v3/sessions/fed77ba2-349a-4df4-b3de-b183158a09d7/","user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36","status":200,"error":"","latency":251831403,"latency_human":"251.831403ms","bytes_in":0,"bytes_out":1574}
{"time":"2020-06-17T15:51:12.777558+09:00","id":"","remote_ip":"::1","host":"relaym.local:8080","method":"GET","uri":"/api/v3/sessions/fed77ba2-349a-4df4-b3de-b183158a09d7/","user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36","status":200,"error":"","latency":237854461,"latency_human":"237.854461ms","bytes_in":0,"bytes_out":1574}
{"time":"2020-06-17T15:51:42.946031+09:00","id":"","remote_ip":"::1","host":"relaym.local:8080","method":"GET","uri":"/api/v3/sessions/fed77ba2-349a-4df4-b3de-b183158a09d7/","user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36","status":200,"error":"","latency":366246073,"latency_human":"366.246073ms","bytes_in":0,"bytes_out":1574}
{"time":"2020-06-17T15:52:21.298962+09:00","id":"","remote_ip":"::1","host":"relaym.local:8080","method":"GET","uri":"/api/v3/users/me","user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36","status":200,"error":"","latency":210370044,"latency_human":"210.370044ms","bytes_in":0,"bytes_out":140}
{"time":"2020-06-17T15:52:21.473713+09:00","id":"","remote_ip":"::1","host":"relaym.local:8080","method":"GET","uri":"/api/v3/users/me/devices","user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36","status":200,"error":"","latency":167234508,"latency_human":"167.234508ms","bytes_in":0,"bytes_out":315}
{"time":"2020-06-17T15:52:21.495944+09:00","id":"","remote_ip":"::1","host":"relaym.local:8080","method":"POST","uri":"/api/v3/sessions","user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36","status":201,"error":"","latency":15736408,"latency_human":"15.736408ms","bytes_in":15,"bytes_out":227}
{"time":"2020-06-17T15:52:21.514833+09:00","id":"","remote_ip":"::1","host":"relaym.local:8080","method":"POST","uri":"/api/v3/sessions/e16b726b-1402-4a42-9847-86a7038206fc/queue","user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36","status":204,"error":"","latency":13255847,"latency_human":"13.255847ms","bytes_in":46,"bytes_out":0}
{"time":"2020-06-17T15:52:21.534664+09:00","id":"","remote_ip":"::1","host":"relaym.local:8080","method":"POST","uri":"/api/v3/sessions/e16b726b-1402-4a42-9847-86a7038206fc/queue","user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36","status":204,"error":"","latency":14984152,"latency_human":"14.984152ms","bytes_in":46,"bytes_out":0}
{"time":"2020-06-17T15:52:22.628305+09:00","id":"","remote_ip":"::1","host":"relaym.local:8080","method":"PUT","uri":"/api/v3/sessions/e16b726b-1402-4a42-9847-86a7038206fc/playback","user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36","status":202,"error":"","latency":1087790486,"latency_human":"1.087790486s","bytes_in":16,"bytes_out":0}
40.009s
{"time":"2020-06-17T15:52:55.845103+09:00","id":"","remote_ip":"::1","host":"relaym.local:8080","method":"GET","uri":"/api/v3/sessions/e16b726b-1402-4a42-9847-86a7038206fc/","user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36","status":200,"error":"","latency":332134364,"latency_human":"332.134364ms","bytes_in":0,"bytes_out":1574}

(途中からおかしい)

対処方法

わからん

[docs] ローカル開発環境に関するドキュメントを書く

概要

ローカル開発環境に関するドキュメントを作成する。

要件

  • Goのインストール方法について書く
  • Dockerコンテナの起動の仕方を書く
  • サーバプロセスの起動方法を書く
  • APIにテストリクエストを送る方法を書く
  • goimports, golint, go vetに関する説明を書く

タスク

  • docs/development.md に内容を書く

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.