2010年6月15日火曜日

Rhomobile RhoSync 2.0

以下のドキュメントは、英語の原文を日本語へ翻訳したものをRhomobile社の許可のもと、公開しています。
公式なドキュメントはRhomobile社のサイトをご覧ください。
また、この文書は2010/6/8(JST)の情報がもとになっています。
この日本語の翻訳について問題・質問などがある場合、コメントを残してください。それ以外については、本ドキュメント内にある問い合わせ先にお願いします。

The following document (a translation of the English original into Japanese) is published with Rhomobile permission.
If you need official documents, please visit Rhomobile site.
In addition, the following document is based on 2010/June/8 (JST) information.
If you have any question, problem about the Japanese translation, please leave your comment. Except for that, refer contacts in the document.

RhoSync 2.0


目次

Rhosync

RhoSyncは、エンタープライズアプリケーションのデータをユーザのスマートフォン上で利用可能にするサーバー型同期ツールです。情報はユーザーのローカルデバイスに格納され、切断やオフライン時でも利用可能です。

RhoSyncインストール

製品には最新のstableバージョンをインストールし、edgeバージョンの使用は開発目的のみに使用することを強く推奨します。

前提条件

必須

  1. ruby - v1.8.7 + RubyのWindowsインストーラ1.8.7
  2. RubyGems - v1.3.7 + RubyGemsは1.3.7
  3. Redis - v1.2.6
  4. Ruby Webサーバー-mongrelでテストしています。rubyに付属するデフォルトのWevサーバー,WEBrickはHTTPのheaders/cookiesにおいて問題の原因として知られており、推奨していません。
  • 注:私たちはredis1.2.6を使用してテストしています。redis 2.0 rc1が作業中の間、final 2.0がリリースされるまで、公式にサポートしません。

Redisのインストール

注:redisを提供されるrhosync rake tasksで管理したい場合、このセクションを飛ばしてください。

POSIXシステムでは:

 wget http://redis.googlecode.com/files/redis-1.2.6.tar.gz
tar xvzf redis-1.2.6.tar.gz
cd redis-1.2.6
make
./redis-server

Windowsシステムでは:

redis 1.2.6 for wondowsをダウンロードして、解凍します。
そしてredis-server.exeを起動します。redis-server.exeを起動します。

オプション

  1. Java JDK -BlackBerryデバイスでバルク同期を使用する場合、Java 1.6が必要です。
  2. sqlite3 Ruby driver -Cプラットフォームでバルク同期を使用する場合、sqlite3-ruby gemのインストールが必要になります:
[sudo] gem install sqlite3-ruby

注:Windowsの場合は、sqlite3.dllをrubyのbinディレクトリ(例 c:\Ruby\bin)へ追加する必要もあります。

安定版インストール

[sudo] gem install rhosync

ベータ版のインストール

[sudo] gem install rhosync --pre

これはrhosyncの最新pre-releaseタグをインストールします。

エッジバージョンをインストール

最新のEdge RhoSyncをインストールするには、あらかじめgitをインストールしおかなければなりません:

 git clone git://github.com/rhomobile/rhosync.git
cd rhosync
[sudo] gem install jeweler
[sudo] rake install

RhoSync 2.0対1.x

RhoSync 2.0はRhoSyncシステムを完全に書き直したものです。スタンドアロンのアプリではなく、今ではバンドルされたコンポーネントが付属したrubyライブラリとなっています。これは重要な違いです。なぜなら、rhosync rails appにプラグイン・コードを書く代わりに、2.0ならばRhoSyncアプリを書くことになるからです。RhoSyncアプリを書くのに、もはやrailsは必要がなくなったのです。必要なものはrhosync gemとredisです

RhoSyncの開発ワークフローは、今や、Rhodes開発ワークフローと同じようになりました。

  1. rhosync app helloworld-server #=> generates a new rhosync app
  2. cd helloworld-server
  3. rhosync source person
  4. specコードを書いたり、person adapterコードを書いたり
  5. テスト、修正、繰り返して...
  6. helloworld-server をdeployする
  7. helloworld Rhodesアプリをhelloworld-serverに接続する

