yasutomogのブログ

作業の備忘録としてリンクと一緒に簡単な説明を残す

CordovaのAndroidビルドエラーと環境構築

前提の環境

ビルドエラーについて

cordovaで開発するときに、Android用のビルドで以下のようなエラーが発生。

Starting 'cordova-with-build'...
(省略)
Error: Android SDK not found. Make sure that it is installed. If it is not at the default location, set the ANDROID_HOME environment variable.
'cordova-with-build' errored after 5.55 s

これだけ見ると「ANDROID_HOME」を設定すればいいように見えるが環境変数として、「ANDROID_HOME」に「~/Library/Android/sdk」を設定しても同様のエラーとなり解決せず。

確認

cordova requirementsコマンドでみると、以下のようにAndroid targetがnot installedになっている。

本来であれば、ここはAndroid StudioのSDKManagerでインストールした環境が表示されるはず。

$ cordova requirements android

Requirements check results for android:
Java JDK: installed .
Android SDK: installed
Android target: not installed
Android SDK not found. Make sure that it is installed. If it is not at the default location, set the ANDROID_HOME environment variable.
Gradle: not installed
Could not find gradle wrapper within Android SDK. Might need to update your Android SDK.

対応方法

・cordova platform rm android
・cordova platform add android

上記を試してた後に、改めてcordova requirementsコマンドを実行し、targetに正しく値が表示されていることを確認してOK

$ cordova requirements android

Requirements check results for android:
Java JDK: installed .
Android SDK: installed
Android target: installed android-21,android-22,android-23,android-24,android-25,android-26,android-27
Gradle: installed

iOSのPush通知(Apple Push Notification)のpemファイル作成

Push通知周りの証明書作成でいつもはまるのでメモ

現象

  • p12ファイル作成後、以下のようなopensslコマンドでpemファイルを生成
  • p12ファイルを生成するときに設定したパスワードを聞かれるので入力
  • Can't read Password というエラーが発生し、0バイトのpemファイルが作成される
openssl pkcs12 -in hoge.p12 -out fuga.pem -nodes -clcerts

解決策

  • iterm2を使って上記コマンドを叩くとエラーになるので、Macにデフォルトで入っているターミナルで全く同じコマンドを叩くことで正常にpemファイルが生成される

App Service(Microsoft Azure)とAzure SQL DatabaseのReconfiguration対応

概要

  • Azure環境でシステム開発している中で、Reconfigurationという現象に遭遇したので、その時の対応についてまとめる

Reconfigurationについて

  • Azure SQL Databaseには、サービスの仕様としてReconfigurationというものがある
  • Reconfigurationが発生すると、数秒〜数十秒の間、DB接続ができなくなる
  • Reconfigurationは、不定期で発生する(現状だと1ヶ月に2、3度)
  • Reconfigurationそのものは、安定したDBの稼働のために必要なものらしい
  • Azure SQL Databaseを使用するには、Reconfigurationが発生することを前提で開発する必要がある

[SQL Database] Reconfiguration (リコンフィグレーション) は悪ではない。 – Microsoft SQL Server Japan Support Team Blog

環境

本番環境

開発環境

Microsoftの公式ドキュメントの対処方法

  • Microsoftの公式ドキュメントでは、Reconfgiuration発生を検知し、wait後にリトライを実装する流れを推奨。
  • Reconfiguration発生時に使用した接続は使用できないため、改めて接続し直す必要がある。

[SQL Database] アプリケーション作成における推奨事項について (Microsoft Azure SQL Database) – Microsoft SQL Server Japan Support Team Blog

テスト方法

  • 基本的には、Reconfigurationは不定期に発生するが、意図的に発生させることも可能。
  • Azure SQL Databaseのプランを変更することで、プランが切り替わる間の数秒間だけReconfigurationが発生。
  • Azure Portal上からプラン変更して、SQL実行を連続して実行することでテスト可能。

ハマるポイント

Reconfigurationの判断

  • 本番でDB接続エラーが発生したときに、それがReconfigurationによるものなのかは現在MSサポートに問い合わせる必要がある。 以前までは、sys_event.logに出力されていたらしいが、現在は出力されない。

V12 の Azure SQL Database の sys.event_log に reconfiguration が記録されない (Document Version 1.0) – Microsoft SQL Server Japan Support Team Blog

  • Microsoft公式ドキュメントでは、Reconfiguration発生の判断をSQLのERRCODEで制御する方法を記載しているが、コネクションプーリングが有効になっていると古いコネクションを使用することでERRCODEに値が入らないことがある、そのときには、SQLSTATEしか入っていないため、そちらで判断する。(これはPHP以外の言語では大丈夫かも。ドライバの問題な気がする。)

