まったり技術ブログ

Technology is power.

『生つべ』というサービス作ったので利用技術の紹介

先日、『生つべ』というWebサービス開発しました。リリースをしたのはよいが「完成!」と言えるような状態になるのは、まだまだ時間が掛かりそう。
どのようなサービスなのかを簡単に説明をすると「YouTubeの動画を皆で見ながらチャットしようよ」というもの。

namatube.motikan2010.com

ソースコードも公開してある。

github.com

利用している技術・API群の紹介

認証

このサービスでは、動画の登録にはログインすることが必要です。
 「Twitter」と「GitHub」アカウントを用いたOAuth認証方式のみをサポートしています。

サービス内だけの認証(ログインIDとパスワードを登録)も用意しようか迷いましたが、最近のWebサービスでは、認証方法にOAuth認証のみというのを目にするようになっているので、今回はOAuth認証のみとしました。(2つのサービスのOAuth認証は少ないと思われるが・・・)

この記事通りにやったらできました。

【Rails4.2.x】omniauth(twitter/facebook/github)実装まとめ

◆ なぜGitHubアカウント?
 Twitterアカウントは多くの人が持っているので、認証方法として適していると思うが、なぜこのサービスに持っている人が限られているであろうGitHubアカウントを用いているかというと、こんな経緯があったりします。
 サービス開発の当初は、技術者向けのサービスとして開発しようと考えいました。具体的には、YouTubeをはじめとするニコニコ動画などといった動画配信サービスに登録されている技術系の動画を1つのサイトにまとめ、検索・評価できるようなサービス。 の予定だったが、途中で微妙...と感じ断念_(:3 」∠ )_ 。

もともとは「Tech TV」というサービス名だったという名残があります。

add アイコンの追加 · motikan2010/NamaTube@714a89f · GitHub

チャット

f:id:motikan2010:20180712213852p:plain

Rails5になって「Action Cable」というWebSocketを簡単に扱えるようになる機能が追加されたので利用しました。

Action Cable の概要 | Rails ガイド

モデルの構成など大枠の作成こちらを参考にしました。

Rails 5 + ActionCableで作る!シンプルなチャットアプリ(DHH氏のデモ動画より)

今回は動画毎にチャットルームが異なるようになっているので、ルーム毎にメッセージを送る方法は下記を参考にしました。

Rails 5 Action Cable メッセージとルームを紐付ける。

タグ生成

f:id:motikan2010:20180712214102p:plain  動画新規登録時のタグ生成の処理は「Google Natural Language API」を利用して実現しています。 その中のエンティティ分析を活用することにより、動画タイトルから固有名詞のみを抽出し、タグとして登録しています。

Googleクラウド自然言語APIを使ってみた

▼ APIを利用しているのは、この辺り

NamaTube/analyze_entity_util.rb at 20180710 · motikan2010/NamaTube · GitHub

動画の再生位置の制御

f:id:motikan2010:20180712214135p:plain 動画の埋め込みは「YouTube Player API」を利用しています。このAPIを活用することによって、動画ページを開いた時の再生位置を制御できています。

iframe 組み込みの YouTube Player API リファレンス  |  YouTube IFrame Player API  |  Google Developers

動画再生ページを開いた時の時間によって再生位置を決めていますので、このサービスの肝である「みんなが同じ動画を見ている」というはこの部分で実現されています。

▼ この辺りで再生位置の計算・制御を行っている

NamaTube/videos.js at 20180710 · motikan2010/NamaTube · GitHub

動画のタイトル・再生時間の取得

動画のタイトルや長さを取得は「YouTube Data API」を利用しています。

API Reference  |  YouTube Data API (v3)  |  Google Developers

▼ APIを利用しているのは、この辺り

NamaTube/youtube_api_util.rb at 20180710 · motikan2010/NamaTube · GitHub

動的なフロント部分

 動的なUIを実現するために「jQuery」と「React」で迷ったのだが、保守的なことを考えてReactを採用することにしました。JSXの方がタグ構造を直感的に把握しやすく、書き直しが簡単だと感じているので。  フロントに関しては、ほぼ知識がないようなものなので、とりあえず動くのを目指して実装。

新規登録画面

f:id:motikan2010:20180712215519p:plain

まずはこっちの方をReactで実装した。
▼ソースコード NamaTube/new.js at 20180710 · motikan2010/NamaTube · GitHub