RhoSync2.0の構成:

  • 同期フレームワーク - RhoSyncコア、これはRhodesクライアントとサードパーティ製のソース(SOAP,RESTなど)間のデータ同期を容易にします。各ソースは、単純な"ソースアダプタ"クラスを実装することによって同期されます。ソースアダプタの集合と双方向にやりとりするために、Rhodesのクライアントは組み込まれたsinatraサーバに接続します。ソースアダプタAPIはいくつかの機能強化と小規模な変更がありますが、パラダイムは1.xと同様です。詳細については、rhosunc 1.x ソースアダプタを2.0へ移行参照してください。
  • REST API -RhoSync APIを参照してください。
  • 管理コンソール - 動作しているRhoSyncアプリの操作や状態を見ることに使用されます。コンソールはそれらすべてにおいてRhoSyncのAPIを使用します。
  • 非同期ジョブ- RhoSync 2.0は実行する必要があるタスクの非同期実行を提供するために、resqueライブラリを使用します。これらのタスクは、ソースアダプタの実行、プッシュメッセージの送信、バルクデータの準備などを含みます。Resqueはとても簡単に使え、拡張性も高いので、ここで説明されないその他の機能のためにも簡単に利用することができます。

RhoSyncアプリケーションを作成する

RhoSyncアプリケーション生成

まず、アプリケーションをRhoSyncコマンドラインユーティリティを使用して生成することから始まります:

 rhosync app helloworld
cd helloworld

dtachのセットアップ

MacOS/Linuxを使っている場合、このpath上でdtach をインストールします:

 [sudo] rake dtach:install

Redisのセットアップ

前のセクションで既にredisをインストールや起動していないなら、RhoSyncアプリケーションのディレクトリから行うことができます:

 [sudo] rake redis:install
rake redis:start

アプリケーションの起動

そして、サーバを起動しましょう!

rake rhosync:start

すべてがうまくいった場合は、コンソールで次のようなメッセージが見られるでしょう:



[07:01:15 PM 2010-05-04] Rhosync Server v2.0.0.beta7 started...
[07:01:15 PM 2010-05-04] ************************************************************

[07:01:15 PM 2010-05-04] WARNING: Change the session secret in config.ru from <changeme> to something secure.
[07:01:15 PM 2010-05-04] i.e. running `rake secret` in a rails app will generate a secret you could use.

[07:01:15 PM 2010-05-04] ************************************************************

Webコンソールを開くには、ブラウザでhttp://localhost:9292/に移動するか、以下のコマンドを実行します:

 rake rhosync:web

RhoSyncソースアダプタの作成

RhoSyncでは、目的とするエンタープライズ・バックエンドのquery(クエリ)、create(作成)、update(更新)、およびdelete(削除)の少量のコードを書くことが要求されます。これらのオペレーションのためのrubyコードの集合を私たちは"ソース"または"ソースアダプタ"と呼びます。

ソースアダプタの生成

rhosyncアプリケーションに新しいソースアダプタを追加するのは簡単です:

 cd <my-rhosync-app>

rhosync source product

これは、sources/product.rbと呼ばれる新しいrubyファイルを生成します:

class Product < SourceAdapter
def initialize(source,credential)
super(source,credential)
end

def login
# TODO: Login to your data source here if necessary
end

def query
# TODO: Query your backend data source and assign the records
# to a nested hash structure called @result. For example:
# @result = {
# "1"=>{"name"=>"Acme", "industry"=>"Electronics"},
# "2"=>{"name"=>"Best", "industry"=>"Software"}
# }
raise SourceAdapterException.new("Please provide some code to read records from the backend data source")
end

def sync
super
end

def create(create_hash,blob=nil)
# TODO: Create a new record in your backend data source
# If your rhodes rhom object contains image/binary data
# (has the image_uri attribute), then a blob will be provided
raise "Please provide some code to create a single record in the backend data source using the create_hash"

end

def update(update_hash)
# TODO: Update an existing record in your backend data source
raise "Please provide some code to update a single record in the backend data source using the update_hash"
end

def delete(object_id)
# TODO: write some code here if applicable
# be sure to have a hash key and value for "object"
# for now, we'll say that its OK to not have a delete operation
# raise "Please provide some code to delete a single object in the backend application using the hash values in name_value_list"
end