リトライ処理をしても同様の接続エラーが発生

  • Lumenでは、リクエスト単位でPDOをキャッシュする機構がある
  • Lumenの機構を改修して、Recofiguration発生時にのみ、PDOを再生成して失敗したSQL実行という流れを単純に作って対応したが、 Reconfiguration発生時と同様の接続エラーが発生
    • Azure App Service(Windowsサーバ)上では、コネクションプーリングがデフォルトで有効になっている
    • Linux環境では、コネクションプーリングの設定はデフォルト無効となっている(開発環境はCentOSだったため、本番のみ再現することでハマる、、)
  • PDOを再生成しても内部ではReconfiguration発生時のプールを使用しているため、エラーが発生する

App Serviceのコネクションプーリングの制御

  • App Serviceのプラン(サーバスペック)によって、プールの最大数などが決まる仕様になっている
  • PHPからプールを破棄するAPIなどは用意されていない
  • PHPからアクティブなプール数を取得するAPIなどは用意されていない
  • コネクションプーリングを無効化すると、その都度確実に接続しにいくため、エラーが発生し続けることはない
    • 但し、遅くなる。

最終的な対応方法

  • 基本方針として、コネクションプーリングを一律無効化するのは、パフォーマンスの観点からNGなため、デフォルトはプールを有効化
  • 現状は対応1でも問題なく動いているため、様子見。これでも駄目な場合、別途キューのプロセス管理が必要になるが、対応2を検討

対応1

  • Reconfigurationを検知したときに、wait後、コネクションプーリングを無効化したPDOを生成し失敗時のSQLを再実行

対応2

  • Reconfigurationを検知したときに、システム全体でコネクションプールを無効化するように制御(PDO生成周りの処理改修)
  • キューに90秒後コネクションプールを有効化する処理を追加(プールの生存期間が60秒なため、若干の余裕を持たせる)

GitHubのリポジトリ(Issue)移行

移行方法

  • 移行元と移行先のリポジトリ管理者が同一の場合、GitHubのセッティングページからボタン1つで移行が可能。
  • 上記条件を満たさない場合は、自分で何かしらの移行スクリプトを書いてあげる必要がある。

移行プログラム

処理概要

  • GitHub APIを使用して移行元からIssue周りのデータをGetし、移行先のリポジトリへPostしていく流れ
  • Issueに必要なマイルストーンやラベルは最初にまとめて移行する
  • Issueは1件ずつPostして、それに紐づくコメントもその都度取得してPostする
  • Issueもある程度の件数になると、GitHubAPIが途中でエラーになることがあるため、簡易的なリトライ処理を実装
    • リトライ処理時は、前回とまったIssue番号を設定して、処理フローを切り替えて再実行とする(簡易的なので、コメントアウトを切り替えて対応)

github.com

プログラムの仕様

移行スクリプトを書いていく中ですべて完全に移行するのは難しく、割り切りが必要になった。

  • IssueのLabelとMilestoneはすべて移行する
  • Issueの移行は、移行元と移行先で同一のIssue番号を付与する
    • Postした順にIssue番号が採番されるため、移行元からIssueデータをソートして取得
  • Pull Requestは簡易的な移行とする
    • GitHubのIssueとPull Requestは1種類のidで管理されており、移行元と移行先のIssue番号をあわせるため、移行元でPull Requestだったものは、タイトルにその旨記載して空のIssueとして登録
  • Issueのコメントで使用している画像添付については、移行を諦める

macでディレクトリの差分抽出

これまで

Macで2つのディレクトリの差分を見る時に、Kaleidoscope — File comparison for Mac を使用していたが、開発端末が変わるタイミングで改めて他の方法がないか検討。

検討結果

開発ではPHPStormを使用していて、プロジェクトビューから対象ディレクトリを指定することで差分を取ることも可能だが、コマンドラインでもいけるということでメモ。

コマンドラインは以下。

/Applications/PhpStorm.app/Contents/MacOS/phpstorm diff dir1 dir2

問題なくいけそうなので、aliasを設定。
最近はfish shellを使い始めたので、以下のような感じでconfig.fishに設定。

balias psd '/Applications/PhpStorm.app/Contents/MacOS/phpstorm diff'