編集画面

f:id:motikan2010:20180712215534p:plain
 最初は「React DnD」というライブラリを利用して、ドラッグ&ドロップで上下移動させることを考えていたのだが、想像よりも実装に時間が掛かりそうだったので断念。
 結局、ボタン押下で上下移動させるようにした。

React DnD

▼ソースコード

NamaTube/edit.js at master · motikan2010/NamaTube · GitHub

今後(TODO)

▲優先度高

  • トップページ(ランディングページ)の作成
  • スマホ向けのレイアウト
  • OAuth認証の対象を増やす
  • HTTPS化
  • マイページの拡充
  • アプリ固有のエラー画面の作成
  • React(フロント)側のリファクタリング
  • MySQLへの移行

▼優先度低

Unityビルド時にAndroidSDKToolsException エラー

Oculus Go向けにUnityプロジェクトをビルドを実施したら下記のようなエラーな出力された。

エラー

/Users/admin/unity/OculusGoSample/Temp/StagingArea/AndroidManifest-main.xml:4:16-57 Error:
    Attribute application@theme value=(@style/UnityThemeSelector) from AndroidManifest-main.xml:4:16-57
    is also present at AndroidManifest.xml:3:83-147 value=(@android:style/Theme.Black.NoTitleBar.Fullscreen).
    Suggestion: add 'tools:replace="android:theme"' to <application> element at AndroidManifest-main.xml:4:3-12:17 to override.

UnityEditor.HostView:OnGUI()
AndroidSDKToolsException: Unable to merge android manifests. See the Console for more details. 
UnityEditor.Android.AndroidSDKTools.DetectErrorsAndWarnings (System.String logMessages, System.String errorMsg)
UnityEditor.Android.AndroidSDKTools.RunCommandInternal (System.String javaExe, System.String sdkToolsDir, System.String[] sdkToolCommand, Int32 memoryMB, System.String workingdir, UnityEditor.Android.WaitingForProcessToExit waitingForProcessToExit, System.String errorMsg)
UnityEditor.Android.AndroidSDKTools.RunCommandSafe (System.String javaExe, System.String sdkToolsDir, System.String[] sdkToolCommand, Int32 memoryMB, System.String workingdir, UnityEditor.Android.WaitingForProcessToExit waitingForProcessToExit, System.String errorMsg)
UnityEditor.Android.AndroidSDKTools.RunCommand (System.String[] sdkToolCommand, Int32 memoryMB, System.String workingdir, UnityEditor.Android.WaitingForProcessToExit waitingForProcessToExit, System.String errorMsg)
UnityEditor.Android.AndroidSDKTools.RunCommand (System.String[] sdkToolCommand, System.String workingdir, UnityEditor.Android.WaitingForProcessToExit waitingForProcessToExit, System.String errorMsg)
UnityEditor.Android.AndroidSDKTools.RunCommand (System.String[] sdkToolCommand, UnityEditor.Android.WaitingForProcessToExit waitingForProcessToExit, System.String errorMsg)
UnityEditor.Android.AndroidSDKTools.MergeManifests (System.String target, System.String mainManifest, System.String[] libraryManifests, UnityEditor.Android.WaitingForProcessToExit waitingForProcessToExit)
UnityEditor.Android.PostProcessor.Tasks.GenerateManifest.MergeManifests (UnityEditor.Android.PostProcessor.PostProcessorContext context, System.String targetManifest, System.String mainManifest)
UnityEditor.Android.PostProcessor.Tasks.GenerateManifest.Execute (UnityEditor.Android.PostProcessor.PostProcessorContext context)
UnityEditor.Android.PostProcessor.PostProcessRunner.RunAllTasks (UnityEditor.Android.PostProcessor.PostProcessorContext context)
UnityEditor.HostView:OnGUI()
UnityEditor.BuildPlayerWindow+BuildMethodException: Build failed with errors.
  at UnityEditor.BuildPlayerWindow+DefaultBuildMethods.BuildPlayer (BuildPlayerOptions options) [0x001bf] in /Users/builduser/buildslave/unity/build/Editor/Mono/BuildPlayerWindowBuildMethods.cs:163 
  at UnityEditor.BuildPlayerWindow.CallBuildMethods (Boolean askForBuildLocation, BuildOptions defaultBuildOptions) [0x00050] in /Users/builduser/buildslave/unity/build/Editor/Mono/BuildPlayerWindowBuildMethods.cs:83 