def logoff
# TODO: Logout from the data source if necessary
end
end

また、specファイルspec/sources/product_spec.rbを追加し、settings/settings.ymlを編集し、いくつかのデフォルト値でproduct adapterをsources sectionへ追加します:

#Sources 
:sources:
Product:
:poll_interval: 300

これでソースアダプタのメソッドを実装したことになります。さらなる詳細はチュートリアルを見てください。

ソースアダプタのAPI

  • login(ログイン)
  • logoff(ログオフ)
  • query(クエリー)
    • stash_result
  • search(検索)
  • create(作成)
  • update(更新)
  • delete(削除)
  • @source - source settings(ソースの設定)
  • current_user - 要求を発行する現在のユーザーの処理

データ・パーティショニング

RhoSync 2.0のソースアダプタは2つの方法でデータをパーティションすることができます:ユーザーとアプリです。推測のように、ユーザー・パーティションは、各ユーザのソースアダプタのデータセットのコピーを格納します(1つのコピーは1ユーザーのすべてのデバイス間で共有されます)。

同様に、アプリケーション・パーティションはアプリ全体のソースアダプタの1コピーを格納します(すべてのユーザとデバイスが同じデータを共有します)。アプリ・パーティションは、ユーザごとに変化しない大量のデータを取得するソース・アダプタの場合、特に便利です。例えば、製品カタログのようなものです。

ユーザーパーティション

ユーザーのパーティションは、ソースアダプタのデフォルトの方式ですが、明示的にsettings/settings.ymlでそれを定義することができます:

:sources: 
Product:
:poll_interval: 300
:partition_type: user
アプリケーションパーティション

同様にアプリパーティションを有効にします:

:sources: 
Product:
:poll_interval: 300
:partition_type: app

これで、すべてのユーザーに対して製品データセットの1つのコピーを持つことになります。

RhoSyncアプリケーションのテスト

RhoSync 2.0は、動作駆動型開発のためにspecフレームワークを提供します。アプリケーションとソースアダプタが生成されるときに、アプリケーションの最上位の'spec"フォルダー中にspecファイルが生成されるのが分かるでしょう。

rhostoreのproductアダプタの簡単なspecのサンプルです:

it "should process Product query" do
test_query.size.should > 0
query_errors.should == {}
end

この単純なspecは、productアダプタのqueryメソッドを実行し、一つ以上のオブジェクトがあること、エラーがないことを検証します。

productアダプタの完全なコードはGitHub上で入手可能です。

TestMethods API

最新のTestMethods APIは、hosted rdocsを見てください。

setup_test_for(adapter,user_id)

指定されたユーザー用のテストのためソースアダプタを初期化するには、通常(:each) blockの前に以下を記述します。

setup_test_for(Product,'testuser') #=> 'testuser' will be used by rest of the specs

test_query

アダプタのqueryメソッドを実行し、redisに格納されているmaster document(:md)を返します。

たとえば、ソースアダプタのクエリメソッドがこのような場合:

def query(params=nil)
@result = {
"1"=>{"name"=>"Acme", "industry"=>"Electronics"},
"2"=>{"name"=>"Best", "industry"=>"Software"}
}
end

test_queryは以下のような結果を返すでしょう:

{ 
"1"=>{"name"=>"Acme", "industry"=>"Electronics"},
"2"=>{"name"=>"Best", "industry"=>"Software"}
}

query_errors

redisに格納された、直前のソースアダプタのqueryのエラーを返します。

たとえば、
{"query-error"=>{"message"=>"error connecting to web service!"}}

test_create(record)

与えられたレコードをアダプタのcreateメソッドで実行し、createメソッドからオブジェクトの文字列を返します。createメソッドが文字列を返したら、デバイスが次回同期するためにリンクが保存されます。このリンクはここでテストできます。

たとえば、specで以下のようになります:

@product = {
'name' => 'iPhone',
'brand' => 'Apple',
'price' => '$299.99',
'quantity' => '5',
'sku' => '1234'

}
new_product_id = test_create(@product)
create_errors.should == {}
md[new_product_id].should == @product

create_errors

