« 2015年9月 | メイン | 2015年11月 »

2015年10月

2015年10月29日 (木)

Wercker v2(Ewok)でSpringBootのビルド時間を短縮する

ブログには久しぶりの登場、浅野でございます。 戻り鰹の漁にいっており、ブログが更新できておりませんでした。

さて、今回のネタは久しぶりのWerckerネタ。ターゲットは以下の条件全てに当てはまる方です。

  • JVM系の言語を使っている
  • Werckerをv1のころから使っていて、v2へ移行している
  • Werckerは、v1ではキャッシュがあってビルドで余分な時間かかんなかったのになーと懐かしんでいる

これで大体わかるかと思うのですが、v2(Ewok)でキャッシュが使えるようになってました。 情報ソースは公式サイトのこちら。(Werckerをキーワードに検索するとV1の情報とごっちゃになってしまってわかりづらいので v2の情報だけに絞り込むには、ewok をキーワードに追加するといいらしいです)

キャッシュを有効にする

環境変数 $WERCKER_CACHE_DIR のパスがキャッシュとして使えるディレクトリです。 このディレクトリ配下に、gradleがダウンロードするファイルを格納すると、次回以降のビルド時にはダウンロードが省略されてビルド時間が短縮されます。 その設定はこんな感じ。

- script:
    name: setup gradle local cache
    code: |-
        mkdir -p $WERCKER_CACHE_DIR/.gradle
        ln -sf $WERCKER_CACHE_DIR/.gradle ~/.gradle

こうする事で、SpringBootベースのWebアプリケーションのビルド時間が約4.5分から約2.5分と2分前後の短縮になりました。 この $WERCKER_CACHE_DIR がキャッシュ用ディレクトリになるのは、v1でも同じでした。過去に蓄積したノウハウがそのまま使えるのは嬉しい限りですね。 (前の案件は、Wercker v1を使っていて、その時にwerckerでmavenのpomをキャッシュする方法を参考にSBTのビルド時間を短縮した、というのがあり、今回もそれをほぼそのまま踏襲できました。)

この手順は、今回題材にしたgradle以外のビルドツールでも使えるかと思います。 ただ公式サイトに書いてある通り、 npm-install, bundle-install, pip-install に関してはデフォルトでキャッシュが効くので対応不要です。

それでは、みなさんもよきCIライフを!

2015年10月20日 (火)

DynoTypeが2ヶ月前に増えていたのご存知ですか?

はい、どうも。 最近、料理をサボりがちのおっぴーです。

じーちゃんも目を見開いて喜んだPrivateSpacesの登場がフレクトの社内でも話題になっております。 現在はPrivateβ版ということでGAになるのが楽しみですね。

こうしたHerokuのサービスについて、公式で最新情報を知る一番の方法は、Herokuの公式ブログをみることですね。 普段からこのブログの内容に目を通したい人は、ここからフィードの購読登録しておくのがお薦めです。

また、サービスの変更履歴はつどtwitterにも流れているので、こちらをフォローするもよい方法ですね。

個人的には「最近、Herokuは積極的にサービスをアップデートしているな!」と感じており、そのすべてをこのブログでご紹介したいと思いつつ、紹介しきれていない、というのが実情です。

今回は、ご紹介できなかったことの1つとして新たなDynoTypeが増えました!というお話です。 約2ヶ月も前のお話ですが、お付き合いくださいませ。

以前、PeformanceDynoのスケールアップについて速報としてお伝えしたあと、ほとんど間をおかずに発表された内容です。 しかもその際に、

「とくに2XDynoとPXDynoの間を埋める性能の新Dynoの登場があるとうれしい」

と書いていたのですが、それを実現するようなアップデートで発表された時はびっくりしたものです。 このアップデートにより、performance-mというDynoが登場し、いままでperformance Dynoと呼ばれていたDynoはperformance-l(える?と読むのかな)という名前になりました。

dyno type memory compute price
standard-1x 512MB 1-4X $25/mo
standard-2x 1GB 2-8X $50/mo
performance-m 2.5GB 12X $250/mo
performance-l 14GB 50X $500/mo

フレクトではBtoB向けのシステム構築の際でも、Herokuをよく利用しています。 こうした時にシステム構築で、重要なのは、選択肢の多さです。 選択肢が多いほど、良い選択をするのは大変なのですが、一方で、提案内容の幅が広がり顧客が達成したいことにあわせたご提案がしやくすなります。