UnityEditor.HostView:OnGUI()

解決

 Android SDK Toolsのバージョンがよくないらしい。 1. 下のサイトから「tools_r25.2.5-macosx.zip」をダウンロード

Android SDK Offline: Android SDK Tools

  1. SDKパス配下のtoolsディレクトリ(/Users/admin/Library/Android/sdk/tools)を上記手順でダウンロードしたフォルダに置き換える。

SDKパス確認は"External Tools"から確認できます。

参考

answers.unity.com

FlameScopeを使ってJavaアプリのパフォーマンス可視化

f:id:motikan2010:20180422143449p:plain

 今回はNetFlixが開発したOSSである「FlameScope』を利用して、Javaアプリケーションのパフォーマンスの可視化をしてみます。
 最終的には上記画像のように、一定期間のCPU利用割合をメソッド単位で表示させてみます。
これを利用することで、どのメソッドがボトルネックになっているのかを特定することが確認することができます。

github.com

続きを読む

【※修正済み】【Embulk】MySQL から Redshift へのレコードコピーで「改行&タブが消える」

f:id:motikan2010:20180407203434p:plain
 まず、MySQLからRedshiftへのコピーなんて「Amazon Data Pipeline」を利用しろよと思われますが、そんなお金はない(※調べてみるとクソ安かった)。

 なので、Embulkを利用して MySQLに格納されているデータをRedshiftへコピーしてみました。
そしてタイトル通り『文字行文字(\r\n)・タブ文字(\t)が消える』のような現象が起きました・・・。

各バージョン
  • embulk (0.9.4 java)
  • embulk-output-redshift (0.8.0)

まずはその事象を実際に確認してみます。

続きを読む

【embulk-input-redshift】大量データでエラーが発生したのでメモ

f:id:motikan2010:20180401005113j:plain
   最近、Embulkを使い始めましたが、想像していたよりも便利でした。データ量によってはエラーも発生するみたいでしたので、メモ程度に書き留めておく。

github.com

 Redshift上のデータをCSVファイルとして保存したり、その逆で、CSVファイルに記載されてるデータをRedshift上に保存したり(CREATE TABLE文も自動生成)可能。

 その便利さ故に、業務でも利用することになりましたが、Redshift上のデータ量が多いことが原因で発生したエラーがありましたので記載してきます。

 下記の設定で作成されたRedshiftインスタンスを使用した場合に発生したエラーの解決策を記述していきます。  結論から言いますと、どちらのエラーもMulti Node(ノード数を複数) でインスタンスを作成すれば解決できました。(貧乏人には辛い・・・)

利用していたRedshiftインスタンス情報
クラスタータイプ Single Node(ノード数:1)
ノードタイプ dc2.large
各バージョン
  • embulk (0.9.4 java)
  • embulk-input-redshift (0.9.1)

github.com

ケース 1 - FETCHの最大サイズを超えている

エラー内容

org.embulk.exec.PartialExecutionException: java.lang.RuntimeException: org.postgresql.util.PSQLException: ERROR: Fetch size 10000 exceeds the limit of 1000 for a single node configuration. Reduce the client fetch/cache size or upgrade to a multi node installation.

FETCH - Amazon Redshift

解決策

 embulk-input-redshift にはfetchサイズを設定するfetch_rowsオプションが存在しているので、「1000」を指定すればエラーは発生しなくなります。

in:
  type: redshift
  host: XXXXX.YYYYY.ap-northeast-1.redshift.amazonaws.com
  user: root
  password: "XXXXXX"
  database: sampledb
  fetch_rows: 1000
  table: users
  select: "*"

ケース 2 - DECLAREの上限

 こちらは取得対象であるテーブルに格納されているデータ容量が大きい場合に発生します。(dc2.large - ノード数 1 の場合は8,000MB)

エラー内容

org.embulk.exec.PartialExecutionException: java.lang.RuntimeException: org.postgresql.util.PSQLException: ERROR: exceeded the maximum size allowed for the total set of cursor data: 8000MB.

DECLARE - Amazon Redshift

解決策

  • 今のところノード数を増やす方法しかなさそう・・・。
    上記リンクの情報通り、ノード数を2にしたらエラーは発生しなくなった。