これはアダプタのcreateメソッドの結果を返します。マスタドキュメント(:md)は新しいレコードも含んでいるでしょう。この前のソースアダプタでcreateした以降の、redisに格納されたどんなエラーも返ります。(query errorsと同じ構成です)

test_update(レコード)

ソースアダプタのupdateメソッドを実行します。ハッシュのハッシュとして(object_id => object)、レコードを受け取ります。

たとえば、

test_update({'4' => {'price' => '$199.99'}})
update_errors.should == {}
test_query
md[product_id]['price'].should == '$199.99'

これは、object_idが'4'のアダプタのUpdateメソッドを呼び出します。

注:マスタードキュメントをテストするには、上記のようにtest_queryを実行する必要があります。

update_errors

以前のソースアダプタのupdate以降からのredisに格納されたエラーを返します(クエリのエラーと同様の構造)。

test_delete(record)

ソースアダプタのdeleteメソッドを実行します。ハッシュのハッシュとして(object_id=>object)レコードを指定します。

たとえば、

@product = {
'name' => 'iPhone',
'brand' => 'Apple',
'price' => '$299.99',
'quantity' => '5',
'sku' => '1234'

}
test_delete('4' => @product)
delete_errors.should == {}
md.should == {}

これは、製品'4'のアダプタのdeleteメソッドを呼び出します。

注:master document(:md)は更新され、上記のように確認することができます。

delete_errors

直前のソースアダプタのdelete以降からのredisに格納されたエラーを返します(クエリのエラーと同様の構造)。

md

redisに格納されたソースアダプタのマスタドキュメント(:md)を返します。これは@result ハッシュのハッシュ構造と同様です。

たとえば、

md.should == { 
"1"=>{"name"=>"Acme", "industry"=>"Electronics"},
"2"=>{"name"=>"Best", "industry"=>"Software"}
}

cd

ソースアダプタとテスト中のクライアントのclient document(:cd)を返します。master document(:cd)とclient document(:cd)はqueryが実行されたあと、等しくなります。

たとえば、

test_query.size.should > 0
md.should == cd

RhoSyncアプリケーションのデプロイ

RhoSync 2.0アプリケーションは標準的なsinatraアプリケーションです。シナトラ本には、RhoSyncアプリケーションを製品として稼働させる前にぜひ読むべき素晴らしいいくつかのデプロイドキュメントがあります。

デバイスに対してpingを実行

RhoSync 2.0はユーザーのデバイスにpingする簡単なruby APIを用意しています。デバイスにメッセージを通知したり、rhodesアプリケーションの応答の仕方を制御したりすることに利用できます。

pingのAPI

Iphone.ping(params)

Blackberry.ping(params)

バルク同期

場合によっては、特にデバイスのアプリケーションの初期化中には、オブジェクトのかなりの数を同期させる必要があります。これは、データをメガバイト単位でデバイスに送信する可能性があります。このような場合には、増分同期は完了にしばらくかかることがあります。RhoSyncの"バルク同期"機能を使用することで、このプロセスを高速化します。

rhosyncサーバーにRhodesアプリケーションがバルクデータの取得を要求した場合、RhoSyncアプリケーションは以下のように動作します:

  • すべてのソースアダプタの'query'メソッドを実行し、バックエンドサーバーからオブジェクトの最新のセットを取得する
  • デバイスの適切なdbファイルを生成 - Blacberryにはhsql,
    その他にはsqliteを生成します。RhoSyncはsqlite3-ruby gemをsqlite dbファイルを生成するために使い、vendor/hsqldata.jarをBlackBerryのdbファイルを生成するために使います。(javaがインストールされて、hsqldata.jarを実行するように設定されていることを確認してください)
  • Rhodesアプリケーションは生成中にdbファイルが利用可能かポーリングします。ファイルが生成されると、Rhodesはロードしてデバイス上にインストールします。デバイス上の以前のオブジェクトはバックエンドから最新のセットに置き換えられますので注意してください。

バルクデータ同期プロセスが完了すると、このデータソースを通常の増分同期プロセスを使用して同期を続行できます。しかし、通常の同期プロセスはsync_typeを:bulk_sync_onlyと対応するソースに設定することにより無効にします。

バルク同期を有効に