今回のDynoTypeが増えたという件については、HerokuはAWS上に構築されるPaaSなので、おそらく技術的な課題はあまり多くなかったのではないか、と勝手に推測しています。 というのも、AWSには多数のインスタンスタイプがあり、ハードウェアまわりのパフォーマンスのスケールアップはお手の物、対応するインスタンスタイプをHerokuが増やしただけと考えられるからです。

こうしたことからDynoTypeへの対応は、技術的な興味がそそられるものではないかもしれませんが、上記のとおりHerokuの用途を広げ提案の幅を広げてくるという点からビジネス的には大きな価値を感じています。

わたしとしても、個人の開発者としては無料でできることが広がった方がうれしい気持ちはあるのですが、実際のビジネスにおいては提案の幅が広がり、安定したパフォーマンスを実現できるDynoが増やしてほしいというニーズのほうが大きいからです。

そして、アップデート内容を見ていると、Herokuが私たちのビジネスに寄り添った考え方をして、サービスをアップデートしてくれている、という安心感がもっています。 また、今後もサービスを拡張していってくれる期待感ももっています。

実際にHerokuを利用して、エンタープライズ系のシステムづくり取り組んでいるフレクトとしては、Herokuのこうしたアップデート内容が今後も続くように期待しております。

ということで今回は新しいDynoTypeが増えました、というお知らせでした。

「こんなことを調べて書いてほしい!」などありましたら、コメントをいただけるとうれしいです。 可能限り調査して回答編をブログとしてアップしたいと思います。

2015年10月16日 (金)

Angular2.0を見すえたAngularJSアプリケーション開発

こんにちは、JavaScripterの三宅です。
最近AngularJSを用いたアプリケーションを開発する機会が多いのですが、その際の考え方や実装の方針について書いていきます。
説明に使うソースコードはここで確認することができます。

Angular1.xとAngular2.0

現在、angular.ioでAngular2.0の開発が進められています。
正式なリリース日は発表されていないのですが、2015年末から2016年初めと言われています。
現時点ではまだα版でありまだ仕様が決定していないのですが、Angular1.xと比較し別のフレームワークと言えるほどの大きな変更が加えられます。
特に以下の変更はアプリケーションのアーキテクチャによっては、移行に際して大幅な改修が必要になることが予想されます。

  • TypeScript/ECMAScript6の採用
  • Controllerや$scopeの廃止によるコンポーネントベースへの変化
  • 双方向データバインディングの廃止

現時点でα版の2.0を採用することは現実的でなはいのでAngular1.xを用いることになるのですが、新しくアプリケーションを開発する際は上記を意識したアーキテクチャとすると、将来2.0がリリースされた際にスムーズに移行できるのではないかと考えています。
今回は、上記の3点を踏まえてどのような考え方で実装しているかを簡単に紹介していきます。

TypeScript/ECMAScript6の採用

AngularJSに限らず、新しいプロジェクトではほぼECMAScript6(ES6)を用いて開発しています。
ES6で追加された機能が魅力的であることに加え、Babelなどのトランスパイラの充実、Node.jsのES6のサポートなど、ブラウザ、サーバサイド共にES6を利用できる環境がほぼ整ったと考えているためです。
AngularJSは独自のモジュール機構を有しているため、JavaScriptファイルを全て結合してからトランスパイルする手法を取ることが多いのですが、Angular1.3.14からCommonJSが採用されたため、Browserifyなどのモジュール管理の仕組みを用いることも可能だと思います。

class MyAppComponent {
  constructor(PersonDataStore) {
    this.PersonDataStore = PersonDataStore;

    this.person = PersonDataStore.person;
  }
}

上記はControllerをES6のClass構文を用いて定義したものです。

angular.module('app').controller('MyAppComponent', MyAppComponent);

controller()メソッドの引数として定義したクラスを渡すと、Controllerとして登録することができます。
クラスのconstructor()の引数であるPersonDataStoreはServiceで、DIを行っています。現在のプロジェクトでは、いわゆるminify対策としてng-annotateを使っていますが、使わないのであれば、constructor()内に以下を追記することで対応可能です。

MyAppComponent.$inject = ['PersonDataStore'];