lumenのログ出力制御(rotateの方法)

デフォルトの設定

  • デフォルト設定のままだと、「ルート/storage/logs」配下に
    lumen.logが吐かれる。
    全てのログがこの1ファイルにずっと吐き続けられる。

laravelの設定

  • 「ルート/config/app.php」のlog(キー値)に対して設定してあげると
    rotateの制御をしてくれるみたい。

lumenでの対応

やりたいこと

  • 日付単位でrotateさせたい
  • ログを今後管理するのを考えた時に、日付はファイル名に付加しないで日付のディレクトリを配置して、その下に吐かれるようにしたい

対応方法

  • 「ルート/app」直下にApplication.php(以下のファイル)を作成
<?php

namespace App;

use Monolog\Logger;
use Laravel\Lumen\Application as LumenApplication;
use Monolog\Handler\StreamHandler;
use Monolog\Formatter\LineFormatter;
use Monolog\Handler\NewRelicHandler;
use Monolog\Handler\RotatingFileHandler;

class Application extends LumenApplication
{

    /**
     * Register container bindings for the application.
     *
     * @return void
     */
    protected function registerLogBindings()
    {
        $this->singleton('Psr\Log\LoggerInterface', function () {
            return new Logger('lumen', $this->getMonologHandler());
        });
    }

    /**
     * Extends the default logging implementation with additional handlers if configured in .env
     *
     * @return array of type \Monolog\Handler\AbstractHandler
     */
    protected function getMonologHandler()
    {

        $errorLogger = new RotatingFileHandler(storage_path("logs/{date}/error.log"), 0, Logger::ERROR, false);
        $infoLogger = new RotatingFileHandler(storage_path("logs/{date}/info.log"), 0, Logger::INFO, false);

        $handlers = [];
        $handlers[] = $this->setLoggerFileFormat($errorLogger);
        $handlers[] = $this->setLoggerFileFormat($infoLogger);

        return $handlers;

    }

    /**
     * Loggerのファイル名と日付フォーマットを設定
     *
     * @param $logger
     * @return mixed
     */
    private function setLoggerFileFormat($logger) {

        $logger->setFilenameFormat('{filename}', 'Ymd');
        $logger->setFormatter(new LineFormatter(null, null, true, true));
        return $logger;

    }

}

  • 「ルート/bootstrap/app.php」の中で$appのインスタンス生成しているところを
    作成したApplication.phpを生成するように変更
$app = new App\Application(
    realpath(__DIR__.'/../')
);

参考URL

laracasts.com

Sencha Ext JS6とPhoneGap Buildの連携

PhoneGap Build

前回はSencha Ext JS6とcordovaの連携について書きましたが、今回はSencha Ext JS6とPhoneGap Build(Adobe PhoneGap Build)について試してみたいと思います。

yasutomo.hatenablog.com

PhoneGap Buildがなにができるかというとリモートビルドで、ローカルの開発環境にいちいちcordovaやPhoneGapの環境を構築しなくても、Webアプリだけ作れれば、WindowsからもMacからもAndroidiOSのネイティブアプリ構築ができます。単純に環境構築が面倒くさいという点と、昔はiOSアプリに作るならまずMac買ってからということで、こういうサービスの需要があるのだと思います。

環境構築

  • 前回の記事で作ったものをそのまま流用します。
  • PhoneGap Buildのサービスのアカウントは作成しておいてください。

PhoneGap Buildに連携までの手順

1.app.jsonの編集 プロジェクトルート直下にある、app.jsonファイルを以下のように編集します。

  • 編集前

f:id:yasug:20151218004442p:plain

  • 編集後

f:id:yasug:20151218004451p:plain

2.local.propertiesの作成 プロジェクトルート直下に、local.propertiesファイルを作成してください。 中身はPhoneGap Buildで作成したユーザとパスを記載。

f:id:yasug:20151218004612p:plain

3.Sencha Cmdでビルド実行

sencha app build remote

※既にPhoneGap Build上にアプリがある場合、無料アカウントだと1つしか作成できないので、ビルド前に削除しておいてください。

4.Web上で確認 以下のようにリモート上でビルドされたものが見えると思います。

f:id:yasug:20151218004735p:plain

まとめ

2回に分けてSencha Ext JS6でハイブリッドアプリ開発について書いてみました。 PhoneGap Buildは作成できるアプリの数に制限はありますが、無料で使用することも可能なのでアカウント作って試してみて頂ければと思います。