デバイス上のrhodesアプリケーションにおいて、rhoconfig.txtのbulksync_stateを0にすると、次の同期が行われるときに、バルク同期が起動します:



bulksync_state = 0

アプリケーションがバルク同期を行った後は、bulksync_stateに1が設定され、次の同期が行われる際にはバルク同期は行われません。アプリケーションでrubyを使って、bulksync_stateに再び0を設定することで、次の同期サイクルでバルク同期を強制的に行うことができます:

Rho::RhoConfig.bulksync_state = '0'

バルク同期のデータファイル

デフォルトでは、バルク同期のデータファイルはアプリケーションのルートフォルダ、'data'ディレクトリの下に格納されます。Rhodesアプリケーションからバルクデータが要求されると、RhoSyncはbulk_sync_poll_interval有効期限が切れていないならば、ファイルへのリンクを返します。期限切れの場合は、RhoSyncはRhodesにwaitコマンドを返し、新たなバルクデータファイルを生成するresque_jobsを待ち行列に入れます。デフォルトでは、bulk_sync_poll_intervalには1時間(3600秒)に設定され、settings.ymlで設定可能です:


:development:
:redis: localhost:6379
:licensefile: settings/license.key
:syncserver: http://localhost:9292/application/
:bulk_sync_poll_interval: 3600

画像やバイナリブロブの同期(blob sync)

メタデータ

メタデータのフレームワークは、ランタイムにおける動的なアプリケーションのレイアウトを提供するRhoSync/Rhodes2.0の特徴です。メタデータドキュメントを確認してください。

非同期ジョブ

RhoSync2.0は非同期ジョブを管理・実行するするために、resqueライブラリを使用します。非同期ジョブを使用する場合、アプリケーションが大規模なデータの処理を必要としたり、built-inのpush通知を使ってデバイスへpingしたり、長時間かかる処理を必要とする場合に、特に便利です。

非同期ジョブの種類

RhoSyncは、次のジョブをサポートします:

バルクデータ

バルクデータジョブは、RhoSyncがデータファイルを用意するために利用されます。

BulkDataJob.enqueue(params)

デバイスに対してping

Pingのジョブはdevice pingを実行するために利用されます。

PingJob.enqueue(params)

例:

PingJob.enqueue(
{
"user_id" => current_user.login,
"message" => "New products available!",
"badge" => 1,
"sources" => ['Product']
}
)

ソース

ソースジョブは、非同期にソースアダプタの待ち行列キューを実行するために使用されます。

SourceJob.enqueue(params)

非同期ジョブを有効にする

非同期ジョブの実行

RhoSyncジョブを実行するには一つ以上のresque workerが動作している必要があります。たとえば、すべてのジョブキューを処理するひとつのresque workerを起動するには:



cd <your rhosync app>
QUEUE=* rake resque:work

複数のworkerを起動するには(この場合、5):


cd <your rhosync app>
QUEUE=* COUNT=5 rake resque:workers

RhoSyncのAPI

RhoSync APIは、RhoSyncアプリケーションの管理制御とデバッグ機能を提供します。詳細はRhoSync API docsを参照してください。

RhoSyncコンソール

RhoSyncコンソールとWebアプリケーションは、ブラウザからRhoSyncアプリケーションを制御したりデバッグしたりすることができます。RhoSyncアプリケーションの一部またはスタンドアロンのWebアプリケーションとして、それを実行することができます。

RhoSyncアプリケーションの一部としてコンソールアプリケーションを起動するには、以下をconfig.ruで指定します:

# Setup the url map
run Rack::URLMap.new \
"/" => Rhosync::Server.new,
"/resque" => Resque::Server.new,
"/console" => RhosyncConsole::Server.new # Add this line to run console app as part of RhoSync

RhoSyncコンソールは、すべてのユーザー、デバイスとデータソースに関連付けられているデータへのアクセスを提供します。我々は、開発モードでのみ走らせて、製品版では無効することをお勧めします。

RhoSync 1.xのソースアダプタを2.0へ移行

RhoSync2.0のソースアダプタのAPIが変更されているため、既存のソースアダプタを1.xから2.0へ変更するには、アダプタのコードの細かい変更が伴います。

APIの変更点

initialize(初期化)

変更はありません。