コントローラを利用する際は、ng-controller="MyAppComponent as app"のようにController As構文を用います。
これにより、Viewから$scopeを介さずに直接Controllerを参照でき、クラスで定義したプロパティやメソッドを利用することができます。

コンポーネント志向

Angular2.0はReact.jsの同様のコンポーネント志向のフレームワークとなります。
データとロジックをカプセル化したコンポーネントを定義し、それを組み合わせていくことでアプリケーションを構築するイメージです。
アプリケーション全体の状態やデータを保持するルートコンポーネントを起点としたツリー構造となります。
React.jsではコンポーネントのデータは親コンポーネントから与えられ、通常不変となります。コンポーネントの状態が変更された際はその配下のコンポーネントは全て再描画されます。
React.jsはVirtual DOMを用いて差分だけを実際に再描画することでパフォーマンスを担保しています。Angular1.xはその仕組みを持たないので変更が起こった際に再描画を行うのは現実的ではありませんが、ツリー構造であること、ルートコンポーネントが状態を持つことを意識することで、データの流れが把握しやすくなります。

class GreetingComponent {
  constructor($scope) {
    this.name = null;

    $scope.$watch('name', (newValue) => {
      this.name = newValue;
    });
  }
}

function createGreetingComponent() {
  return {
    controller: GreetingComponent,
    controllerAs: 'greeting',
    template: '<h1>Hello {{greeting.name}}</h1>',
    scope: {
      name: '=appName'
    }
  };
}

angular.module('app')
.directive('appGreeting', createGreetingComponent);

Angular1.xのDirectiveを用いてコンポーネントを作成したコードです。

<app-greeting app-name="{{parent.value}}"></app-greeting>

Directiveを利用する際は、上記のように記述します。
app-nameはコンポーネントが親コンポーネントから与えられるデータで、Directiveの$scopeのプロパティとなります。
GreetingComponentのconstructor()でクラスのプロパティにその値を代入し、コンポーネントの内部ではその値を利用します。

$scope.$watch('name', (newValue) => {
  this.name = newValue;
});

constructor()内で、$scopeのnameプロパティを監視する記述です。再描画の代替として親コンポーネントから与えられた値が変更された際に、そのイベントをトリガとして明示的にクラスのプロパティをアップデートします。
ブラウザにレンダリングされる値は、Angularの双方向データバインディングによってクラスのプロパティがアップデートによって更新されます。

双方向データバインディングの廃止

Angular1.xの特徴とも言える双方向データバインディングはAngular2.0では廃止されます。
双方向データバインディングは非常に便利ではあるのですが、個人的には以下の理由から限定的な範囲で利用するようにしています。

  • 複数のController間やネストしたスコープ間でモデルを共有した際にいつ、どこで値が変更されたのか把握できず、バグの温床になる
  • モデルの更新方法によっては(setTimeout()など)画面の更新が行われず、コンポーネントを定義する際に外部の状態を意識する必要がある

 

class Person {
  constructor(name) {
    this.name = name;
  }
}

class PersonDataStore {
  constructor() {
    this.person = new Person('Alice');
  }
}

angular.module('app')
.service('PersonDataStore', PersonDataStore);

サンプルでは、データを保持するServiceを定義しています。ルートコンポーネントがデータの参照を保持し、それを配下のコンポーネントに伝達するような構成としています。

class TextFieldComponent {
  constructor($scope, PersonDataStore) {
    this.PersonDataStore = PersonDataStore;
    this.text = $scope.text;
  }
  didChange() {
    this.PersonDataStore.person.name = this.text;
  }
}

function createTextFieldComponent() {
  return {
    controller: TextFieldComponent,
    controllerAs: 'textField',
    template: '<input type="text" ng-model="textField.text" ng-change="textField.didChange()"></input>',
    scope: {
      text: '=appText'
    }
  };
}

angular.module('app')
.directive('appTextField', createTextFieldComponent);

ng-modelの双方向バインディングによってTextFieldComponentのtextプロパティは入力によって更新されますが、そのスコープはコンポーネントの内部に閉じています。
ng-changeによって呼び出される、didChange()メソッドによって変更された値でDataStoreが保持するオブジェクトのプロパティを明示的に更新しています。
各コンポーネントも親から渡されたDataStoreの参照を$scopeに保持していますが、その変更をViewに反映するのは各コンポーネントの責務となります。
GreetingComponentは$scope.nameが変更された際に自身のnameプロパティにその変更を反映しViewを更新していますが、TextFieldComponentは特にアクションを行いません。親コンンポーネントから渡されたデータは、初期値の設定にしか用いないようになっています。
このように、DataStoreからルートコンポーネントを経由し、その配下のコンポーネントというような一方向のデータフローのアーキテクチャとすることで、モデルの値の変更を制御しやすくなると考えています。


今回は簡単なサンプルで、コンポーネントベース、一方向のデータフローのアーキテクチャに基づくAngularJSアプリケーションの考え方を説明しました。
実際の開発ではui-routerの利用やサードパーティのライブラリを用いる場合など、そのまま適用できないケースもあるとは思います。
また、CSSも合わせてコンポーネント志向の設計とする必要が出てきます。
ただコンポーネントベースの考え方は、 Angular2.0だけでなくReact.jsでも取り入れられていること、HTML/JavaScript/CSSを一つのコンポーネントとして定義するWeb Componentsの策定が進んでいることなどから、今後のフロントエンドアプリケーションのスタンダートになってくると予想されます。
AngularJSを用いない場合でも、今回説明した考え方は有効だと思います。

2015年10月 9日 (金)

【Herokuお絵かき】じーちゃん!東京リージョンできたよ!

こんにちは、中山です。

今日はHerokuが東京リージョンにやってきたのお話になります。

Tokyo_01

 

9月のことでした。

インターネット中のたろうはHerokuに関するニュースを見つけたようです。

Tokyo_02

 

なんと、Herokuが東京リージョンにやってくるようです!

Introducing Heroku Private Spaces: Private PaaS, delivered as-a-Service

Tokyo_03

 

たろうは、じーちゃんが東京リージョンに来てほしいって言ってたことを思い出しました。

Tokyo_04

 

じーちゃん!このニュースをみて!

東京リージョンでHerokuが使えるんだって!!

Tokyo_05

 

でもおかしいな。

アプリを作るときに東京リージョンの指定ができなかったことを思い出しました。

Tokyo_06

 

うーん。

じーちゃんからはニュースを読んでみるのじゃと言われる。

Tokyo_07

 

 Private Spacesでつかえるとのこと。

Tokyopdf_08

 

どうやったらPrivate Spacesに参加できるのかな?

Tokyo_09

 

記事を読むとHeroku Enterpriseの一つとして使えるようです。

Tokyo_10

 

Heroku Enterpriseってなんだろう?

Tokyo_11

 

Heroku Enterpriseの契約をすると、こんなことができるようです。

・Herokuの困ったことを日本語で問い合わせ可能

・アプリを作る上でのアカウントの細かい権限管理

・複数のアプリの一括請求

などなど。

Tokyo_12

 

hobby環境で開発しているたろうには、遠い存在のようです。

Tokyo_13

 

じーちゃん曰く

BtoC向けのWebサービスをHeroku使って日本で展開したいなら

どんぴしゃじゃー!!!

とのことでした。

Tokyopdf_14

 


大事なことなので2回言いました

Tokyo_14

 

 

今日のお絵かきはこんな感じで、おしまい。

Tokyo_15

 

 

おしらせ。

2015/12/3〜4にSalesforceの大きなイベントがありますよ。

エンジニア向けなのは、12/4の虎ノ門ヒルズフォーラムですね!

http://eventjp.salesforce.com/

忘れないように参加登録しておきましょう!

採用情報

株式会社フレクトでは、事業拡大のため、
Salesforce/Force.comのアプリケーション
開発
HerokuやAWSなどのクラウドプラッ
トフォーム上でのWebアプリケーション開発

エンジニア、マネージャーを募集中です。

未経験でも、これからクラウドをやってみた
い方、是非ご応募下さい。

フレクト採用ページへ

会社紹介

株式会社フレクトは、
認定コンサルタント
認定上級デベロッパー
認定デベロッパー
が在籍している、
セールスフォースパートナーです。
heroku partnersにも登録されています。
herokuパートナー
株式会社フレクトのSalesforce/Force.com
導入支援サービス
弊社の認定プロフェッショナルが支援致します。
・Visualforce/Apexによるアプリ開発
・Salesforceと連携するWebアプリ開発
も承っております。
セールスフォースご検討の際は、
お気軽にお問合せください。
Powered by Six Apart