login(ログイン)

変更はありません。

query(クエリー)

1.x:

query #=> takes no args, or optionally takes conditions,limit,offset

2.0:

query(params=nil) #=> takes optional params sent by the client using search

sync(同期)

すべてのActiveRecord固有のコード、またはObjectValueクラスを使用しているコードを削除します。ActiveRecordまたはObjectValue ActiveRecordのクラスはもうありません。

create(作成)

1.x:

create(name_value_list,blob=nil) #=> name_value_list is an array

2.0:

create(create_hash,blob=nil) #=> create_hash is a hash containing the attributes and values

update(更新)

1.x:

update(name_value_list) #=> name_value_list is an array

2.0:

update(update_hash) #=> update_hash is a hash containing the attributes and values
# update_hash contains n 'id' element for the object to be updated

delete(削除)

1.x:

delete(name_value_list) #=> name_value_list is an array

2.0:

delete(object_id) #=> object_id is the id of the object to delete

logoff(ログオフ)

変更はありません。

page(ページ)

2.0ではこのメソッドを削除します。代わりにstash_resultを使用してください。これは@resultハッシュを隠し、その他の処理にも使うことができます。

移行例

このソースアダプタ(product.rb)があったとしましょう。

このアダプタをRhoSync 2.0アプリケーションへ移行するには、次のようにします:

  • 2.0のソースを生成します:


cd <my-rhosync-app>
rhosync source product
  • sources/product.rbのqueryメソッドの内容を置換します:
    url="http://rhostore.heroku.com/products.json"
parsed=nil
open(url) do |f|
parsed=JSON.parse(f.read)
end
@result={}
parsed.each { |item|@result[item["product"]["id"].to_s]=item["product"] } if parsed @result
  • Rails.loggerやconditions,limitそしてoffsetを削除したことに注意してください。RhoSync 2.0では、これらは必要とはされません。
  • create,update,deleteメソッドの手順を繰り返します。前のセクションに記載されているAPIの変更に注意してください。
  • 最後に、完全なアダプタがこのようになります: http://gist.github.com/415136
  • そしてspec/product_spec.rbにいくつかのspecを書きます。http://gist.github.com/415138

貢献

RhoSyncに機能を追加したい?レポートまたは修正したいバグを見つけたら?

RhoSyncの問題を報告

バグ、特徴、機能拡張をRhoSyncの問題へ報告してください。

RhoSyncのspecを走らせる

環境が開発用に最新であることを確認するために、rhosync specを先ず走らせます:

  1. RhoSyncリポジトリフォークする
  2. 新しいレポジトリをcloneします:
    git clone git://github.com/<yourhandle>/rhosync.git
    cd rhosync
  3. Jewelerをインストール:
    [sudo] gem install jeweler
  4. Jewelerは、開発の依存関係の欠如を識別するためにしています。実行して、報告された不足しているgemsをインストールしてください:
    rake check_dependencies
  5. hsqldataをインストール :
    git clone git://github.com/rhomobile/hsqldata.git
    cd hsqldata
    ant
    mkdir -p <path-to-rhosync>/vendor/
    cp bin/hsqldata.jar <path-to-rhosync>/vendor/
  6. rake #=>デフォルトですべてのrhosync specが走ります


すべてがパスしたら(pending specはOK)、環境は開発のための準備が整っています。もし特定のgemのインストールで問題が発生したり、specが正しく動作しなったりした場合、ご自由にrhomobile google groupへ知らせたり、issueに記録したり、hop on IRCで他のRhoSync開発者とチャットしたりしてください。

パッチの貢献

これで、環境の準備ができて、あなた自身の変更を加えることでできます!

  1. テーマとなるbranchを作ります:
    git checkout -b cool_new_feature
  2. テストを書きます(
  3. 変更を加えます...
  4. 関連ドキュメントを追加(RDocと、該当する場合はREADMEを更新)
  5. branchにプッシュ:
    git checkout -b cool_new_feature
  6. テーマのbranchへのリンクを含んだGitHubのissueを作成します。

以上です。コーディングの際には、これらのruby styleガイドラインをお勧めします。

ベンチマーク

詳細はbenchmarksのページを参照してください。


0 件のコメント: